Skip to content

❄️ A realistic snowfall effect for React with physics-based accumulation on surfaces. Features melting, wind, and smart surface detection.

License

Notifications You must be signed in to change notification settings

hdcodedev/snowfall

Repository files navigation

npm version

A realistic snowfall effect for React with physics-based accumulation on surfaces. Features melting, wind, and smart surface detection.

ScreenRecording2025-12-23at00 07 30-ezgif com-optimize

Features

  • Realistic Physics - Wind, wobble, and varied snowflake speeds
  • Surface Accumulation - Snow naturally piles up on elements
  • Melting Effect - Gradual melting over time
  • Border-Radius Aware - Respects rounded corners
  • Auto-Detection - Automatically finds and accumulates on semantic elements
  • High Performance - Smooth 60 FPS with adaptive optimizations
  • Toggleable - Enable/disable on demand
  • Responsive - Adapts to viewport and element changes

Installation

npm install @hdcodedev/snowfall

or

yarn add @hdcodedev/snowfall

Quick Start

Snowfall automatically detects semantic tags (like <header>) and styled elements. You can also force accumulation manually.

Basic Usage

import { Snowfall, SnowfallProvider } from '@hdcodedev/snowfall';

export default function App() {
  return (
    <SnowfallProvider>
      <Snowfall />

      {/* Auto-detected: Headers accumulate snow on BOTTOM */}
      <header>
        <h1>My Site</h1>
      </header>
      
      {/* Auto-detected: Footers accumulate snow on TOP (natural piling) */}
      <footer>
        <p>© 2025</p>
      </footer>
      
      {/* Manual: Force accumulation on any element */}
      <div data-snowfall="top">
        <h2>Custom Element</h2>
      </div>
      
      {/* Disable accumulation on specific elements */}
      <div data-snowfall="ignore">
        <p>No snow here</p>
      </div>
    </SnowfallProvider>
  );
}

Surface Types

  • data-snowfall="top" (default for most elements): Snow accumulates on the top edge, piling downward
  • data-snowfall="bottom" (default for <header> tags): Snow accumulates on the bottom edge
  • data-snowfall="ignore": Prevents snow accumulation on the element

By default:

  • <header> and role="banner" → Bottom accumulation
  • <footer> and other elements → Top accumulation (natural piling)

Customization

You can customize physics via the SnowfallProvider:

import { SnowfallProvider, DEFAULT_PHYSICS } from '@hdcodedev/snowfall';

const customPhysics = {
  ...DEFAULT_PHYSICS,
  MAX_FLAKES: 500,              // Maximum number of snowflakes
  MELT_SPEED: 0.00005,          // How fast snow melts (lower = lasts longer)
  WIND_STRENGTH: 1.5,           // Wind intensity
  ACCUMULATION: {
    SIDE_RATE: 1.0,             // Accumulation rate on sides
    TOP_RATE: 5.0,              // Accumulation rate on top surfaces
    BOTTOM_RATE: 5.0,           // Accumulation rate on bottom surfaces (headers)
  },
  MAX_DEPTH: {
    TOP: 100,                   // Max snow height on top surfaces (px)
    BOTTOM: 50,                 // Max snow height on bottom surfaces (px)
    SIDE: 20,                   // Max snow width on sides (px)
  },
  FLAKE_SIZE: {
    MIN: 0.5,                   // Minimum flake radius
    MAX: 1.6,                   // Maximum flake radius
  }
};

API

<SnowfallProvider>

Wraps your app to provide snowfall context.

<Snowfall />

The main snowfall canvas component. Must be used within SnowfallProvider.

useSnowfall()

Hook to access snowfall controls. Must be used within SnowfallProvider.

Returns:

{
  isEnabled: boolean;                           // Current enabled state
  toggleSnow: () => void;                       // Function to toggle snow on/off
  physicsConfig: PhysicsConfig;                 // Current physics configuration
  updatePhysicsConfig: (config: Partial<PhysicsConfig>) => void;  // Update physics
  resetPhysics: () => void;                     // Reset to default physics
}

Tips

  • The snowfall canvas has pointer-events: none, so it won't interfere with user interactions
  • Snow accumulation works best on static or slowly-changing layouts
  • The component uses 'use client' directive for Next.js 13+ App Router compatibility

Performance Optimizations

Key optimizations for smooth 60 FPS performance:

  • Probabilistic Collision Detection: Only 30% of snowflakes check collisions per frame (configurable via COLLISION_CHECK_RATE), significantly reducing CPU load while maintaining visual quality
  • Adaptive Spawn Rate: Automatically reduces snowflake spawning when FPS drops below 40 to prevent performance degradation
  • Viewport Culling: Only renders accumulation for visible elements
  • Zero-allocation FPS Tracking: Uses a second-bucket approach to eliminate per-frame memory allocations

Tuning for lower-end devices:

const customPhysics = {
  ...DEFAULT_PHYSICS,
  MAX_FLAKES: 200,
  COLLISION_CHECK_RATE: 0.1,
  MAX_SURFACES: 15,
};

Development

# Install dependencies
npm install

# Build the library
npm run build

# Run in development mode
npm run dev

# Run the demo
cd demo && npm run dev

License

Copyright © 2025 hdcodedev.

Licensed under the Apache 2.0 License.

Contributing

Contributions are welcome! If you like this project, please give it a star ⭐

Found a bug or have a feature request? Open an issue on GitHub.

About

❄️ A realistic snowfall effect for React with physics-based accumulation on surfaces. Features melting, wind, and smart surface detection.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •