diff --git a/README.md b/README.md index 79fe160..92ea8cf 100644 --- a/README.md +++ b/README.md @@ -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.

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).

The rotation speed determines how quickly the snowflake rotates when an image is being rendered.

The value for each snowflake will be randomly selected within this range. | `[-1.0, 1.0]` | -| `enable3DRotation`| Enable 3D rotation effect (like falling leaves).

When enabled, snowflakes will rotate on X, Y, and Z axes, creating a more realistic 3D tumbling effect.

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).

The speed determines how quickly the snowflake moves along the y axis (vertical speed).

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).

The wind determines how quickly the snowflake moves along the x axis (horizontal speed).

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.

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.

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).

The rotation speed determines how quickly the snowflake rotates when an image is being rendered.

The value for each snowflake will be randomly selected within this range. | `[-1.0, 1.0]` | +| `enable3DRotation` | Enable 3D rotation effect (like falling leaves).

When enabled, snowflakes will rotate on X, Y, and Z axes, creating a more realistic 3D tumbling effect.

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).

The speed determines how quickly the snowflake moves along the y axis (vertical speed).

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).

The wind determines how quickly the snowflake moves along the x axis (horizontal speed).

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.

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).

The values will be randomly selected within this range. | `[0, 360]` | ## Using Images diff --git a/packages/demo/src/App.tsx b/packages/demo/src/App.tsx index 6ddd651..b9c97b5 100644 --- a/packages/demo/src/App.tsx +++ b/packages/demo/src/App.tsx @@ -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 (
{ const mergedStyle = useSnowfallStyle(style) @@ -39,6 +40,7 @@ export const Snowfall = ({ snowflakeCount, opacity, enable3DRotation, + rotation, }) // A reference to the config used for creating the initial instance diff --git a/packages/react-snowfall/src/Snowflake.ts b/packages/react-snowfall/src/Snowflake.ts index 8e46a47..2182a80 100644 --- a/packages/react-snowfall/src/Snowflake.ts +++ b/packages/react-snowfall/src/Snowflake.ts @@ -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 @@ -89,6 +97,7 @@ export const defaultConfig: SnowflakeProps = { rotationSpeed: [-1.0, 1.0], opacity: [1, 1], enable3DRotation: false, + rotation: [0, 360], } interface SnowflakeParams { @@ -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), @@ -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() } @@ -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) @@ -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