A radial Canvas 2D burst of metallic confetti: 260 pieces in 4 waves, 3D-normal lighting with glints, a 2-3 s shower, Δt-normalised physics and a ConfettiExplosion.burst() API.
ConfettiCanvas 2DExplosionCélébration
Clic · ou
Hover or click the scene to interact
This effect is free — the Atmosphere category contains 57 effects total, including 10 free. Effect.Labs has 811 vanilla effects. Explore the category →
WhenThe user completes a course, challenge, or streak and clicks 'Claim my badge' — the radial burst fires from the button and floods the frame with golden confetti.
WhyThe large dark surface lets the golden confetti burst and fall freely — nothing competes with the effect, and the medal stays readable thanks to the contrast.
SettingsGold palette (#FFD700, #FFF0A0, #FFA500, #FFFFFF, #FDFFB6), count 260, power 1.0. 4 waves over 148 ms from the bottom-center button. DRAG 0.96, G 0.06.
🏆
Victory!
Final score: 9 840 pts9 840 pts
② Victory — End of round
WhenThe round ends and the results screen appears — tournament, multiplayer quiz, level completion. The burst fires automatically on viewport entry (180 ms delay).
WhyThe auto-burst on viewport entry removes the need to click on a results screen — confetti explode on display and fill all visible space. Clicking the scene fires a second 160-particle burst.
WhenThe user finishes a quiz without a single mistake. The results page reveals the score and the Share button fires the burst from the bottom of the scene.
WhyDark background vs rainbow confetti makes the radial explosion maximally legible. Curved ribbons and stars add shape variety that quiz and learning apps appreciate.
The IIFE creates one instance per .cxp-scene found on the page. Each instance maintains a local pool ≤ 550 particles, 12 permanent floating confetti that drift slowly downward in a loop, and 14 sparkles that twinkle between bursts. A single requestAnimationFrame per instance drives rendering; an IntersectionObserver (threshold 0.15) starts and stops the loop based on visibility; a ResizeObserver recalibrates the canvas on resize, accounting for devicePixelRatio.
Each burst fires particles in 4 waves spread over 148 ms — 30% at 0 ms, 28% at 42 ms, 25% at 90 ms, 17% at 148 ms — to avoid a visible spawn spike. Then physics takes over: air drag 0.96 per frame, gravity 0.06, lateral wobble 0.32 and slowing spin — pieces drift back down over 2–3 s.
Four shapes mix at random: rectangles, circles, curved ribbons (9-segment quadratic Bézier curves) and 5-point stars. Each particle simulates a 3D normal via rotX × rotY: face toward the viewer → main color; opposite face → shade darkened by 30% (darken(hex, 0.30)). A specular glint (~92% intensity) briefly shifts the color toward white. Physics is Δt-normalised: drag DRAG = 0.96 per frame @ 60fps (compensated as DRAG^dt), gravity G = 0.06 px/frame², lateral wobble WOB = 0.32. Particles live 144–204 frames and fade in the last 25% of their life.
In idle mode, floaters drift and sparkles twinkle. An automatic burst fires on viewport entry (180 ms delay) and repeats every 7 s with no user click. In prefers-reduced-motion, a single gentle burst (20 particles, power = 0.50) fires on entry then all looping stops — floaters and auto-repeat included.
Accessibility
prefers-reduced-motion: if reduced, a single gentle burst (20 particles, power = 0.50) fires on viewport entry then all animation stops. The 12 permanent floaters and the 7-second auto-repeat are also disabled.
The scene carries role="img" and a descriptive aria-label; the canvas is marked aria-hidden="true" — graphical elements do not feed the accessibility tree.
The trigger is a native <button class="cxp-btn">, keyboard-focusable (Tab / Enter / Space), with a golden :focus-visible ring (#fbbf24).
Clicks outside the button fire a burst at the exact click point (160 particles) — the keyboard is never required to reach the main functionality.
Browser compatibility
Requires Canvas 2D, requestAnimationFrame, IntersectionObserver and ResizeObserver — available in all modern browsers. Zero external dependencies.
Chrome 88+✓ Full
Firefox 78+✓ Full
Safari 15+✓ Full
Edge 88+✓ Full
Mobile iOS 15+✓ Touch OK
Android Chrome✓ Full
Without Canvas 2D support, the scene stays empty (no fatal JS errors); the button and any overlaid text remain readable. Without IntersectionObserver (IE 11), the effect starts immediately on initialisation.
The code
Copy the three blocks into your page. No dependencies.
HTML
<div class="cxp-scene" id="cxpScene"
role="img"
aria-label="Confetti Explosion — explosion radiale de confettis métallisés depuis le bouton"
data-colors="#FF4D9E,#FFD700,#00E5FF,#8AFF59,#F0F4F8,#FF8040,#E040FB,#FDFFB6">
<canvas class="cxp-canvas" aria-hidden="true"></canvas>
<div class="cxp-label" aria-hidden="true">Clic · ou</div>
<button class="cxp-btn" aria-label="Lancer une explosion de confettis">🎉 Celebrate!</button>
</div>
Confetti color palette — comma-separated hex values on the HTML element. Override per burst via window.ConfettiExplosion.burst({colors:['#f00','#fff']}).
burst({count})
260 (20 in reduced-motion)
Particles per burst via the API. 60–350 for smooth mobile performance. Clicking outside the button always fires a fixed 160-particle burst.
Four built-in palettes in the IIFE. Change COLORS_DEFAULT = PALETTES.gold at the top of the script to apply a palette to all scenes without data-colors.
FAQ
How do I fire the burst from a button outside the scene?
Call window.ConfettiExplosion.burst({x, y, count, colors, power}) from any event handler. x and y are CSS pixels in the scene's coordinate system; omit them to burst from the center. The API fires all .cxp-scene instances on the page simultaneously.
Does the effect work without a JavaScript framework?
Yes — the code is a vanilla IIFE, zero dependencies. Copy the CSS block and JS block into any HTML page, add a <div class="cxp-scene"><canvas class="cxp-canvas"></canvas></div> and the effect initialises automatically on load.
Does the effect respect prefers-reduced-motion?
Yes. When prefers-reduced-motion is active in the OS, a single short gentle burst (20 particles, power = 0.50) fires on viewport entry, then all animation stops. Permanent floaters and the 7-second auto-repeat are also disabled.