A realistic snowfall effect for React with physics-based accumulation on surfaces. Features melting, wind, and smart surface detection.
- 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
npm install @hdcodedev/snowfallor
yarn add @hdcodedev/snowfallSnowfall automatically detects semantic tags (like <header>) and styled elements. You can also force accumulation manually.
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>
);
}data-snowfall="top"(default for most elements): Snow accumulates on the top edge, piling downwarddata-snowfall="bottom"(default for<header>tags): Snow accumulates on the bottom edgedata-snowfall="ignore": Prevents snow accumulation on the element
By default:
<header>androle="banner"→ Bottom accumulation<footer>and other elements → Top accumulation (natural piling)
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
}
};Wraps your app to provide snowfall context.
The main snowfall canvas component. Must be used within SnowfallProvider.
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
}- 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
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,
};# Install dependencies
npm install
# Build the library
npm run build
# Run in development mode
npm run dev
# Run the demo
cd demo && npm run devCopyright © 2025 hdcodedev.
Licensed under the Apache 2.0 License.
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.
