From efc40d964b66c69deb39110cef89020ba0feab83 Mon Sep 17 00:00:00 2001 From: Dmitry Kravtsov Date: Wed, 29 Nov 2023 17:05:48 +0300 Subject: [PATCH] Add support opacity for snowflake --- README.md | 1 + packages/demo/src/App.tsx | 3 +- .../demo/src/components/Settings/Settings.tsx | 45 ++++++++++++------- packages/demo/src/settings.tsx | 3 +- packages/react-snowfall/lib/Snowfall.d.ts | 2 +- packages/react-snowfall/lib/Snowfall.js | 3 +- packages/react-snowfall/lib/Snowfall.js.map | 2 +- packages/react-snowfall/lib/Snowflake.d.ts | 6 +++ packages/react-snowfall/lib/Snowflake.js | 13 +++++- packages/react-snowfall/lib/Snowflake.js.map | 2 +- packages/react-snowfall/src/Snowfall.tsx | 2 + packages/react-snowfall/src/Snowflake.ts | 26 ++++++++++- 12 files changed, 85 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6d7b813..b5366be 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ All available properties are detailed below. | `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]` | ## Using Images diff --git a/packages/demo/src/App.tsx b/packages/demo/src/App.tsx index aefc770..35fd09e 100644 --- a/packages/demo/src/App.tsx +++ b/packages/demo/src/App.tsx @@ -14,7 +14,7 @@ snowflake.src = logo const images = [snowflake] const App = () => { - const { color, snowflakeCount, radius, speed, wind, useImages } = useSettingsStore() + const { color, snowflakeCount, radius, speed, wind, useImages, opacity } = useSettingsStore() return (
@@ -25,6 +25,7 @@ const App = () => { speed={speed} wind={wind} images={useImages ? images : undefined} + opacity={opacity} /> Snowflake Logo diff --git a/packages/demo/src/components/Settings/Settings.tsx b/packages/demo/src/components/Settings/Settings.tsx index 0259b24..4598c17 100644 --- a/packages/demo/src/components/Settings/Settings.tsx +++ b/packages/demo/src/components/Settings/Settings.tsx @@ -107,21 +107,36 @@ const Settings = () => { />
{settings.useImages ? ( -
- - Rotation Speed - - - - settings.update({ rotationSpeed: value as [number, number] }) - } - /> -
+ <> +
+ + Opacity + + + settings.update({ opacity: value as [number, number] })} + /> +
+
+ + Rotation Speed + + + + settings.update({ rotationSpeed: value as [number, number] }) + } + /> +
+ ) : ( diff --git a/packages/demo/src/settings.tsx b/packages/demo/src/settings.tsx index aef244d..a44f208 100644 --- a/packages/demo/src/settings.tsx +++ b/packages/demo/src/settings.tsx @@ -14,6 +14,7 @@ export const useSettingsStore = create((set) => ({ speed: [0.5, 3.0], wind: [-0.5, 2.0], rotationSpeed: [-1.0, 1.0], + opacity: [0.1, 0.2], useImages: false, update: (changes) => set(changes), setUseImages: (useImages) => { @@ -22,5 +23,5 @@ export const useSettingsStore = create((set) => ({ } else { return set({ useImages, radius: [0.5, 3] }) } - } + }, })) diff --git a/packages/react-snowfall/lib/Snowfall.d.ts b/packages/react-snowfall/lib/Snowfall.d.ts index e9453c9..ef3401a 100644 --- a/packages/react-snowfall/lib/Snowfall.d.ts +++ b/packages/react-snowfall/lib/Snowfall.d.ts @@ -6,5 +6,5 @@ export interface SnowfallProps extends Partial { */ style?: React.CSSProperties; } -export declare const Snowfall: ({ color, changeFrequency, radius, speed, wind, rotationSpeed, snowflakeCount, images, style, }?: SnowfallProps) => JSX.Element; +export declare const Snowfall: ({ color, changeFrequency, radius, speed, wind, rotationSpeed, opacity, snowflakeCount, images, style, }?: SnowfallProps) => JSX.Element; export default Snowfall; diff --git a/packages/react-snowfall/lib/Snowfall.js b/packages/react-snowfall/lib/Snowfall.js index 53135e2..dcfd9c5 100644 --- a/packages/react-snowfall/lib/Snowfall.js +++ b/packages/react-snowfall/lib/Snowfall.js @@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react'; import { SnowfallCanvas } from './SnowfallCanvas.js'; import { defaultConfig } from './Snowflake.js'; import { useComponentSize, useDeepMemo, useSnowfallStyle } from './hooks.js'; -export const Snowfall = ({ color = defaultConfig.color, changeFrequency = defaultConfig.changeFrequency, radius = defaultConfig.radius, speed = defaultConfig.speed, wind = defaultConfig.wind, rotationSpeed = defaultConfig.rotationSpeed, snowflakeCount = 150, images, style, } = {}) => { +export const Snowfall = ({ color = defaultConfig.color, changeFrequency = defaultConfig.changeFrequency, radius = defaultConfig.radius, speed = defaultConfig.speed, wind = defaultConfig.wind, rotationSpeed = defaultConfig.rotationSpeed, opacity = defaultConfig.opacity, snowflakeCount = 150, images, style, } = {}) => { const mergedStyle = useSnowfallStyle(style); const canvasRef = useRef(null); const canvasSize = useComponentSize(canvasRef); @@ -15,6 +15,7 @@ export const Snowfall = ({ color = defaultConfig.color, changeFrequency = defaul rotationSpeed, images, snowflakeCount, + opacity, }); // A reference to the config used for creating the initial instance const configRef = useRef(config); diff --git a/packages/react-snowfall/lib/Snowfall.js.map b/packages/react-snowfall/lib/Snowfall.js.map index 78ce89c..c5e33b3 100644 --- a/packages/react-snowfall/lib/Snowfall.js.map +++ b/packages/react-snowfall/lib/Snowfall.js.map @@ -1 +1 @@ -{"version":3,"file":"Snowfall.js","sourceRoot":"","sources":["../src/Snowfall.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAChD,OAAO,EAAE,cAAc,EAAwB,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAS5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EACvB,KAAK,GAAG,aAAa,CAAC,KAAK,EAC3B,eAAe,GAAG,aAAa,CAAC,eAAe,EAC/C,MAAM,GAAG,aAAa,CAAC,MAAM,EAC7B,KAAK,GAAG,aAAa,CAAC,KAAK,EAC3B,IAAI,GAAG,aAAa,CAAC,IAAI,EACzB,aAAa,GAAG,aAAa,CAAC,aAAa,EAC3C,cAAc,GAAG,GAAG,EACpB,MAAM,EACN,KAAK,MACY,EAAE,EAAe,EAAE;IACpC,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAE3C,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IACjD,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAA;IAE9C,MAAM,MAAM,GAAG,WAAW,CAAuB;QAC/C,KAAK;QACL,eAAe;QACf,MAAM;QACN,KAAK;QACL,IAAI;QACJ,aAAa;QACb,MAAM;QACN,cAAc;KACf,CAAC,CAAA;IAEF,mEAAmE;IACnE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAEhC,MAAM,iBAAiB,GAAG,MAAM,EAAkB,CAAA;IAElD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,iBAAiB,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACpD,iBAAiB,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;QACtF,CAAC;QAED,OAAO,GAAG,EAAE;;YACV,MAAA,iBAAiB,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAA;YAClC,iBAAiB,CAAC,OAAO,GAAG,SAAS,CAAA;QACvC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC9B,iBAAiB,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,OAAO,CACL,gCACE,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,UAAU,CAAC,MAAM,EACzB,KAAK,EAAE,UAAU,CAAC,KAAK,EACvB,KAAK,EAAE,WAAW,iBACN,gBAAgB,GAC5B,CACH,CAAA;AACH,CAAC,CAAA;AAED,eAAe,QAAQ,CAAA"} \ No newline at end of file +{"version":3,"file":"Snowfall.js","sourceRoot":"","sources":["../src/Snowfall.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAChD,OAAO,EAAE,cAAc,EAAwB,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAS5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EACvB,KAAK,GAAG,aAAa,CAAC,KAAK,EAC3B,eAAe,GAAG,aAAa,CAAC,eAAe,EAC/C,MAAM,GAAG,aAAa,CAAC,MAAM,EAC7B,KAAK,GAAG,aAAa,CAAC,KAAK,EAC3B,IAAI,GAAG,aAAa,CAAC,IAAI,EACzB,aAAa,GAAG,aAAa,CAAC,aAAa,EAC3C,OAAO,GAAG,aAAa,CAAC,OAAO,EAC/B,cAAc,GAAG,GAAG,EACpB,MAAM,EACN,KAAK,MACY,EAAE,EAAe,EAAE;IACpC,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAE3C,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IACjD,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAA;IAE9C,MAAM,MAAM,GAAG,WAAW,CAAuB;QAC/C,KAAK;QACL,eAAe;QACf,MAAM;QACN,KAAK;QACL,IAAI;QACJ,aAAa;QACb,MAAM;QACN,cAAc;QACd,OAAO;KACR,CAAC,CAAA;IAEF,mEAAmE;IACnE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAEhC,MAAM,iBAAiB,GAAG,MAAM,EAAkB,CAAA;IAElD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,iBAAiB,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACpD,iBAAiB,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;QACtF,CAAC;QAED,OAAO,GAAG,EAAE;;YACV,MAAA,iBAAiB,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAA;YAClC,iBAAiB,CAAC,OAAO,GAAG,SAAS,CAAA;QACvC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC9B,iBAAiB,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,OAAO,CACL,gCACE,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,UAAU,CAAC,MAAM,EACzB,KAAK,EAAE,UAAU,CAAC,KAAK,EACvB,KAAK,EAAE,WAAW,iBACN,gBAAgB,GAC5B,CACH,CAAA;AACH,CAAC,CAAA;AAED,eAAe,QAAQ,CAAA"} \ No newline at end of file diff --git a/packages/react-snowfall/lib/Snowflake.d.ts b/packages/react-snowfall/lib/Snowflake.d.ts index 08f3442..c9d41e8 100644 --- a/packages/react-snowfall/lib/Snowflake.d.ts +++ b/packages/react-snowfall/lib/Snowflake.d.ts @@ -54,6 +54,12 @@ export interface SnowflakeProps { * The default value is `[-1.0, 1.0]`. */ rotationSpeed: [number, number]; + /** + * The minimum and maximum opacity of the snowflake image. + * + * This value only applies to snowflakes that are using images. + */ + opacity: [number, number]; } export type SnowflakeConfig = Partial; export declare const defaultConfig: SnowflakeProps; diff --git a/packages/react-snowfall/lib/Snowflake.js b/packages/react-snowfall/lib/Snowflake.js index a5416ff..a675a2c 100644 --- a/packages/react-snowfall/lib/Snowflake.js +++ b/packages/react-snowfall/lib/Snowflake.js @@ -7,6 +7,7 @@ export const defaultConfig = { wind: [-0.5, 2.0], changeFrequency: 200, rotationSpeed: [-1.0, 1.0], + opacity: [1, 1], }; /** * An individual snowflake that will update it's location every call to `update` @@ -32,7 +33,7 @@ class Snowflake { // Set custom config this.updateConfig(config); // Setting initial parameters - const { radius, wind, speed, rotationSpeed } = this.config; + const { radius, wind, speed, rotationSpeed, opacity } = this.config; this.params = { x: random(0, canvas.offsetWidth), y: random(-canvas.offsetHeight, 0), @@ -44,6 +45,7 @@ class Snowflake { nextSpeed: random(...speed), nextWind: random(...wind), nextRotationSpeed: random(...rotationSpeed), + opacity: random(...opacity), }; this.framesSinceLastUpdate = 0; } @@ -146,6 +148,11 @@ class Snowflake { const radian = (rotation * Math.PI) / 180; const cos = Math.cos(radian); const sin = Math.sin(radian); + // Save the current state to avoid affecting other drawings if changing the opacity + if (this.params.opacity !== 1) { + ctx.save(); + ctx.globalAlpha = this.params.opacity; // Set the global alpha to the snowflake's opacity + } // Translate to the location that we will be drawing the snowflake, including any rotation that needs to be applied // The arguments for setTransform are: a, b, c, d, e, f // a (scaleX), b (skewY), c (skewX), d (scaleY), e (translateX), f (translateY) @@ -153,6 +160,10 @@ class Snowflake { // Draw the image with the center of the image at the center of the current location const image = this.getImageOffscreenCanvas(this.image, radius); ctx.drawImage(image, -(radius / 2), -(radius / 2), radius, radius); + // Reset the transform to avoid affecting other drawings if we were changing the opacity + if (this.params.opacity !== 1) { + ctx.restore(); + } } } Snowflake.offscreenCanvases = new WeakMap(); diff --git a/packages/react-snowfall/lib/Snowflake.js.map b/packages/react-snowfall/lib/Snowflake.js.map index 56f304c..f07d942 100644 --- a/packages/react-snowfall/lib/Snowflake.js.map +++ b/packages/react-snowfall/lib/Snowflake.js.map @@ -1 +1 @@ -{"version":3,"file":"Snowflake.js","sourceRoot":"","sources":["../src/Snowflake.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AA8D/D,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;IACjB,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC;IACjB,eAAe,EAAE,GAAG;IACpB,aAAa,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC;CAC3B,CAAA;AAeD;;;GAGG;AACH,MAAM,SAAS;IAGb;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAgC,EAAE,MAAc,EAAE,MAAuB;QAC/F,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAA;QAEtB,MAAM,UAAU,GAAgB,EAAE,CAAA;QAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;QAChD,CAAC;QAED,OAAO,UAAU,CAAA;IACnB,CAAC;IAOD,YAAmB,MAAyB,EAAE,SAA0B,EAAE;QACxE,oBAAoB;QACpB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QAEzB,6BAA6B;QAC7B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE1D,IAAI,CAAC,MAAM,GAAG;YACZ,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;YAChC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YAClC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC;YACxB,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;YACzB,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;YACvB,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;YACrB,aAAa,EAAE,MAAM,CAAC,GAAG,aAAa,CAAC;YACvC,SAAS,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;YAC3B,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;YACzB,iBAAiB,EAAE,MAAM,CAAC,GAAG,aAAa,CAAC;SAC5C,CAAA;QAED,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAA;IAChC,CAAC;IAEO,WAAW;QACjB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,SAAS,CAAA;QACxB,CAAC;IACH,CAAC;IAEM,YAAY,CAAC,MAAuB;QACzC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAA;QAClC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,MAAM,EAAE,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,GAAG,CAAC,CAAA;QAEpG,qFAAqF;QACrF,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,MAAM,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACpD,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,MAAM,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,WAAW,EAAE,CAAA;QACpB,CAAC;IACH,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACpD,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAClD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QACtE,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,WAAmB,EAAE,YAAoB,EAAE,YAAY,GAAG,CAAC;QACvE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAElH,mEAAmE;QACnE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;QACtE,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM;YAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAA;QACjE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,YAAY,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;QACxE,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,YAAY,GAAG,MAAM;YAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAA;QAElE,iBAAiB;QACjB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAC,GAAG,GAAG,CAAA;QACzD,CAAC;QAED,iEAAiE;QACjE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;QAChD,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAA;QAExE,IAAI,IAAI,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC/D,IAAI,CAAC,kBAAkB,EAAE,CAAA;YACzB,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAEO,uBAAuB,CAAC,KAAwB,EAAE,IAAY;;QACpE,IAAI,KAAK,YAAY,gBAAgB,IAAI,KAAK,CAAC,OAAO;YAAE,OAAO,KAAK,CAAA;QACpE,IAAI,KAAK,GAAG,SAAS,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAElD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,CAAA;YACV,SAAS,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC/C,CAAC;QAED,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC/C,MAAM,CAAC,KAAK,GAAG,IAAI,CAAA;YACnB,MAAM,CAAC,MAAM,GAAG,IAAI,CAAA;YACpB,MAAA,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,0CAAE,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YAC3D,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAA;QACtB,CAAC;QAED,OAAO,MAAA,KAAK,CAAC,IAAI,CAAC,mCAAI,KAAK,CAAA;IAC7B,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACI,UAAU,CAAC,GAA6B;QAC7C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACxC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;IACrE,CAAC;IAED;;;;;;OAMG;IACI,SAAS,CAAC,GAA6B;QAC5C,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE9C,MAAM,MAAM,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAE5B,mHAAmH;QACnH,uDAAuD;QACvD,+EAA+E;QAC/E,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAE3C,oFAAoF;QACpF,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAM,EAAE,MAAM,CAAC,CAAA;QAC/D,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACpE,CAAC;;AAvKc,2BAAiB,GAAG,IAAI,OAAO,EAAwD,CAAA;AA0KxG,eAAe,SAAS,CAAA"} \ No newline at end of file +{"version":3,"file":"Snowflake.js","sourceRoot":"","sources":["../src/Snowflake.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/react-snowfall/src/Snowfall.tsx b/packages/react-snowfall/src/Snowfall.tsx index 3105f67..3217448 100644 --- a/packages/react-snowfall/src/Snowfall.tsx +++ b/packages/react-snowfall/src/Snowfall.tsx @@ -17,6 +17,7 @@ export const Snowfall = ({ speed = defaultConfig.speed, wind = defaultConfig.wind, rotationSpeed = defaultConfig.rotationSpeed, + opacity = defaultConfig.opacity, snowflakeCount = 150, images, style, @@ -35,6 +36,7 @@ export const Snowfall = ({ rotationSpeed, images, snowflakeCount, + opacity, }) // 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 1511228..4267939 100644 --- a/packages/react-snowfall/src/Snowflake.ts +++ b/packages/react-snowfall/src/Snowflake.ts @@ -57,6 +57,16 @@ export interface SnowflakeProps { * The default value is `[-1.0, 1.0]`. */ rotationSpeed: [number, number] + /** + * The minimum and maximum opacity of the snowflake image. + * + * This value only applies to snowflakes that are using images. + * + * The values will be randomly selected within this range. + * + * The default value is `[1, 1]`. + */ + opacity: [number, number] } export type SnowflakeConfig = Partial @@ -68,6 +78,7 @@ export const defaultConfig: SnowflakeProps = { wind: [-0.5, 2.0], changeFrequency: 200, rotationSpeed: [-1.0, 1.0], + opacity: [1, 1], } interface SnowflakeParams { @@ -81,6 +92,7 @@ interface SnowflakeParams { nextSpeed: number nextWind: number nextRotationSpeed: number + opacity: number } /** @@ -118,7 +130,7 @@ class Snowflake { this.updateConfig(config) // Setting initial parameters - const { radius, wind, speed, rotationSpeed } = this.config + const { radius, wind, speed, rotationSpeed, opacity } = this.config this.params = { x: random(0, canvas.offsetWidth), @@ -131,6 +143,7 @@ class Snowflake { nextSpeed: random(...speed), nextWind: random(...wind), nextRotationSpeed: random(...rotationSpeed), + opacity: random(...opacity), } this.framesSinceLastUpdate = 0 @@ -247,6 +260,12 @@ class Snowflake { const cos = Math.cos(radian) const sin = Math.sin(radian) + // Save the current state to avoid affecting other drawings if changing the opacity + if (this.params.opacity !== 1) { + ctx.save() + ctx.globalAlpha = this.params.opacity // Set the global alpha to the snowflake's opacity + } + // Translate to the location that we will be drawing the snowflake, including any rotation that needs to be applied // The arguments for setTransform are: a, b, c, d, e, f // a (scaleX), b (skewY), c (skewX), d (scaleY), e (translateX), f (translateY) @@ -255,6 +274,11 @@ class Snowflake { // Draw the image with the center of the image at the center of the current location const image = this.getImageOffscreenCanvas(this.image!, radius) ctx.drawImage(image, -(radius / 2), -(radius / 2), radius, radius) + + // Reset the transform to avoid affecting other drawings if we were changing the opacity + if (this.params.opacity !== 1) { + ctx.restore() + } } }