Skip to content
Founding Lifetime: every Pro skillfirst 100 members · $169 onceUpgrade
Lookbk
Sign In
Effect guide

Confetti animation in JavaScript

A burst of paper that flies up, hangs, flutters and falls. The small bit of physics that makes confetti look right, a canvas starter you can fire from any button, and a skill for a looping confetti hero.

Free skills to start. Pro is $79 a year for every skill, or $9.99 a month for 10. See pricing

What is a confetti animation?

A confetti animation celebrates a moment: a signup, a purchase, a launch, a birthday. Good confetti is not just colored squares falling. It shoots out fast, slows almost at once in the air, then drifts down while each piece flips and catches the light.

Use it for one moment of success, not on every click. A burst after a real achievement feels like a reward; constant confetti feels like an ad.

How the effect works

Each piece gets a launch angle and speed, then every frame three things happen: air drag multiplies its velocity by a little less than one, gravity adds to its downward speed, and it moves. Drag is what gives confetti its pop then float; without it, pieces fly like cannonballs.

Flutter is a fake 3D flip. Rotate the piece and squash it vertically by the cosine of its rotation, so it looks edge-on at times and face-on at others. A darker back side for the edge-on half sells the paper.

  1. 01

    Launch in a cone

    Angles spread 30 to 40 degrees around straight up, speeds varied by about half.

  2. 02

    Apply drag and gravity

    velocity × e^(−k·dt) for drag, plus g·dt downward. Time-based so frame rate does not matter.

  3. 03

    Flip as they fall

    Spin each piece and scale its height by cos(angle) for the flutter.

  4. 04

    Clean up

    Stop the loop when every piece has left the screen, so the page goes back to idle.

JS

A confetti burst on a canvas

Fires from a point, with drag, gravity and flutter, and stops itself when the last piece has fallen. Call it from a click handler.

function confetti(canvas, x0, y0, count = 160) {
  const g = canvas.getContext('2d')
  const colors = ['#ff5a5f', '#ffd166', '#06d6a0', '#118ab2', '#f78c6b']
  const pieces = Array.from({ length: count }, () => {
    const angle = -Math.PI / 2 + (Math.random() - 0.5) * 1.2
    const speed = 700 + Math.random() * 500 // px per second
    return {
      x: x0, y: y0,
      vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed,
      rot: Math.random() * Math.PI, spin: (Math.random() - 0.5) * 14,
      color: colors[(Math.random() * colors.length) | 0],
    }
  })
  let last = performance.now()
  function frame(now) {
    const dt = Math.min(0.033, (now - last) / 1000)
    last = now
    g.clearRect(0, 0, canvas.width, canvas.height)
    let alive = 0
    const drag = Math.exp(-2.4 * dt)
    for (const p of pieces) {
      p.vx *= drag
      p.vy = p.vy * drag + 1100 * dt // gravity
      p.x += p.vx * dt
      p.y += p.vy * dt
      p.rot += p.spin * dt
      if (p.y < canvas.height + 20) alive++
      const flip = Math.cos(p.rot * 2)
      g.save()
      g.translate(p.x, p.y)
      g.rotate(p.rot)
      g.scale(1, flip) // edge-on when flip is near 0
      g.fillStyle = p.color
      g.globalAlpha = flip < 0 ? 0.75 : 1 // a darker back
      g.fillRect(-6, -3.5, 12, 7)
      g.restore()
    }
    if (alive) requestAnimationFrame(frame)
    else g.clearRect(0, 0, canvas.width, canvas.height)
  }
  requestAnimationFrame(frame)
}

A starting point written for this page, free to use in your own projects. The skills below build the finished version with checks, fallbacks and a recorded video.

What to get right on a real page

  1. 01

    Put the canvas on top, out of the way

    A fixed, full-screen canvas with pointer-events: none lets the burst cross the page without blocking clicks.

  2. 02

    Fire from the action

    Launching from the button the visitor pressed ties the reward to what they did.

  3. 03

    Skip it for reduced motion

    For visitors who turn motion off, show a check mark or a short message instead of the burst.

  4. 04

    Keep it off the words

    Confetti crossing a success message makes it hard to read. Aim the burst beside or above the text.

Skills that build a confetti animation

For a launch page that celebrates on loop rather than on click: a finished hero with your copy and a 1080p video.

  1. Confetti Launch Hero: an example of what it makes
    web
    Confetti Launch HeroClaude CodeCodexCursor+3 more agents

    Motion Heroes · Pro

    Confetti Launch Hero

    Animated canvas hero · page + embed + 1080p video

    A confetti cannon that fires from your main button: paper squares, strips, dots and curls, twisting streamers and sparkles burst out, hang, flutter down flipping to their darker backs, and settle along the floor of the hero before it clears and fires again. Every piece follows a closed-form path with drag and gravity, so the loop is exact, and confetti never crosses the headline.

    Worth knowing: It is a looping hero, not a one-off burst on click.

    Needs: Node.js 18+, Chrome (or Chromium/Edge), and ffmpeg for the video

    See what Confetti Launch Hero makes

Install

Build a confetti animation with your agent

Each skill is a SKILL.md folder, so it installs the same way in Claude Code, Codex, Cursor and other agents. The example below uses Confetti Launch Hero; each skill page has its own prompt.

1. Paste the install prompt

Your agent runs the installer. The first time, it shows a sign-in link so you can approve it in the browser.

Install the "Confetti Launch Hero" skill from Lookbk (https://lookbk.dev/skills/confetti-launch-hero).
1. Run: curl -fsSL https://lookbk.dev/cli.js | node - add confetti-launch-hero
2. If it prints a sign-in link, show it to me. When I say I approved it, run the same command again.
3. When the install finishes, read the SKILL.md it installed and tell me what you need from me to make the first result.

Or run it in a terminal

curl -fsSL https://lookbk.dev/cli.js | node - add confetti-launch-hero

2. Start a new session

Agents load skills when a session starts. The installer writes the folder where your agent looks:

Claude Code
~/.claude/skills/confetti-launch-hero
Codex
~/.agents/skills/confetti-launch-hero
Cursor
~/.agents/skills/confetti-launch-hero

3. Ask for the result

Describe it in plain words, for example:

Build a Confetti Launch hero for Tallybird, an invoicing app shipping version 3: deep violet ground, yellow accent, five bright paper colors firing from the 'Try 3.0 free' button, headline 'Invoices that chase themselves.', and record a 10-second loop.

Another agent? Install a skill in any agent

FAQ

Questions

Still stuck? The guides cover installing, agents and licensing in more detail.

Read the guides
How do I make a confetti animation in JavaScript?

Give each piece a launch velocity, then every frame apply air drag and gravity, move it and draw it rotated and squashed for flutter. The starter on this page is complete and stops on its own.

Can I make confetti with CSS only?

You can animate a few dozen absolutely positioned elements with keyframes, but each piece follows a fixed path. Canvas with simple physics looks more natural and handles hundreds of pieces.

How do I make the confetti flutter?

Rotate each piece over time and scale its height by the cosine of the rotation. It flips between face-on and edge-on like real paper.

How do I make a confetti loop for a video?

Use closed-form paths, positions computed straight from time instead of stepped frame by frame, so you can render any frame exactly and end the loop where it started. Confetti Launch Hero records a seamless 1080p MP4 that way.