Confetti
framecn/confettiFreeComponent
Deterministic CSS-animated particle burst celebration effect.
Install it
npx shadcn@latest add https://framecn.dev/r/confetti.jsonSource
1"use client";23import { Timegroup } from "@editframe/react";4import type { CSSProperties } from "react";56export interface ConfettiProps {7 particleCount?: number;8 originX?: number;9 originY?: number;10 lifetime?: number;11 power?: number;12 gravity?: number;13 size?: number;14 seed?: number;15 colors?: string[];16 fps?: number;17 durationInFrames?: number;18 width?: number;19 height?: number;20 background?: string;21 className?: string;22 speed?: number;23}2425// Park-Miller PRNG — no bitwise operations needed26const makePrng = (initialSeed: number) => {27 let s = (Math.abs(initialSeed) % 2_147_483_646) + 1;28 return () => {29 s = (s * 16_807) % 2_147_483_647;30 return (s - 1) / 2_147_483_646;31 };32};3334export const Confetti = ({35 particleCount = 80,36 originX = 0.5,37 originY = 0.5,38 lifetime = 90,39 power = 17,40 gravity = 0.45,41 size = 13,42 seed = 1,43 colors = ["#1d9bf0", "#ff5da2", "#ffd23f", "#22c55e", "#a855f7", "#ff7a45"],44 background = "white",45 fps = 30,46 durationInFrames = 180,47 width = 1280,48 height = 720,49 className,50 speed = 1,51}: ConfettiProps) => {52 const durationMs = (durationInFrames / fps) * 1000;53 const safeSpeed = Math.max(0.01, speed);54 const lifetimeMs = ((lifetime / fps) * 1000) / safeSpeed;5556 const rand = makePrng(seed);57 const safeCount = Math.min(particleCount, 120);5859 const particles = Array.from({ length: safeCount }, (_, i) => {60 const angle = rand() * Math.PI * 2;61 const spd = rand() * power;62 const drift = (rand() - 0.5) * 2;63 const vx = Math.cos(angle) * spd + drift;64 const vy = Math.sin(angle) * spd;65 const lt = lifetime;6667 const startX = originX * width;68 const startY = originY * height;69 const endX = startX + vx * lt;70 const endY = startY + (vy * lt + 0.5 * gravity * lt * lt);7172 const color = colors[i % colors.length] ?? "#fff";73 const rot0 = rand() * 360;74 const rotSpeed = (rand() - 0.5) * 720;75 const endRot = rot0 + rotSpeed;76 const w = size * (0.5 + rand() * 0.5);77 const h = size * (0.5 + rand() * 0.5);7879 return { color, endRot, endX, endY, h, i, rot0, startX, startY, w };80 });8182 const keyframesCSS = particles83 .map(84 ({ startX, startY, endX, endY, rot0, endRot, i }) => `85 @keyframes framecn-confetti-p-${i}-${seed} {86 0% { opacity: 0; transform: translate(${startX - width / 2}px, ${startY - height / 2}px) rotate(${rot0}deg); }87 5% { opacity: 1; }88 70% { opacity: 1; }89// … truncated
What it pulls in
npm packages
Files it writes
More from framecn
All 101 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AI Generate Overlayai-generate-overlay | framecn | Components | Free | 1 dep | |
| AI Generation Canvasai-generation-canvas | framecn | Components | Free | 1 dep | |
| Animated Bar Chartanimated-bar-chart | framecn | Components | Free | 1 dep | |
| Animated Line Chartanimated-line-chart | framecn | Components | Free | 1 dep | |
| Backdropbackdrop | framecn | Components | Free | 1 dep | |
| Blur Out Upblur-out-up | framecn | Components | Free | 1 dep | |
| Blur Revealblur-reveal | framecn | Components | Free | 1 dep | |
| Bounding Box Selectorbounding-box-selector | framecn | Components | Free | 1 dep |
