Home

Awesome

Canvas Confetti

github actions ci jsdelivr npm-downloads npm-version

Demo

catdad.github.io/canvas-confetti

Install

You can install this module as a component from NPM:

npm install --save canvas-confetti

You can then require('canvas-confetti'); to use it in your project build. Note: this is a client component, and will not run in Node. You will need to build your project with something like webpack in order to use this.

You can also include this library in your HTML page directly from a CDN:

<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.3/dist/confetti.browser.min.js"></script>

Note: you should use the latest version at the time that you include your project. You can see all versions on the releases page.

Reduced Motion

Thank you for joining me in this very important message about motion on your website. See, not everyone likes it, and some actually prefer no motion. They have ways to tell us about it and we should listen. While I don't want to go as far as tell you not to have confetti on your page just yet, I do want to make it easy for you to respect what your users want. There is a disableForReducedMotion option you can use so that users that have trouble with chaotic animations don't need to struggle on your website. This is disabled by default, but I am considering changing that in a future major release. If you have strong feelings about this, please let me know. For now, please confetti responsibly.

API

When installed from npm, this library can be required as a client component in your project build. When using the CDN version, it is exposed as a confetti function on window.

confetti([options {Object}])Promise|null

confetti takes a single optional object. When window.Promise is available, it will return a Promise to let you know when it is done. When promises are not available (like in IE), it will return null. You can polyfill promises using any of the popular polyfills. You can also provide a promise implementation to confetti through:

const MyPromise = require('some-promise-lib');
const confetti = require('canvas-confetti');
confetti.Promise = MyPromise;

If you call confetti multiple times before it is done, it will return the same promise every time. Internally, the same canvas element will be reused, continuing the existing animation with the new confetti added. The promise returned by each call to confetti will resolve once all animations are done.

options

The confetti parameter is a single optional options object, which has the following properties:

confetti.shapeFromPath({ path, matrix? })Shape

This helper method lets you create a custom confetti shape using an SVG Path string. Any valid path should work, though there are a few caveats:

This method will return a Shape -- it's really just a plain object with some properties, but shhh... we'll pretend it's a shape. Pass this Shape object into the shapes array directly.

As an example, here's how you might do a triangle confetti:

var triangle = confetti.shapeFromPath({ path: 'M0 10 L5 0 L10 10z' });

confetti({
  shapes: [triangle]
});

confetti.shapeFromText({ text, scalar?, color?, fontFamily? })Shape

This is the highly anticipated feature to render emoji confetti! Use any standard unicode emoji. Or other text, but... maybe don't use other text.

While any text should work, there are some caveats:

The options for this method are:

var scalar = 2;
var pineapple = confetti.shapeFromText({ text: '🍍', scalar });

confetti({
  shapes: [pineapple],
  scalar
});

confetti.create(canvas, [globalOptions])function

This method creates an instance of the confetti function that uses a custom canvas. This is useful if you want to limit the area on your page in which confetti appear. By default, this method will not modify the canvas in any way (other than drawing to it).

Canvas can be misunderstood a bit though, so let me explain why you might want to let the module modify the canvas just a bit. By default, a canvas is a relatively small image -- somewhere around 300x150, depending on the browser. When you resize it using CSS, this sets the display size of the canvas, but not the image being represented on that canvas. Think of it as loading a 300x150 jpeg image in an img tag and then setting the CSS for that tag to 1500x600 -- your image will end up stretched and blurry. In the case of a canvas, you need to also set the width and height of the canvas image itself. If you don't want to do that, you can allow confetti to set it for you.

Note also that you should persist the custom instance and avoid initializing an instance of confetti with the same canvas element more than once.

The following global options are available:

Important: If you use useWorker: true, I own your canvas now. It's mine now and I can do whatever I want with it (don't worry... I'll just put confetti inside it, I promise). You must not try to use the canvas in any way (other than I guess removing it from the DOM), as it will throw an error. When using workers for rendering, control of the canvas must be transferred to the web worker, preventing any usage of that canvas on the main thread. If you must manipulate the canvas in any way, do not use this option.

var myCanvas = document.createElement('canvas');
document.body.appendChild(myCanvas);

var myConfetti = confetti.create(myCanvas, {
  resize: true,
  useWorker: true
});
myConfetti({
  particleCount: 100,
  spread: 160
  // any other options from the global
  // confetti function
});

confetti.reset()

Stops the animation and clears all confetti, as well as immediately resolves any outstanding promises. In the case of a separate confetti instance created with confetti.create, that instance will have its own reset method.

confetti();

setTimeout(() => {
  confetti.reset();
}, 100);
var myCanvas = document.createElement('canvas');
document.body.appendChild(myCanvas);

var myConfetti = confetti.create(myCanvas, { resize: true });

myConfetti();

setTimeout(() => {
  myConfetti.reset();
}, 100);

Examples

Launch some confetti the default way:

confetti();

Launch a bunch of confetti:

confetti({
  particleCount: 150
});

Launch some confetti really wide:

confetti({
  spread: 180
});

Get creative. Launch a small poof of confetti from a random part of the page:

confetti({
  particleCount: 100,
  startVelocity: 30,
  spread: 360,
  origin: {
    x: Math.random(),
    // since they fall down, start a bit higher than random
    y: Math.random() - 0.2
  }
});

I said creative... we can do better. Since it doesn't matter how many times we call confetti (just the total number of confetti in the air), we can do some fun things, like continuously launch more and more confetti for 30 seconds, from multiple directions:

// do this for 30 seconds
var duration = 30 * 1000;
var end = Date.now() + duration;

(function frame() {
  // launch a few confetti from the left edge
  confetti({
    particleCount: 7,
    angle: 60,
    spread: 55,
    origin: { x: 0 }
  });
  // and launch a few from the right edge
  confetti({
    particleCount: 7,
    angle: 120,
    spread: 55,
    origin: { x: 1 }
  });

  // keep going until we are out of time
  if (Date.now() < end) {
    requestAnimationFrame(frame);
  }
}());