UNPKG

@tsparticles/confetti

Version:

Easily create highly customizable particle animations and use them as animated backgrounds for your website. Ready to use components available also for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Riot.js, Inferno.

356 lines (355 loc) 12.2 kB
import { isSsr, isString, millisecondsToSeconds, tsParticles, } from "@tsparticles/engine"; import { loadEmittersPlugin } from "@tsparticles/plugin-emitters"; import { ConfettiOptions } from "./ConfettiOptions.js"; import { loadBasic } from "@tsparticles/basic"; import { loadCardsShape } from "@tsparticles/shape-cards"; import { loadEmojiShape } from "@tsparticles/shape-emoji"; import { loadHeartShape } from "@tsparticles/shape-heart"; import { loadImageShape } from "@tsparticles/shape-image"; import { loadLifeUpdater } from "@tsparticles/updater-life"; import { loadMotionPlugin } from "@tsparticles/plugin-motion"; import { loadPolygonShape } from "@tsparticles/shape-polygon"; import { loadRollUpdater } from "@tsparticles/updater-roll"; import { loadRotateUpdater } from "@tsparticles/updater-rotate"; import { loadSquareShape } from "@tsparticles/shape-square"; import { loadStarShape } from "@tsparticles/shape-star"; import { loadTiltUpdater } from "@tsparticles/updater-tilt"; import { loadWobbleUpdater } from "@tsparticles/updater-wobble"; const defaultGravity = 9.81, sizeFactor = 5, speedFactor = 3, decayOffset = 1, disableRotate = 0, disableTilt = 0; let initialized = false; let initializing = false; const ids = new Map(); async function initPlugins(engine) { if (initialized) { return; } if (initializing) { return new Promise(resolve => { const timeout = 100, interval = setInterval(() => { if (!initialized) { return; } clearInterval(interval); resolve(); }, timeout); }); } initializing = true; engine.checkVersion("3.9.1"); await loadEmittersPlugin(engine, false); await loadMotionPlugin(engine, false); await loadCardsShape(engine, false); await loadHeartShape(engine, false); await loadImageShape(engine, false); await loadPolygonShape(engine, false); await loadSquareShape(engine, false); await loadStarShape(engine, false); await loadEmojiShape(engine, false); await loadRotateUpdater(engine, false); await loadLifeUpdater(engine, false); await loadRollUpdater(engine, false); await loadTiltUpdater(engine, false); await loadWobbleUpdater(engine, false); await loadBasic(engine); initializing = false; initialized = true; } async function setConfetti(params) { const actualOptions = new ConfettiOptions(); actualOptions.load(params.options); let container; const fpsLimit = 120, fpsLimitFactor = 3.6, opacitySpeed = (actualOptions.ticks * millisecondsToSeconds) / (fpsLimitFactor * millisecondsToSeconds * fpsLimit); if (ids.has(params.id)) { container = ids.get(params.id); if (container && !container.destroyed) { const alias = container; if (alias.addEmitter) { await alias.addEmitter({ startCount: actualOptions.count, position: actualOptions.position, size: { width: 0, height: 0, }, rate: { delay: 0, quantity: 0, }, life: { duration: 0.1, count: 1, }, particles: { color: { value: actualOptions.colors, }, shape: { type: actualOptions.shapes, options: actualOptions.shapeOptions, }, life: { count: 1, }, opacity: { value: { min: 0, max: 1 }, animation: { enable: true, sync: true, speed: opacitySpeed, startValue: "max", destroy: "min", }, }, size: { value: sizeFactor * actualOptions.scalar, }, move: { angle: { value: actualOptions.spread, offset: 0, }, drift: { min: -actualOptions.drift, max: actualOptions.drift, }, gravity: { acceleration: actualOptions.gravity * defaultGravity, }, speed: actualOptions.startVelocity * speedFactor, decay: decayOffset - actualOptions.decay, direction: -actualOptions.angle, }, rotate: { value: actualOptions.flat ? disableRotate : { min: 0, max: 360, }, direction: "random", animation: { enable: !actualOptions.flat, speed: 60, }, }, tilt: { direction: "random", enable: !actualOptions.flat, value: actualOptions.flat ? disableTilt : { min: 0, max: 360, }, animation: { enable: true, speed: 60, }, }, roll: { darken: { enable: true, value: 25, }, enable: !actualOptions.flat, speed: { min: 15, max: 25, }, }, wobble: { distance: 30, enable: !actualOptions.flat, speed: { min: -15, max: 15, }, }, }, }); return; } } } const particlesOptions = { fullScreen: { enable: !params.canvas, zIndex: actualOptions.zIndex, }, fpsLimit: 120, particles: { number: { value: 0, }, color: { value: actualOptions.colors, }, shape: { type: actualOptions.shapes, options: actualOptions.shapeOptions, }, opacity: { value: { min: 0, max: 1 }, animation: { enable: true, sync: true, speed: opacitySpeed, startValue: "max", destroy: "min", }, }, size: { value: sizeFactor * actualOptions.scalar, }, links: { enable: false, }, life: { count: 1, }, move: { angle: { value: actualOptions.spread, offset: 0, }, drift: { min: -actualOptions.drift, max: actualOptions.drift, }, enable: true, gravity: { enable: true, acceleration: actualOptions.gravity * defaultGravity, }, speed: actualOptions.startVelocity * speedFactor, decay: decayOffset - actualOptions.decay, direction: -actualOptions.angle, random: true, straight: false, outModes: { default: "none", bottom: "destroy", }, }, rotate: { value: actualOptions.flat ? disableRotate : { min: 0, max: 360, }, direction: "random", animation: { enable: !actualOptions.flat, speed: 60, }, }, tilt: { direction: "random", enable: !actualOptions.flat, value: actualOptions.flat ? disableTilt : { min: 0, max: 360, }, animation: { enable: true, speed: 60, }, }, roll: { darken: { enable: true, value: 25, }, enable: !actualOptions.flat, speed: { min: 15, max: 25, }, }, wobble: { distance: 30, enable: !actualOptions.flat, speed: { min: -15, max: 15, }, }, }, detectRetina: true, motion: { disable: actualOptions.disableForReducedMotion, }, emitters: { name: "confetti", startCount: actualOptions.count, position: actualOptions.position, size: { width: 0, height: 0, }, rate: { delay: 0, quantity: 0, }, life: { duration: 0.1, count: 1, }, }, }; container = await tsParticles.load({ id: params.id, element: params.canvas, options: particlesOptions }); ids.set(params.id, container); return container; } export async function confetti(idOrOptions, confettiOptions) { await initPlugins(tsParticles); let options; let id; if (isString(idOrOptions)) { id = idOrOptions; options = confettiOptions ?? {}; } else { id = "confetti"; options = idOrOptions; } return setConfetti({ id, options, }); } confetti.create = async (canvas, options) => { if (!canvas) { return confetti; } await initPlugins(tsParticles); const id = canvas.getAttribute("id") ?? "confetti"; canvas.setAttribute("id", id); return async (idOrOptions, confettiOptions) => { let subOptions; let subId; if (isString(idOrOptions)) { subId = idOrOptions; subOptions = confettiOptions ?? options; } else { subId = id; subOptions = idOrOptions; } return setConfetti({ id: subId, canvas, options: subOptions, }); }; }; confetti.init = async () => { await initPlugins(tsParticles); }; confetti.version = "3.9.1"; if (!isSsr()) { window.confetti = confetti; }