🎉 Long Confetti
A JavaScript library for creating beautiful confetti animations using custom PNG/SVG images instead of traditional shapes. Perfect for celebrations, achievements, games, and any visual enhancement that needs floating custom images!
✨ Features
- 🖼️ Custom Images: Use up to 5 different PNG/SVG images as confetti particles
- ⚡ Physics Engine: Realistic gravity, wind, and velocity simulation
- 🎯 Flexible Origins: Launch confetti from any position on screen
- 📐 Customizable: Adjust size, rotation, duration, and particle count
- 🎭 Built-in Defaults: Emoji and geometric shape presets included
- 🚀 Performance: Optimized DOM manipulation and RAF animation
- 📱 Responsive: Works on all screen sizes and devices
- 🔧 TypeScript: Full TypeScript support with type definitions
- 🌐 Browser Ready: Works directly in browsers without build tools
🚀 Installation & Setup
Method 1: CDN Import (Easiest - No Node.js Required!)
Simply include the CDN script in your HTML - no build tools or Node.js needed:
<!-- From jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/npm/long-confetti@1.0.0/long-confetti.cdn.js"></script>
<!-- Or from unpkg CDN -->
<script src="https://unpkg.com/long-confetti@1.0.0/long-confetti.cdn.js"></script>
Then use it immediately:
<script>
// Functions are globally available!
fireShapeConfetti({ particleCount: 100 });
fireEmojiConfetti({ duration: 4000 });
</script>
Method 2: NPM/Yarn (For Projects with Build Tools)
npm install long-confetti
Or with yarn:
yarn add long-confetti
Method 3: Direct File Usage (Local Development)
Download and include the files directly:
<!-- Use the CDN-ready version -->
<script src="long-confetti.cdn.js"></script>
<!-- Or use the source file -->
<script src="src/index.js"></script>
📖 Complete CDN Example (Super Easy!)
Here's a minimal example using the CDN - just save as .html
and open in any browser:
<!DOCTYPE html>
<html>
<head>
<title>Long Confetti - CDN Example</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
min-height: 100vh;
margin: 0;
}
button {
padding: 15px 30px;
font-size: 18px;
margin: 10px;
border: none;
border-radius: 8px;
background: rgba(255,255,255,0.2);
color: white;
cursor: pointer;
transition: all 0.3s ease;
}
button:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-2px);
}
</style>
</head>
<body>
<h1>🎉 Long Confetti CDN Demo</h1>
<p>No Node.js, no build tools, no installation - just works!</p>
<button onclick="fireShapeConfetti({particleCount: 100})">
🔷 Shape Confetti
</button>
<button onclick="fireEmojiConfetti({particleCount: 75, duration: 4000})">
😊 Emoji Confetti
</button>
<button onclick="customConfetti()">
⭐ Custom Images
</button>
<button onclick="stopAllConfetti()">
⏹️ Stop All
</button>
<!-- Include Long Confetti from CDN -->
<script src="https://cdn.jsdelivr.net/npm/long-confetti@1.0.0/long-confetti.cdn.js"></script>
<script>
function customConfetti() {
const hearts = [
'data:image/svg+xml;base64,' + btoa(`
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 28 C16 28 2 18 2 10 C2 6 6 2 10 2 C12 2 16 6 16 6 C16 6 20 2 22 2 C26 2 30 6 30 10 C30 18 16 28 16 28 Z"
fill="#FF6B9D"/>
</svg>
`)
];
fireConfetti(hearts, {
particleCount: 50,
duration: 3000,
spread: 70
});
}
</script>
</body>
</html>
📖 Complete Advanced Example (From Scratch)
For more advanced usage with a full test suite:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Confetti Demo</title>
<style>
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
}
.demo-container {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.1);
border-radius: 20px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
h1 {
margin-bottom: 30px;
font-size: 2.5em;
}
.button-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-top: 30px;
}
button {
padding: 15px 25px;
font-size: 16px;
border: none;
border-radius: 10px;
background: rgba(255, 255, 255, 0.2);
color: white;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(5px);
}
button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
button:active {
transform: translateY(0);
}
.instructions {
margin-top: 30px;
padding: 20px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
font-size: 14px;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="demo-container">
<h1>🎉 Image Confetti Demo</h1>
<p>Click any button below to see different confetti effects!</p>
<div class="button-grid">
<button id="shapeBtn">🔷 Geometric Shapes</button>
<button id="emojiBtn">😊 Emoji Confetti</button>
<button id="customBtn">⭐ Custom Images</button>
<button id="celebrationBtn">🎊 Celebration</button>
<button id="burstBtn">💥 Center Burst</button>
<button id="multiBtn">🎪 Multiple Effects</button>
</div>
<div class="instructions">
<strong>How this works:</strong><br>
1. Save this HTML file to your computer<br>
2. Make sure the long-confetti source file is in the correct path<br>
3. Open the HTML file in any modern browser<br>
4. Click buttons to see confetti effects!
</div>
</div>
<!-- Include the Image Confetti library -->
<!-- Option 1: From src folder (if you have the source) -->
<script src="src/index.js"></script>
<!-- Option 2: From dist folder (if you built the project) -->
<!-- <script src="dist/index.js"></script> -->
<!-- Option 3: If you downloaded just this HTML file, you'll need to adjust the path -->
<!-- <script src="path/to/your/long-confetti/src/index.js"></script> -->
<script>
// Wait for the library to load
document.addEventListener('DOMContentLoaded', function() {
// Check if library loaded successfully
if (typeof window.fireShapeConfetti === 'undefined') {
alert('Image Confetti library not found! Please check the script src path.');
return;
}
// 1. Default geometric shapes
document.getElementById('shapeBtn').addEventListener('click', async function() {
await window.fireShapeConfetti({
particleCount: 100,
duration: 4000,
origin: { x: 0.5, y: 0.1 }
});
});
// 2. Default emojis (🎉⭐❤️🌟🎈)
document.getElementById('emojiBtn').addEventListener('click', async function() {
await window.fireEmojiConfetti({
particleCount: 75,
duration: 3000,
origin: { x: 0.5, y: 0.1 }
});
});
// 3. Custom SVG images
document.getElementById('customBtn').addEventListener('click', async function() {
const customImages = [
// Star SVG
'data:image/svg+xml;base64,' + btoa(`
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2 L20 12 L30 12 L22 18 L26 28 L16 22 L6 28 L10 18 L2 12 L12 12 Z"
fill="#FFD700" stroke="#FFA500" stroke-width="1"/>
</svg>
`),
// Heart SVG
'data:image/svg+xml;base64,' + btoa(`
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 28 C16 28 2 18 2 10 C2 6 6 2 10 2 C12 2 16 6 16 6 C16 6 20 2 22 2 C26 2 30 6 30 10 C30 18 16 28 16 28 Z"
fill="#FF6B9D"/>
</svg>
`),
// Diamond SVG
'data:image/svg+xml;base64,' + btoa(`
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2 L26 12 L16 30 L6 12 Z"
fill="#4ECDC4" stroke="#45B7D1" stroke-width="1"/>
</svg>
`)
];
await window.fireConfetti(customImages, {
particleCount: 60,
duration: 4000,
startVelocity: 35,
spread: 70,
origin: { x: 0.5, y: 0.1 },
imageSize: { width: 25, height: 25 },
rotationSpeed: 6
});
});
// 4. Celebration effect (top-down)
document.getElementById('celebrationBtn').addEventListener('click', async function() {
await window.fireShapeConfetti({
particleCount: 150,
duration: 5000,
startVelocity: 40,
spread: 90,
origin: { x: 0.5, y: 0.1 },
gravity: 0.6
});
});
// 5. Center burst
document.getElementById('burstBtn').addEventListener('click', async function() {
await window.fireEmojiConfetti({
particleCount: 100,
duration: 3000,
startVelocity: 50,
spread: 360,
origin: { x: 0.5, y: 0.5 }
});
});
// 6. Multiple sequential effects
document.getElementById('multiBtn').addEventListener('click', async function() {
// Left cannon
setTimeout(async () => {
await window.fireEmojiConfetti({
particleCount: 50,
origin: { x: 0.1, y: 0.7 },
spread: 45,
startVelocity: 40
});
}, 0);
// Right cannon
setTimeout(async () => {
await window.fireEmojiConfetti({
particleCount: 50,
origin: { x: 0.9, y: 0.7 },
spread: 45,
startVelocity: 40
});
}, 200);
// Center finale
setTimeout(async () => {
await window.fireShapeConfetti({
particleCount: 100,
origin: { x: 0.5, y: 0.5 },
spread: 360,
startVelocity: 55
});
}, 400);
});
console.log('Image Confetti Demo Ready! 🎉');
});
</script>
</body>
</html>
📖 Quick Start Guide
Step 1: Get the Files
- Download or clone this repository
- The main file you need is
src/index.js
Step 2: Basic HTML Setup
<!DOCTYPE html>
<html>
<head>
<title>My Confetti App</title>
</head>
<body>
<button id="confetti-btn">🎉 Fire Confetti!</button>
<!-- Include the library -->
<script src="src/index.js"></script>
<script>
document.getElementById('confetti-btn').addEventListener('click', async () => {
// Fire some confetti!
await window.fireShapeConfetti({
particleCount: 100,
duration: 3000
});
});
</script>
</body>
</html>
🎯 Usage Examples
1. Basic Confetti Effects
// Default geometric shapes (circles, squares, triangles, stars)
await window.fireShapeConfetti({
particleCount: 100,
duration: 4000,
origin: { x: 0.5, y: 0.1 }
});
// Default emojis (🎉⭐❤️🌟🎈)
await window.fireEmojiConfetti({
particleCount: 75,
duration: 3000,
origin: { x: 0.5, y: 0.5 }
});
// Custom images
const customImages = [
'path/to/your/image1.png',
'path/to/your/image2.svg',
'data:image/svg+xml;base64,' + btoa('<svg>...</svg>')
];
await window.fireConfetti(customImages, {
particleCount: 50,
duration: 3000,
startVelocity: 30,
spread: 70,
origin: { x: 0.5, y: 0.1 },
gravity: 0.5,
wind: 0.1,
imageSize: { width: 20, height: 20 },
rotationSpeed: 5,
zIndex: 9999
});
2. Node.js/Module Usage (If using NPM)
import { fireShapeConfetti, fireEmojiConfetti, fireConfetti } from "long-confetti";
// Default shapes - colorful geometric shapes
await fireShapeConfetti({
particleCount: 100,
duration: 5000,
origin: { x: 0.5, y: 0.1 }
});
// Default emojis - fun emoji confetti (🎉⭐❤️🌟🎈)
await fireEmojiConfetti({
particleCount: 150,
duration: 4000,
origin: { x: 0.5, y: 0.5 }
});
// Custom images - your own PNG/SVG images
await fireConfetti(
["/images/star.png", "/images/heart.png", "/images/diamond.png"],
{
particleCount: 50,
duration: 3000,
startVelocity: 30,
spread: 70,
gravity: 0.5,
wind: 0.1,
imageSize: { width: 25, height: 25 },
rotationSpeed: 5
}
);
3. React Integration
import React, { useRef, useEffect } from "react";
// For NPM/module usage (if working)
// import { fireEmojiConfetti, fireConfetti, fireShapeConfetti } from "long-confetti";
function CelebrationComponent() {
const confettiLoaded = useRef(false);
useEffect(() => {
// Load the fixed library script if not already loaded
if (!confettiLoaded.current && !window.fireConfetti) {
const script = document.createElement('script');
script.src = '/image-confetti-fixed.js'; // Adjust path as needed
script.onload = () => {
confettiLoaded.current = true;
console.log('Image Confetti library loaded');
};
document.head.appendChild(script);
}
}, []);
// Simple emoji celebration
const handleEmojiClick = async () => {
if (window.fireEmojiConfetti) {
await window.fireEmojiConfetti({
particleCount: 100,
duration: 4000,
origin: { x: 0.5, y: 0.1 }
});
}
};
// Custom images
const handleCustomClick = async () => {
if (window.fireConfetti) {
// Create custom SVG logos as data URLs
const customLogos = [
'data:image/svg+xml;base64,' + btoa(`
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<circle cx="32" cy="32" r="30" fill="#ff6b6b"/>
<text x="32" y="40" text-anchor="middle" fill="white" font-size="24" font-family="Arial">★</text>
</svg>
`),
'data:image/svg+xml;base64,' + btoa(`
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<rect x="8" y="8" width="48" height="48" fill="#4ecdc4"/>
<text x="32" y="40" text-anchor="middle" fill="white" font-size="24" font-family="Arial">♥</text>
</svg>
`)
];
await window.fireConfetti(customLogos, {
particleCount: 75,
duration: 4000,
startVelocity: 35,
spread: 60,
origin: { x: 0.5, y: 0.1 },
gravity: 0.5,
wind: 0.1,
imageSize: { width: 25, height: 25 },
rotationSpeed: 6
});
}
};
// Geometric shapes
const handleShapesClick = async () => {
if (window.fireShapeConfetti) {
await window.fireShapeConfetti({
particleCount: 150,
duration: 5000,
startVelocity: 40,
spread: 90,
origin: { x: 0.5, y: 0.5 }
});
}
};
// Multiple effects sequence
const handleMultipleEffects = async () => {
if (window.fireConfetti && window.fireEmojiConfetti) {
// Fire from left
setTimeout(() => {
window.fireEmojiConfetti({
particleCount: 50,
origin: { x: 0.1, y: 0.7 },
spread: 45
});
}, 0);
// Fire from right
setTimeout(() => {
window.fireEmojiConfetti({
particleCount: 50,
origin: { x: 0.9, y: 0.7 },
spread: 45
});
}, 200);
// Center burst
setTimeout(() => {
window.fireShapeConfetti({
particleCount: 100,
origin: { x: 0.5, y: 0.5 },
spread: 360
});
}, 400);
}
};
return (
<div style={{ padding: '20px', textAlign: 'center' }}>
<h2>🎉 React Confetti Demo</h2>
<div style={{ display: 'flex', gap: '10px', justifyContent: 'center', flexWrap: 'wrap' }}>
<button onClick={handleEmojiClick} style={{ padding: '10px 20px', fontSize: '16px' }}>
🎉 Emoji Confetti
</button>
<button onClick={handleCustomClick} style={{ padding: '10px 20px', fontSize: '16px' }}>
⭐ Custom Images
</button>
<button onClick={handleShapesClick} style={{ padding: '10px 20px', fontSize: '16px' }}>
🔷 Geometric Shapes
</button>
<button onClick={handleMultipleEffects} style={{ padding: '10px 20px', fontSize: '16px' }}>
🎊 Multiple Effects
</button>
</div>
</div>
);
}
export default CelebrationComponent;
4. Advanced Class Usage
// Create a persistent confetti instance
const confetti = new window.ImageConfetti();
// Fire multiple effects
await confetti.fire({
images: ['/logo1.png', '/logo2.png'],
particleCount: 50,
duration: 3000
});
// Clean up when done
setTimeout(() => {
confetti.destroy(); // Removes from DOM completely
}, 5000);
🎛️ Configuration Options
interface ImageConfettiOptions {
images?: string[]; // Array of image URLs (up to 5) - optional, uses defaults if not provided
particleCount?: number; // Number of particles (default: 50)
duration?: number; // Animation duration in ms (default: 3000)
gravity?: number; // Gravity strength (default: 0.5)
wind?: number; // Wind force (default: 0.1)
startVelocity?: number; // Initial velocity (default: 30)
spread?: number; // Launch angle spread in degrees (default: 50)
origin?: {
// Launch position (default: { x: 0.5, y: 0.1 })
x: number; // 0-1, left to right (0 = left edge, 1 = right edge)
y: number; // 0-1, top to bottom (0 = top edge, 1 = bottom edge)
};
zIndex?: number; // CSS z-index (default: 9999)
imageSize?: {
// Particle size (default: { width: 20, height: 20 })
width: number;
height: number;
};
rotationSpeed?: number; // Rotation speed (default: 5)
}
Available Functions
// Custom images
window.fireConfetti(imageUrls, options)
// Default emojis (🎉⭐❤️🌟🎈)
window.fireEmojiConfetti(options)
// Default geometric shapes (circles, squares, triangles, stars)
window.fireShapeConfetti(options)
// Advanced class usage
const confetti = new window.ImageConfetti();
await confetti.fire(options);
confetti.stop(); // Stop animation but keep container
confetti.destroy(); // Remove from DOM completely
🎨 Common Effect Patterns
Celebration Effects
// 🎉 Top celebration - particles fall from top
await window.fireShapeConfetti({
particleCount: 100,
duration: 4000,
startVelocity: 35,
spread: 60,
origin: { x: 0.5, y: 0.1 }, // Top center
gravity: 0.6
});
// 💥 Center burst - particles explode outward
await window.fireEmojiConfetti({
particleCount: 75,
duration: 2500,
startVelocity: 45,
spread: 90,
origin: { x: 0.5, y: 0.5 }, // Center
gravity: 0.5
});
// ⛲ Fountain effect - particles shoot up from bottom
await window.fireShapeConfetti({
particleCount: 30,
duration: 5000,
startVelocity: 25,
spread: 30,
origin: { x: 0.5, y: 0.9 }, // Bottom center
gravity: 0.3 // Light gravity for floating effect
});
Side Cannon Effects
// 🎪 Left side cannon
await window.fireEmojiConfetti({
particleCount: 60,
duration: 3500,
startVelocity: 40,
spread: 45,
origin: { x: 0.1, y: 0.7 }, // Left side
wind: 0.2 // Push particles right
});
// 🎪 Right side cannon
await window.fireEmojiConfetti({
particleCount: 60,
duration: 3500,
startVelocity: 40,
spread: 45,
origin: { x: 0.9, y: 0.7 }, // Right side
wind: -0.2 // Push particles left
});
🎯 Advanced Usage
Multiple Sequential Effects
// Fire multiple effects in sequence for maximum celebration
const sequentialCelebration = async () => {
// Left cannon
setTimeout(async () => {
await window.fireEmojiConfetti({
particleCount: 50,
origin: { x: 0.1, y: 0.7 },
spread: 45
});
}, 0);
// Right cannon
setTimeout(async () => {
await window.fireEmojiConfetti({
particleCount: 50,
origin: { x: 0.9, y: 0.7 },
spread: 45
});
}, 200);
// Center burst finale
setTimeout(async () => {
await window.fireShapeConfetti({
particleCount: 100,
origin: { x: 0.5, y: 0.5 },
spread: 360,
startVelocity: 50
});
}, 400);
};
sequentialCelebration();
Custom Physics and Styling
// ❄️ Winter scene with custom physics
const snowflakeImage = 'data:image/svg+xml;base64,' + btoa(`
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2 L16 30 M2 16 L30 16 M6 6 L26 26 M6 26 L26 6"
stroke="#87CEEB" stroke-width="2" stroke-linecap="round"/>
</svg>
`);
await window.fireConfetti([snowflakeImage], {
particleCount: 100,
duration: 10000,
gravity: 0.1, // Very light gravity for floating effect
wind: -0.3, // Strong left wind
startVelocity: 15, // Gentle start
spread: 180, // Full semicircle spread
origin: { x: 0.5, y: 0 }, // Top of screen
imageSize: { width: 15, height: 15 },
rotationSpeed: 2, // Slow gentle rotation
});
// 🌟 Golden celebration with custom images
const starImage = 'data:image/svg+xml;base64,' + btoa(`
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2 L20 12 L30 12 L22 18 L26 28 L16 22 L6 28 L10 18 L2 12 L12 12 Z"
fill="#FFD700" stroke="#FFA500" stroke-width="1"/>
</svg>
`);
await window.fireConfetti([starImage], {
particleCount: 200,
duration: 6000,
gravity: 0.8,
wind: 0.2,
startVelocity: 50,
spread: 120,
origin: { x: 0.2, y: 0.3 },
imageSize: { width: 30, height: 30 },
rotationSpeed: 8,
zIndex: 10000,
});
Persistent Confetti Instance
// Create a single confetti instance for multiple effects
const confetti = new window.ImageConfetti();
// Method 1: Use defaults (colorful geometric shapes)
await confetti.fire();
// Method 2: Custom images with full control
await confetti.fire({
images: ["/logo1.png", "/logo2.png"],
particleCount: 200,
duration: 6000,
gravity: 0.8,
wind: 0.2,
startVelocity: 50,
spread: 120,
origin: { x: 0.2, y: 0.3 },
imageSize: { width: 30, height: 30 },
rotationSpeed: 8,
zIndex: 10000,
});
// Stop current animation but keep the container for reuse
confetti.stop();
// Remove confetti container from DOM completely when done
confetti.destroy();
🌐 Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- Mobile browsers (iOS Safari, Chrome Mobile)
🔧 Development
Building from Source
# Clone the repository
git clone https://github.com/longleon/long-confetti.git
cd long-confetti
# Install dependencies
npm install
# Build TypeScript
npm run build
# Run tests
npm test
# Start development server
npm run dev
Project Structure
long-confetti/
├── src/
│ └── index.js # Main library source code
├── dist/ # Built distribution files
│ ├── index.js # CommonJS build
│ ├── index.d.ts # TypeScript definitions
│ └── *.map # Source maps
├── package.json # Package configuration
├── README.md # Documentation (this file)
├── LICENSE # MIT License
└── node_modules/ # Dependencies
📝 Image Requirements
- Format: PNG, JPG, GIF, WebP, or SVG
- Size: Recommended 64x64px or smaller for best performance
- CORS: Images from external domains need proper CORS headers
- Transparency: PNG with transparency works best for realistic confetti effect
🚨 Common Issues & Solutions
Library Not Loading
Problem: window.fireConfetti is not a function
// Solution: Check if library is loaded before using
if (typeof window.fireConfetti === 'function') {
await window.fireConfetti(images, options);
} else {
console.error('Image Confetti library not loaded');
}
Images Not Loading
Problem: Custom images not displaying as confetti
// Solution 1: Use data URLs for reliable loading
const logoSvg = 'data:image/svg+xml;base64,' + btoa(`
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<circle cx="32" cy="32" r="30" fill="#ff6b6b"/>
</svg>
`);
// Solution 2: Check CORS settings for external images
// Ensure images are served with proper CORS headers
// Solution 3: Verify file paths are correct and accessible
const testImage = new Image();
testImage.onload = () => console.log('Image loaded successfully');
testImage.onerror = () => console.error('Failed to load image');
testImage.src = '/path/to/your/image.png';
Performance Issues
Problem: Slow performance with many particles
// Solution: Optimize settings for better performance
await window.fireConfetti(images, {
particleCount: 30, // Reduce particle count
duration: 2000, // Shorter duration
imageSize: { width: 15, height: 15 }, // Smaller particles
});
Mobile Compatibility
Problem: Effects too intense on mobile devices
// Solution: Detect mobile and adjust accordingly
const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
const particleCount = isMobile ? 25 : 100;
const duration = isMobile ? 2000 : 4000;
await window.fireShapeConfetti({
particleCount,
duration,
imageSize: { width: isMobile ? 12 : 20, height: isMobile ? 12 : 20 }
});
Path Issues
Problem: Script not loading or functions not available
// Solution: Check if library is loaded before using
if (typeof window.fireConfetti === 'function') {
await window.fireConfetti(images, options);
} else {
console.error('Image Confetti library not loaded - check script src path');
}
// For different folder structures, adjust the path:
// <script src="src/index.js"></script> <!-- If in same folder -->
// <script src="dist/index.js"></script> <!-- If using built version -->
// <script src="../long-confetti/src/index.js"></script> <!-- If in parent folder -->
📄 License
MIT License - see LICENSE file for details
🤝 Contributing
- Fork the repository
- Create a feature branch:
git checkout -b my-new-feature
- Commit changes:
git commit -am 'Add some feature'
- Push to branch:
git push origin my-new-feature
- Submit a pull request
🙋 Support
- 📧 Email: your-email@example.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
🌟 Changelog
v1.0.0
- ✨ NEW: Support for up to 5 custom PNG/SVG images as confetti particles
- ✨ NEW: Built-in emoji presets (🎉⭐❤️🌟🎈)
- ✨ NEW: Built-in geometric shape presets (circles, squares, triangles, stars)
- ⚡ NEW: Physics engine with realistic gravity, wind, and velocity simulation
- 🎯 NEW: Flexible launch origins (fire from any screen position)
- 📐 NEW: Highly customizable options (size, rotation, duration, particle count)
- 🚀 NEW: Performance-optimized DOM manipulation with RAF animation
- 🔧 NEW: Full TypeScript support with comprehensive type definitions
- 🌐 NEW: Direct browser usage without build tools required
- 📱 NEW: Responsive design that works on all screen sizes and devices
📋 Quick Reference
Function | Purpose | Example |
---|---|---|
window.fireConfetti(images, options) |
Custom images | await window.fireConfetti(['/logo.png'], {particleCount: 50}) |
window.fireEmojiConfetti(options) |
Default emojis | await window.fireEmojiConfetti({particleCount: 100}) |
window.fireShapeConfetti(options) |
Geometric shapes | await window.fireShapeConfetti({duration: 4000}) |
new window.ImageConfetti() |
Advanced usage | const confetti = new window.ImageConfetti(); await confetti.fire(options); |
Quick Usage Reference
Method | Use Case | Code |
---|---|---|
CDN (Recommended) | No Node.js needed | <script src="https://cdn.jsdelivr.net/npm/long-confetti@1.0.0/long-confetti.cdn.js"></script> |
unpkg CDN | Alternative CDN | <script src="https://unpkg.com/long-confetti@1.0.0/long-confetti.cdn.js"></script> |
Local CDN File | Downloaded file | <script src="long-confetti.cdn.js"></script> |
Source File | Development | <script src="src/index.js"></script> |
NPM Module | Build tools | import { fireConfetti } from "long-confetti" |
Made with ❤️ for celebrations everywhere! 🎉