Lightweight falling effects (snow, flower, leaf) for any website
npm install @sangdonpark/falling-effectsbash
npm install @sangdonpark/falling-effects
`
🚀 Usage
$3
This library must be used in a Client Component.
`ts
"use client";
import { useEffect } from "react";
import { startFalling } from "@sangdonpark/falling-effects";
export default function FallingEffect() {
useEffect(() => {
const cleanup = startFalling({
type: "flower",
mode: "rate",
rate: 30,
maxParticles: 120,
rampUpSeconds: 1.5,
duration: 10,
direction: "diagonal",
diagonalDirection: "left-to-right",
diagonalStrength: 200,
sway: true,
});
return () => cleanup();
}, []);
return null;
}
`
Add the component to app/layout.tsx to enable the effect globally.
`ts
import FallingEffect from "@/components/FallingEffect";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
`
$3
Use inside useEffect.
startFalling() returns a cleanup function
`ts
import { useEffect } from "react";
import { startFalling } from "@sangdonpark/falling-effects";
export default function FallingEffect() {
useEffect(() => {
const cleanup = startFalling({
type: "flower",
mode: "rate",
rate: 30,
maxParticles: 120,
rampUpSeconds: 1.5,
duration: 10,
direction: "diagonal",
diagonalDirection: "left-to-right",
diagonalStrength: 200,
sway: true,
});
return () => cleanup();
}, []);
return null;
}
`
$3
Call startFalling() after the DOM is ready.
`html
`
⚙️ Options
$3
| Option | Type | Default | Description |
| ------ | ------------------------------ | -------- | ----------------------- |
| type | "snow" \| "flower" \| "leaf" | "snow" | Particle type to render |
---
$3
| Option | Type | Default | Description |
| --------------- | ------------------- | ----------- | ------------------------------------------------------ |
| mode | "rate" \| "count" | "rate" | Spawn mode |
| rate | number | 10 | Particles spawned per second (rate mode) |
| density | number | 30 | Target particle count (count mode) |
| maxParticles | number | 150 | Maximum number of active particles |
| duration | number | undefined | Spawn duration in seconds (omit for continuous effect) |
| rampUpSeconds | number | 0 | Smooth ramp-up time in seconds |
---
$3
| Option | Type | Default | Description |
| ------------------- | ------------------------------------ | ----------------- | ----------------------------- |
| direction | "vertical" \| "diagonal" | "vertical" | Falling direction |
| diagonalDirection | "left-to-right" \| "right-to-left" | "left-to-right" | Diagonal movement direction |
| diagonalStrength | number | 120 | Strength of diagonal movement |
| speedMultiplier | number | 1 | Global speed multiplier |
---
$3
| Option | Type | Default | Description |
| -------------------- | ------------------ | ------------ | -------------------------- |
| sway | boolean | false | Enable natural sway motion |
| swayAmplitudeRange | [number, number] | [10, 30] | Sway amplitude range (px) |
| swayFrequencyRange | [number, number] | [0.2, 0.8] | Sway frequency range (Hz) |
---
$3
| Option | Type | Default | Description |
| -------- | -------- | ------- | ------------------------------- |
| zIndex | number | 9999 | z-index of the effect container |
---
🎛 Presets
$3
`ts
startFalling({
type: "snow | flower | leaf",
mode: "rate",
rate: 30,
maxParticles: 120,
rampUpSeconds: 1.5,
duration: 10,
direction: "diagonal",
diagonalDirection: "left-to-right",
diagonalStrength: 200,
sway: true,
});
``