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

@affectively/confetti-physics

v1.0.0

Published

Physics-based confetti celebrations with fluid dynamics, haptic feedback, and procedural audio. Built with hexgrid-3d math.

Downloads

889

Readme

@affectively/confetti-physics

Physics-based confetti celebrations with fluid dynamics, haptic feedback, and procedural audio. Built with hexgrid-3d math.

npm version License: MIT

Features

  • 🌀 Physics-based confetti - Fluid dynamics, flow fields, and particle attractors
  • 🎉 Classic confetti - Traditional particle effects via canvas-confetti
  • 🔊 Procedural audio - Web Audio API tones (no audio files needed)
  • 📳 Haptic feedback - Web Vibration API patterns
  • ⚛️ React hooks - Easy integration with React apps
  • Accessibility - Respects prefers-reduced-motion
  • 💾 Preference persistence - User settings saved to localStorage

Installation

npm install @affectively/confetti-physics
# or
yarn add @affectively/confetti-physics
# or
bun add @affectively/confetti-physics

Quick Start

Basic Usage

import { CelebrationService, ConfettiService, SoundService, HapticService } from '@affectively/confetti-physics';

// Quick celebration with confetti + sound + haptic
CelebrationService.celebrate('achievement');

// Physics-based confetti only
ConfettiService.supernova();
ConfettiService.aurora();
ConfettiService.vortex();

// Individual services
SoundService.success();
HapticService.celebrate();

React Hooks

import { useCelebration, useConfetti, usePhysicsConfetti } from '@affectively/confetti-physics/react';

function MyComponent() {
  const { celebrate, success, milestone } = useCelebration();
  const confetti = useConfetti();

  return (
    <div>
      <button onClick={() => celebrate('achievement')}>
        🏆 Unlock Achievement
      </button>
      <button onClick={() => confetti.supernova()}>
        💥 Supernova!
      </button>
    </div>
  );
}

Celebration Types

Orchestrated Celebrations

CelebrationService combines confetti, sound, and haptic feedback:

| Type | Confetti | Sound | Haptic | |------|----------|-------|--------| | tap | - | tap | light | | success | - | success | medium | | complete | sparkles | complete | medium | | achievement | achievement | milestone | strong | | milestone | milestone | milestone | strong | | streak | burst | streak | medium | | streakMilestone | streak | celebration | strong | | levelUp | levelUp | levelUp | strong | | unlock | stars | unlock | strong | | premium | premium | celebration | strong | | welcome | welcome | success | medium | | error | - | error | medium | | warning | - | warning | light |

Classic Confetti Effects

| Type | Description | |------|-------------| | burst | Quick celebration burst | | shower | Confetti rain from top | | fireworks | Firework explosions | | sparkles | Gentle sparkle effect | | stars | Star-shaped particles | | hearts | Heart emoji particles | | achievement | Grand achievement celebration | | streak | Fire + gold confetti | | milestone | Trophy + stars | | levelUp | Rocket + fireworks | | welcome | Gentle welcome | | premium | Crown + gem + gold |

Physics-Based Confetti Effects

These use fluid dynamics, flow fields, and attractors from hexgrid-3d:

| Type | Description | |------|-------------| | vortex | Spiral vortex pulling particles inward | | supernova | Explosive burst with fluid shockwave | | aurora | Flowing northern lights ribbons | | resonance | Heart-rate synced pulsing | | orbit | Particles orbiting multiple attractors | | cascade | Fluid waterfall effect | | emergence | Particles following flow field | | harmony | Lissajous pattern attractors | | helix | DNA-like double helix spiral | | bloom | Flower-like unfolding pattern | | constellation | Particles forming and connecting | | nebula | Gas cloud effect with density |

Emotion-Aware Celebrations

Automatically select effects and colors based on emotional context:

import { ConfettiService } from '@affectively/confetti-physics';

ConfettiService.celebrateEmotion({
  emotion: 'joy',
  valence: 0.8,   // -1 to 1 (negative to positive)
  arousal: 0.7,   // 0 to 1 (calm to excited)
  heartRate: 80   // Optional: sync with biometrics
});

Emotion Color Palettes

| Emotion | Colors | |---------|--------| | joy | Gold, amber | | serenity | Emerald, mint | | excitement | Rose, gold | | love | Pink, rose | | triumph | Purple, gold | | gratitude | Teal, emerald | | wonder | Sky blue, purple | | peace | Green, teal |

Sound Effects

14 procedurally generated sounds using Web Audio API:

import { SoundService } from '@affectively/confetti-physics';

SoundService.tap();           // Soft click
SoundService.success();       // C5-E5-G5 ascending
SoundService.celebration();   // Full fanfare
SoundService.milestone();     // Grand achievement
SoundService.streak();        // Quick excitement
SoundService.levelUp();       // Ascending scale
SoundService.unlock();        // Unlocking tone
SoundService.complete();      // Task done
SoundService.breatheIn();     // Rising tone for breathing exercises
SoundService.breatheOut();    // Falling tone
SoundService.heartbeat();     // Lub-dub rhythm
SoundService.error();         // Descending tone
SoundService.warn();          // Alert tone

Volume Control

SoundService.setVolume(0.5);  // 0-1
SoundService.setEnabled(false); // Mute

Haptic Feedback

15 vibration patterns via Web Vibration API:

import { HapticService } from '@affectively/confetti-physics';

HapticService.tap('light');       // Light tap
HapticService.success('medium');  // Satisfying success
HapticService.celebrate('strong'); // Excitement burst
HapticService.milestone();        // Grand achievement
HapticService.streak();           // Rapid fire
HapticService.levelUp();          // Ascending power
HapticService.unlock();           // Unlocking sensation
HapticService.heartbeat();        // Calming heartbeat
HapticService.breatheIn();        // For breathing exercises
HapticService.breatheOut();

Intensity Levels

  • light - 50% duration multiplier
  • medium - 100% (default)
  • strong - 150%

User Preferences

Preferences are automatically saved to localStorage:

import { CelebrationService } from '@affectively/confetti-physics';

// Get current settings
const settings = CelebrationService.getSettings();
// { soundEnabled, hapticEnabled, confettiEnabled, volume, hapticSupported, soundSupported }

// Update settings
CelebrationService.setSoundEnabled(false);
CelebrationService.setHapticEnabled(true);
CelebrationService.setConfettiEnabled(true);
CelebrationService.setVolume(0.7);

// Enable/disable all at once
CelebrationService.enableAll();
CelebrationService.disableAll();

React Hooks

useCelebration

Main hook for all celebration functionality:

const {
  celebrate,           // (type) => void
  celebrateCustom,     // (config) => void
  celebrateStreak,     // (days) => void
  tap, success, complete, achievement, milestone,
  levelUp, unlock, premium, welcome, error, warning,
  settings,            // Current settings
  setSoundEnabled, setHapticEnabled, setConfettiEnabled, setVolume
} = useCelebration();

useConfetti

For visual celebrations:

const {
  celebrate,           // (type) => void
  celebratePhysics,    // (config) => void
  celebrateEmotion,    // ({ emotion, valence, arousal }) => void
  enabled, setEnabled,
  physicsEnabled, setPreferPhysics,
  fromElement,         // (element, type?) => void
  reset,               // () => void
  // Classic: burst, shower, fireworks, sparkles, stars, hearts, etc.
  // Physics: vortex, supernova, aurora, resonance, orbit, cascade, etc.
} = useConfetti();

usePhysicsConfetti

Direct access to physics engine:

const {
  celebrate,           // (config) => void
  celebrateWithEmotion, // (type, emotion, options) => void
  clear,               // () => void
  enabled, setEnabled,
  isAvailable,
  // Each type as a method with optional config
  vortex, supernova, aurora, resonance, orbit, cascade,
  emergence, harmony, helix, bloom, constellation, nebula
} = usePhysicsConfetti();

useSound / useHaptic

Individual service hooks:

const sound = useSound();
const haptic = useHaptic();

// Both have:
// - enabled, supported, setEnabled
// - Convenience methods (tap, success, etc.)

useInteractionFeedback

For button feedback:

const { onPress, onSuccess, onError } = useInteractionFeedback();

<button onClick={onPress}>Click me</button>

useBreathingFeedback

For breathing exercises:

const { breatheIn, breatheOut, hold, complete, breathingCycle } = useBreathingFeedback();

useStreakCelebration

For streak milestones:

const { celebrateStreak, celebrateDaily, celebrateWeekly } = useStreakCelebration();

// celebrateStreak(days) automatically picks the right celebration:
// - Day 1: dailyCheckIn
// - Days 7, 30, 100, 365: streakMilestone
// - Other days: streak

Accessibility

The library automatically respects prefers-reduced-motion:

@media (prefers-reduced-motion: reduce) {
  /* Confetti and animations are disabled */
}

You can also manually disable effects:

CelebrationService.disableAll();
// or individually:
ConfettiService.setEnabled(false);
SoundService.setEnabled(false);
HapticService.setEnabled(false);

Browser Support

| Feature | Browser Support | |---------|-----------------| | Confetti (canvas) | All modern browsers | | Physics engine | All modern browsers | | Web Audio API | All modern browsers | | Vibration API | Android Chrome, Firefox |

Dependencies

License

MIT © AFFECTIVELY

Contributing

Contributions are welcome! Please read our contributing guidelines first.

Related Projects