Performant confetti animation library for web browsers with customizable particle effects using HTML5 Canvas
npx @tessl/cli install tessl/npm-canvas-confetti@1.9.0Canvas Confetti is a performant confetti animation library for web browsers that creates customizable particle effects using HTML5 Canvas. It offers extensive configuration options including particle count, colors, shapes, physics properties, and animation parameters, with support for both npm installation and direct CDN inclusion.
npm install canvas-confettiESM (preferred):
import confetti from "canvas-confetti";CommonJS:
const confetti = require("canvas-confetti");CDN (browser global):
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.3/dist/confetti.browser.min.js"></script>
<!-- confetti is available as global function -->import confetti from "canvas-confetti";
// Launch basic confetti
confetti();
// Launch with configuration
confetti({
particleCount: 100,
spread: 70,
origin: { y: 0.6 }
});
// Launch custom colored confetti
confetti({
particleCount: 150,
colors: ['#ff0000', '#00ff00', '#0000ff'],
shapes: ['circle', 'square']
});Canvas Confetti uses several key components:
Launch confetti animations with extensive customization options.
/**
* Launch confetti animation with specified options
* @param options - Configuration object for the confetti animation
* @returns Promise that resolves when animation completes, or null if Promise unavailable
*/
function confetti(options?: ConfettiOptions): Promise<void> | null;
interface ConfettiOptions {
/** Number of confetti particles to launch (default: 50) */
particleCount?: number;
/** Launch angle in degrees, 90 is straight up (default: 90) */
angle?: number;
/** How far off center confetti can go in degrees (default: 45) */
spread?: number;
/** Initial velocity in pixels (default: 45) */
startVelocity?: number;
/** Speed decay rate, keep between 0-1 (default: 0.9) */
decay?: number;
/** Gravity strength, 1 is full gravity (default: 1) */
gravity?: number;
/** Horizontal drift amount (default: 0) */
drift?: number;
/** Disable 3D tilt and wobble effects (default: false) */
flat?: boolean;
/** Animation lifetime in ticks (default: 200) */
ticks?: number;
/** Launch origin position */
origin?: {
/** X position, 0=left edge, 1=right edge (default: 0.5) */
x?: number;
/** Y position, 0=top edge, 1=bottom edge (default: 0.5) */
y?: number;
};
/** Array of hex color strings (default: 7 predefined colors) */
colors?: string[];
/** Array of shape names or custom shapes (default: ['square', 'circle']) */
shapes?: Array<'square' | 'circle' | 'star' | Shape>;
/** Scale factor for particles (default: 1) */
scalar?: number;
/** CSS z-index for the confetti canvas (default: 100) */
zIndex?: number;
/** Disable for users with reduced motion preference (default: false) */
disableForReducedMotion?: boolean;
}Usage Examples:
// Simple confetti burst
confetti();
// Confetti from specific position
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: {
x: Math.random(),
y: Math.random() - 0.2
}
});
// Custom colors and shapes
confetti({
particleCount: 50,
colors: ['#ff0000', '#00ff00', '#0000ff'],
shapes: ['star'],
spread: 180
});
// Continuous confetti
(function frame() {
confetti({
particleCount: 7,
angle: 60,
spread: 55,
origin: { x: 0 }
});
if (Date.now() < endTime) {
requestAnimationFrame(frame);
}
}());Stop animations and clear all confetti.
/**
* Stop animation and clear all confetti immediately
* Resolves any outstanding promises
*/
function reset(): void;Usage Example:
// Launch confetti then stop after 2 seconds
confetti({ particleCount: 200 });
setTimeout(() => {
confetti.reset();
}, 2000);Create confetti instances bound to specific canvas elements.
/**
* Create a confetti instance bound to a specific canvas
* @param canvas - HTML canvas element to render confetti on
* @param globalOptions - Global configuration options
* @returns Confetti function with same signature as main function, plus reset method
*/
function create(canvas: HTMLCanvasElement, globalOptions?: GlobalOptions): ConfettiFunction;
interface GlobalOptions {
/** Allow canvas resizing and window resize handling (default: false) */
resize?: boolean;
/** Use web worker for animation when possible (default: false) */
useWorker?: boolean;
/** Global reduced motion setting (default: false) */
disableForReducedMotion?: boolean;
}
interface ConfettiFunction {
(options?: ConfettiOptions): Promise<void> | null;
reset(): void;
}Usage Examples:
// Create custom canvas instance
const myCanvas = document.createElement('canvas');
document.body.appendChild(myCanvas);
const myConfetti = confetti.create(myCanvas, {
resize: true,
useWorker: true
});
// Use like main confetti function
myConfetti({
particleCount: 100,
spread: 160
});
// Reset specific instance
myConfetti.reset();Create custom confetti shapes using SVG path strings.
/**
* Create custom confetti shape from SVG path
* @param pathData - SVG path string or path configuration object
* @returns Shape object for use in shapes array
*/
function shapeFromPath(pathData: string | PathConfig): Shape;
interface PathConfig {
/** SVG path string */
path: string;
/** Optional 6-element transform matrix, auto-calculated if omitted */
matrix?: number[];
}
interface Shape {
type: 'path';
path: string;
matrix: number[];
}Usage Examples:
// Triangle shape from path string
const triangle = confetti.shapeFromPath({
path: 'M0 10 L5 0 L10 10z'
});
confetti({
shapes: [triangle],
particleCount: 50
});
// Heart shape with custom matrix
const heart = confetti.shapeFromPath({
path: 'M12,21.35l-1.45-1.32C5.4,15.36,2,12.28,2,8.5 C2,5.42,4.42,3,7.5,3c1.74,0,3.41,0.81,4.5,2.09C13.09,3.81,14.76,3,16.5,3 C19.58,3,22,5.42,22,8.5c0,3.78-3.4,6.86-8.55,11.54L12,21.35z',
matrix: [0.03, 0, 0, 0.03, -0.35, -0.35]
});
confetti({
shapes: [heart],
colors: ['#ff69b4'],
particleCount: 30
});Create custom confetti shapes from text characters, especially emoji.
/**
* Create custom confetti shape from text or emoji
* @param textData - Text string or text configuration object
* @returns Shape object for use in shapes array
*/
function shapeFromText(textData: string | TextConfig): Shape;
interface TextConfig {
/** Text or emoji to render as confetti */
text: string;
/** Scale factor relative to default size (default: 1) */
scalar?: number;
/** Text color in hex format (default: '#000000') */
color?: string;
/** Font family name (default: native emoji fonts) */
fontFamily?: string;
}
interface Shape {
type: 'bitmap';
bitmap: ImageBitmap;
matrix: number[];
}Usage Examples:
// Simple emoji confetti
const pineapple = confetti.shapeFromText('🍍');
confetti({
shapes: [pineapple],
particleCount: 20
});
// Scaled emoji with custom font
const largeHeart = confetti.shapeFromText({
text: '❤️',
scalar: 2,
fontFamily: 'Apple Color Emoji'
});
confetti({
shapes: [largeHeart],
scalar: 2,
particleCount: 15
});
// Text confetti with custom color
const customText = confetti.shapeFromText({
text: '★',
scalar: 1.5,
color: '#ffd700',
fontFamily: 'serif'
});
confetti({
shapes: [customText],
particleCount: 25
});Customize Promise implementation for environments without native Promise support.
/**
* Custom Promise implementation for confetti animations
* Set this property to provide Promise polyfill
*/
confetti.Promise: PromiseConstructor | undefined;Usage Example:
// Provide Promise polyfill
const MyPromise = require('some-promise-lib');
confetti.Promise = MyPromise;
// Now confetti will use the custom Promise
confetti().then(() => {
console.log('Confetti animation completed!');
});// Built-in shape names
type BuiltInShape = 'square' | 'circle' | 'star';
// Custom shape objects
interface PathShape {
type: 'path';
path: string;
matrix: number[];
}
interface BitmapShape {
type: 'bitmap';
bitmap: ImageBitmap;
matrix: number[];
}
type Shape = PathShape | BitmapShape;
// Default color palette
const DEFAULT_COLORS = [
'#26ccff', '#a25afd', '#ff5e7e', '#88ff5a',
'#fcff42', '#ffa62d', '#ff36ff'
];prefers-reduced-motion media query