webdevpuneet.com

Matter.js Confetti Cannon — Free Physics-Based Confetti Burst Snippet

Matter.js Confetti Cannon · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

Requires
<div class="mc-wrap">
  <canvas id="mcCanvas" class="mc-canvas"></canvas>
  <button class="mc-btn" id="mcFire">Launch confetti</button>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real rigid-body physics
Matter.js simulates gravity, mass, and collisions.
Invisible floor and walls
Bounds keep confetti contained without visible bodies.
Mixed shapes
Circles and rectangles vary the burst's silhouette.
Randomized impulses
Body.applyForce gives every piece a unique path.
Independent spin
Angular velocity is randomized per piece.
Resize-safe bounds
Walls rebuild to match the current canvas size.
Auto cleanup
Settled confetti is removed after 6 seconds.
Repeatable bursts
Every click produces a genuinely different outcome.

About this UI Snippet

Matter.js Confetti Cannon — Real Physics Confetti That Bounces and Settles

Screenshot of the Matter.js Confetti Cannon snippet rendered live

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).

Step by step

How to Use

  1. 1
    Add the matter-js CDNInclude matter.min.js from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSAn empty physics canvas and a launch button render.
  3. 3
    Click "Launch confetti"60 bodies launch upward with randomized force.
  4. 4
    Watch it settleGravity and collisions bring pieces to rest naturally.
  5. 5
    Click againA fresh burst launches; old pieces clean up after 6s.
  6. 6
    Resize the windowBounds rebuild so confetti stays contained.

Real-world uses

Common Use Cases

Purchase confirmations
Give a completed order a heavier celebratory moment than a CSS animation, with pieces that really fall, collide and settle at the bottom.
Achievement unlocks
Pair with a confetti celebration card so an achievement message arrives with matching physical confetti falling behind it.
Physics playground companions
Sit alongside physics balls in a section on physical interaction, reusing the same engine and bounds setup.
Game-like interactions
Reuse the invisible floor and walls from makeBounds for any effect that needs contained, colliding bodies, such as physics props and pucks.
Confetti technique comparison
Contrast with a canvas confetti burst, which fakes motion, while this version applies randomised Body.applyForce impulses.
Related: Wave Text Animation
See the Wave Text Animation for a related animations pattern worth pairing with this one.

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.