Skip to content

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.

Screenshot 2026-03-29 at 19 18 18

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 HTML elements like <header> and <footer> and accumulates snow on their edges. You can also mark any element 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

Use the data-snowfall attribute to control where snow accumulates on an element:

  • data-snowfall="top" — Snow piles up on the top edge (default for <footer> and most elements)
  • data-snowfall="bottom" — Snow hangs from the bottom edge (default for <header> and role="banner")
  • data-snowfall="ignore" — No snow accumulates on this element

Customization

You can customize how snow behaves 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 manage snowfall state. Place it at the root of your component tree.

<Snowfall />

Renders the snowfall canvas. Must be placed inside SnowfallProvider. Snow accumulates on detected elements automatically.

useSnowfall()

Hook to control snowfall at runtime. Must be used inside SnowfallProvider.

Returns:

{
  isEnabled: boolean;                           // Whether snow is currently falling
  toggleSnow: () => void;                       // Start or stop the snowfall
  physicsConfig: PhysicsConfig;                 // Current snow behavior settings
  updatePhysicsConfig: (config: Partial<PhysicsConfig>) => void;  // Change settings at runtime
  resetPhysics: () => void;                     // Restore default settings
}

Tips

  • Snow is drawn on a transparent layer that doesn't block clicks, scrolling, or other 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:

  • Smart Collision Checks: Only 30% of snowflakes check for collisions each frame (configurable via COLLISION_CHECK_RATE), reducing CPU load while maintaining visual quality
  • Adaptive Spawn Rate: Automatically reduces snowflake count when FPS drops below 40
  • Offscreen Skipping: Only processes accumulation for elements visible in the viewport
  • Efficient FPS Tracking: Uses a second-bucket approach to avoid per-frame memory allocations

For slower devices, reduce the load:

const customPhysics = {
  ...DEFAULT_PHYSICS,
  MAX_FLAKES: 200,             // Fewer snowflakes
  COLLISION_CHECK_RATE: 0.1,   // Check fewer flakes per frame
  MAX_SURFACES: 15,            // Fewer surfaces to track
};

License

MIT

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