You Might Also Like
Matter.js Confetti Cannon — Free Physics-Based Confetti Burst Snippet
Matter.js Confetti Cannon · Animations · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Matter.js Confetti Cannon — Real Physics Confetti That Bounces and Settles

Most confetti effects fake physics with CSS keyframes and hand-tuned easing curves — see confetti button for that approach. This snippet uses Matter.js, a real 2D rigid-body physics engine, so every piece of confetti actually has mass, velocity, restitution, and collides with the floor and walls (and, briefly, each other) rather than following a pre-baked trajectory — the burst looks different every time you click it.
Engine, renderer, and runner
Matter.js separates three concerns: Engine runs the physics simulation (gravity, collisions, constraints), Render draws the current body states to a canvas, and Runner drives the engine forward on a fixed timestep loop. This snippet wires up all three against the same canvas, with engine.gravity.y = 1 set explicitly so confetti actually falls once launched, rather than floating.
Invisible bounds keep the burst contained
Three static bodies — a floor and two side walls, all with render: { visible: false } — bound the play area so confetti bounces and settles inside the canvas instead of falling through the bottom edge forever (Matter.js bodies fall infinitely without a floor to collide with). makeBounds() is recreated on window resize so the walls always match the current canvas size.
Launching a burst with real forces
launchConfetti() creates 60 mixed circle and rectangle bodies at a point near the bottom-center, each with randomized restitution (bounciness) and friction, then calls Body.applyForce with a randomized upward-ish angle and magnitude per piece — an actual physics impulse, not a CSS animation-fill-mode. Body.setAngularVelocity gives each piece independent spin. Because the engine resolves gravity, drag, and collisions every tick, pieces naturally spread, tumble, bounce off each other and the floor, and settle at different rates.
Cleanup so bursts don't accumulate
Each burst's bodies are removed from the world 6 seconds after launch via World.remove, so clicking the button repeatedly doesn't leave hundreds of resting bodies in the simulation, which would otherwise slow collision resolution down over time.
Where this fits
For a lighter CSS-only confetti burst, see confetti button or canvas confetti burst; for real physics without confetti, see physics balls, physics 2D burst, or physics props pucks — this snippet borrows the same Matter.js setup pattern and applies it to a celebratory launch instead of draggable or falling props.
Customizing it
Change engine.gravity.y for a floatier or heavier fall, tune restitution/friction per body for bouncier or stickier confetti, or increase the piece count for a denser burst (watch performance if you also increase the cleanup delay).
Build with AI
Build, Understand, Optimize, and Extend It With AI
You don't have to reverse-engineer Matter.js's engine/render/runner split from its docs alone. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the invisible floor and wall bodies keep confetti contained without being drawn, and why applying a randomized force vector to each piece via Body.applyForce produces a different-every-time burst compared to a CSS keyframe animation with fixed start and end states. The same assistant can help optimize it — asking whether 60 bodies with a 6-second cleanup window is reasonable for lower-end devices, or whether switching some circle bodies to a lower-cost collision shape would help performance at higher particle counts. It's also useful for extending the effect: ask it to add a second burst origin so confetti launches from both bottom corners, make gravity strength configurable so the fall feels heavier or floatier, or add mouse-based repulsion so moving the cursor near settled confetti scatters it again. Treat the code less like a finished artifact and more like a starting point for a conversation.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a button-triggered confetti burst that uses real 2D rigid-body physics via Matter.js (load it from a CDN), rendered to a canvas, with gravity, bouncing, and settling — not a pre-authored CSS keyframe animation.
Requirements:
- Set up a Matter.js Engine, Render (targeting a canvas sized to its container, with wireframes disabled and a transparent background), and Runner, and start the simulation running.
- Set the engine's gravity explicitly so launched bodies actually fall.
- Create three static, invisible boundary bodies — a floor beneath the visible canvas area and a wall just outside each side — so confetti bodies collide with them and stay contained within the canvas instead of falling out of view indefinitely. Render these bodies invisible while still keeping them solid for collision purposes.
- Rebuild these boundary bodies whenever the window is resized, so they continue to match the canvas's current dimensions.
- On a button click, create roughly 60 new physics bodies near the bottom-center of the canvas, mixing circle and rectangle shapes, each with randomized size, a randomized color from a small fixed palette, and randomized restitution (bounciness) and friction values.
- Immediately after creating each burst body, apply an actual physics force to it (not a fixed velocity) at a randomized upward-ish angle and randomized magnitude, and also give it a randomized angular velocity so pieces spin independently as they fly and fall.
- A few seconds after each burst (once pieces have had time to settle), remove that burst's bodies from the physics world so repeated clicks don't cause the simulation to accumulate an ever-growing number of resting bodies and slow down over time.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Step by step
How to Use
- 1Add the matter-js CDNInclude matter.min.js from the CDN panel.
- 2Paste HTML, CSS, and JSAn empty physics canvas and a launch button render.
- 3Click "Launch confetti"60 bodies launch upward with randomized force.
- 4Watch it settleGravity and collisions bring pieces to rest naturally.
- 5Click againA fresh burst launches; old pieces clean up after 6s.
- 6Resize the windowBounds rebuild so confetti stays contained.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
A CSS confetti burst (like the confetti button snippet) pre-calculates each particle's trajectory as a keyframe animation with fixed start and end states. This snippet instead creates real Matter.js bodies with mass, restitution, and friction, then applies actual force impulses to them — gravity, collisions with the floor and walls, and piece-to-piece contact are all resolved by the physics engine every tick, so the outcome is genuinely simulated rather than pre-authored, and no two bursts play out identically.
They're real Matter.js static bodies (isStatic: true) so confetti collides with and bounces off them, but render: { visible: false } tells Matter's renderer not to draw them, since their only job is to contain the simulation, not to be seen. Without them, confetti bodies would fall under gravity indefinitely and exit the canvas instead of settling at a visible floor.
It applies a force vector to a body at a given point, which Matter.js's engine integrates into that body's velocity over subsequent simulation steps — this is a genuine physics impulse, not a CSS transform. Because each of the 60 pieces gets its own randomized angle and magnitude, they launch in a natural-looking spread rather than a mechanically uniform fan.
Once confetti has settled at the floor, the bodies are still part of the physics world and Matter.js's collision detection still has to check them against everything else every tick. Repeated clicks without cleanup would accumulate hundreds of resting bodies, gradually slowing collision resolution down; removing each burst's pieces from the world a few seconds after it settles keeps the simulation's body count bounded.
The resize listener recreates the render canvas dimensions and rebuilds the three boundary bodies (floor and two walls) to match the new size, removing the old ones first. Confetti bodies already in flight or settled keep their existing position and velocity — they're unaffected by the resize — but the new bounds ensure any bodies launched afterward, or already resting near an old wall position, stay properly contained.