Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,20 @@ Optional properties can be provided to customise the animation.

All available properties are detailed below.

| Property | Description | Default |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `changeFrequency` | The frequency in frames that the wind and speed values will update. | `200` |
| `color` | The color of the snowflake, can be any valid CSS color. | `'#dee4fd'` |
| `images` | An array of images that will be rendered as the snowflakes instead of the default circle shapes. | `undefined` |
| `radius` | The minimum and maximum radius of the snowflake in pixels.<br/><br/>The value for each snowflake will be randomly selected within this range. | `[0.5, 3.0]` |
| `rotationSpeed` | The minimum and maximum rotation speed of the snowflake (in degrees of rotation per frame).<br/><br/>The rotation speed determines how quickly the snowflake rotates when an image is being rendered.<br/><br/>The value for each snowflake will be randomly selected within this range. | `[-1.0, 1.0]` |
| `enable3DRotation`| Enable 3D rotation effect (like falling leaves).<br/><br/>When enabled, snowflakes will rotate on X, Y, and Z axes, creating a more realistic 3D tumbling effect.<br/><br/>Works with both images and circles. | `false` |
| `snowflakeCount` | The number of snowflakes to be rendered. | `150` |
| `speed` | The minimum and maximum speed of the snowflake (in pixels per frame).<br/><br/>The speed determines how quickly the snowflake moves along the y axis (vertical speed).<br/><br/>The value for each snowflake will be randomly selected within this range. | `[1.0, 3.0]` |
| `style` | Any style properties that will be passed to the canvas element. | `undefined` |
| `wind` | The minimum and maximum wind of the snowflake (in pixels per frame).<br/><br/>The wind determines how quickly the snowflake moves along the x axis (horizontal speed).<br/><br/>The value for each snowflake will be randomly selected within this range. | `[-0.5, 2.0]` |
| `opacity` | The minimum and maximum opacity of the snowflake.<br/><br/>The value for each snowflake will be randomly selected within this range. | `[1, 1]` |
| Property | Description | Default |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `changeFrequency` | The frequency in frames that the wind and speed values will update. | `200` |
| `color` | The color of the snowflake, can be any valid CSS color. | `'#dee4fd'` |
| `images` | An array of images that will be rendered as the snowflakes instead of the default circle shapes. | `undefined` |
| `radius` | The minimum and maximum radius of the snowflake in pixels.<br/><br/>The value for each snowflake will be randomly selected within this range. | `[0.5, 3.0]` |
| `rotationSpeed` | The minimum and maximum rotation speed of the snowflake (in degrees of rotation per frame).<br/><br/>The rotation speed determines how quickly the snowflake rotates when an image is being rendered.<br/><br/>The value for each snowflake will be randomly selected within this range. | `[-1.0, 1.0]` |
| `enable3DRotation` | Enable 3D rotation effect (like falling leaves).<br/><br/>When enabled, snowflakes will rotate on X, Y, and Z axes, creating a more realistic 3D tumbling effect.<br/><br/>Works with both images and circles. | `false` |
| `snowflakeCount` | The number of snowflakes to be rendered. | `150` |
| `speed` | The minimum and maximum speed of the snowflake (in pixels per frame).<br/><br/>The speed determines how quickly the snowflake moves along the y axis (vertical speed).<br/><br/>The value for each snowflake will be randomly selected within this range. | `[1.0, 3.0]` |
| `style` | Any style properties that will be passed to the canvas element. | `undefined` |
| `wind` | The minimum and maximum wind of the snowflake (in pixels per frame).<br/><br/>The wind determines how quickly the snowflake moves along the x axis (horizontal speed).<br/><br/>The value for each snowflake will be randomly selected within this range. | `[-0.5, 2.0]` |
| `opacity` | The minimum and maximum opacity of the snowflake.<br/><br/>The value for each snowflake will be randomly selected within this range. | `[1, 1]` |
| `rotation` | The minimum and maximum initial rotation of the snowflake (in degrees). <br/><br/>The values will be randomly selected within this range. | `[0, 360]` |

## Using Images

Expand Down
13 changes: 12 additions & 1 deletion packages/demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,24 @@ snowflake.src = logo
const images = [snowflake]

const App = () => {
const { color, snowflakeCount, radius, speed, wind, useImages, opacity, enable3DRotation } = useSettingsStore()
const {
color,
rotationSpeed,
snowflakeCount,
radius,
speed,
wind,
useImages,
opacity,
enable3DRotation
} = useSettingsStore()

return (
<div className="app">
<Snowfall
color={color}
snowflakeCount={snowflakeCount}
rotationSpeed={rotationSpeed}
radius={radius}
speed={speed}
wind={wind}
Expand Down
2 changes: 2 additions & 0 deletions packages/react-snowfall/src/Snowfall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const Snowfall = ({
snowflakeCount = 150,
images,
enable3DRotation = defaultConfig.enable3DRotation,
rotation = defaultConfig.rotation,
style,
}: SnowfallProps = {}): JSX.Element => {
const mergedStyle = useSnowfallStyle(style)
Expand All @@ -39,6 +40,7 @@ export const Snowfall = ({
snowflakeCount,
opacity,
enable3DRotation,
rotation,
})

// A reference to the config used for creating the initial instance
Expand Down
23 changes: 19 additions & 4 deletions packages/react-snowfall/src/Snowflake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ export interface SnowflakeProps {
* The default value is `false`.
*/
enable3DRotation?: boolean
/**
* The minimum and maximum initial rotation of the snowflake (in degrees).
*
* The values will be randomly selected within this range.
*
* The default value is `[0, 360]`.
*/
rotation: [number, number]
}

export type SnowflakeConfig = Partial<SnowflakeProps>
Expand All @@ -89,6 +97,7 @@ export const defaultConfig: SnowflakeProps = {
rotationSpeed: [-1.0, 1.0],
opacity: [1, 1],
enable3DRotation: false,
rotation: [0, 360],
}

interface SnowflakeParams {
Expand Down Expand Up @@ -148,12 +157,12 @@ class Snowflake {
this.updateConfig(config)

// Setting initial parameters
const { radius, wind, speed, rotationSpeed, opacity, enable3DRotation } = this.config
const { radius, wind, rotation, speed, rotationSpeed, opacity, enable3DRotation } = this.config

this.params = {
x: random(0, canvas.offsetWidth),
y: random(-canvas.offsetHeight, 0),
rotation: random(0, 360),
rotation: random(...rotation),
radius: random(...radius),
speed: random(...speed),
wind: random(...wind),
Expand Down Expand Up @@ -193,6 +202,10 @@ class Snowflake {
this.params.radius = random(...this.config.radius)
}

if (this.params && !isEqual(this.config.rotation, previousConfig?.rotation)) {
this.params.rotation = random(...this.config.rotation)
}

if (!isEqual(this.config.images, previousConfig?.images)) {
this.selectImage()
}
Expand All @@ -215,7 +228,7 @@ class Snowflake {
}

public update(offsetWidth: number, offsetHeight: number, framesPassed = 1): void {
const { x, y, rotation, rotationSpeed, nextRotationSpeed, wind, speed, nextWind, nextSpeed, radius } = this.params
const { x, y, rotationSpeed, nextRotationSpeed, wind, speed, nextWind, nextSpeed, radius } = this.params

// Update current location, wrapping around if going off the canvas
this.params.x = (x + wind * framesPassed) % (offsetWidth + radius * 2)
Expand All @@ -226,12 +239,14 @@ class Snowflake {
this.params.opacity = random(...this.config.opacity)
this.params.hasNextOpacity = false
}
this.params.rotation = random(...this.config.rotation)

this.params.y = -radius
}

// Apply rotation
if (this.image || this.config.enable3DRotation) {
this.params.rotation = (rotation + rotationSpeed) % 360
this.params.rotation = (this.params.rotation + this.params.rotationSpeed * framesPassed) % 360
}

// Apply 3D rotation if enabled
Expand Down