npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@papit/confetti

v0.0.1

Published

a simple to use confetti

Readme

@papit/confetti

a simple to use confetti

Logo


Type Tests NPM version


<pap-confetti> is a canvas-based confetti burst web component, built on @papit/game-engine for the canvas/render loop and an internal particle system for the burst physics (rects, triangles, and circles with gravity, spread, and a soft "toward center" bias). It ships three built-in sound effects and can be triggered programmatically, by clicking the element itself, or by wiring it to an external control button.

installation

npm install @papit/confetti

to use in html

<script type="module" defer>
  import "@papit/confetti";
</script>

<pap-confetti></pap-confetti>

Usage

Trigger it from code

const confetti = document.querySelector("pap-confetti");

confetti.start();

// with options
confetti.start({
  amount: 200,
  sound: false,
  placement: "top-right",
});

start(options?) accepts a Partial of:

| Option | Type | Default | Description | | ----------- | ----------- | ---------------------------- | --------------------------------------------------------------- | | amount | number | 100 | number of particles to spawn for this burst | | sound | boolean | true | whether to play the pop/yay/horn sound effects | | placement | Placement | current placement property | overrides placement for this call (also updates the property) |

Calling start() while a burst is already animating clears the previous particles and restarts the render loop rather than stacking two loops.

Trigger it by clicking the element

<pap-confetti click></pap-confetti>

With the click attribute set, clicking the canvas fires a burst originating from the exact click position (converted from screen to canvas coordinates, accounting for canvas scaling), instead of a placement-based position.

Trigger it from another button

<button id="celebrate">🎉</button>
<pap-confetti aria-controls="celebrate"></pap-confetti>

Setting aria-controls to the id of an element in the same root (shadow root or document) wires a click listener on that element to call start(). Re-setting aria-controls cleans up the previous listener first.

Attributes / Properties

| Attribute | Property | Type | Default | Description | | --------------- | ----------- | ----------- | ---------- | ---------------------------------------------------------------------- | | placement | placement | Placement | "bottom" | where the burst originates from, see below | | click | withClick | boolean | false | if present, clicking the canvas triggers a burst at the click position | | aria-controls | controls | string | — | id of an external element that should trigger start() on click | | x | x | number | — | explicit burst origin X (overrides placement) | | y | y | number | — | explicit burst origin Y (overrides placement) |

Placement is one of:

"top-left" | "top" | "top-right"
"left" | "center" | "right"
"bottom-left" | "bottom" | "bottom-right"
"random"

"random" picks a new placement from the full set on every call to getPosition(). If both x and y are set, they take priority over placement for positioning (this is also how the click attribute positions bursts).

Sound effects

Three effects — /pop.mp3, /yay.mp3, /horn.mp3 — are loaded once per page (shared statically across all <pap-confetti> instances) and play on every start() call unless sound: false is passed. They're expected to be served from your app's root; host your own copies at those paths, or override by placing files at /pop.mp3, /yay.mp3, and /horn.mp3.

Styling

The component renders a single <canvas> in its shadow root and sizes it via resizeCanvasToDisplaySize() (from @papit/game-engine) whenever a burst starts, so it always matches the element's current on-screen size. Style the host element (width/height/position) as you would any block element; the canvas fills it.

Contributing

Contributions are welcome! Please follow the development guidelines above and ensure all tests pass before submitting a pull request.

License

Licensed under the @Papit License 1.0 - Copyright (c) 2024 Henry Pap (@onkelhoy)

Key points:

  • ✅ Free to use in commercial projects
  • ✅ Free to modify and distribute
  • ✅ Attribution required
  • ❌ Cannot resell the component itself as a standalone product

See the LICENSE file for full details.

Related Components

Support

For issues, questions, or contributions, please visit the GitHub repository.