react-animated-waves 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 - PRESENT Rohit Agrawal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # React Animated Waves
2
+
3
+ <div style="display: flex; flex-direction: row">
4
+ <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/agrawal-rohit/react-animated-waves/Publish.yml">
5
+ <img alt="Codacy coverage" src="https://img.shields.io/codacy/coverage/09220ab3d193472ba76d1ad50f11ee51">
6
+ <img alt="npm" src="https://img.shields.io/npm/dw/react-animated-waves">
7
+ <img alt="Licence" src="https://img.shields.io/github/license/agrawal-rohit/react-animated-waves">
8
+ </div>
9
+
10
+ <br />
11
+
12
+ **React Animated Waves** is a React component that generates beautiful animated waves for audio visualizations or UI loading states.
13
+
14
+ ## Table of Contents
15
+
16
+ 1. [Installation](#installation)
17
+ 2. [Usage](#usage)
18
+ 3. [Props](#props)
19
+ 4. [Contributing](#contributing)
20
+ 5. [License](#license)
21
+
22
+ ## Installation
23
+
24
+ **React Animated Waves** can be installed using either npm or yarn:
25
+
26
+ **Using npm:**
27
+
28
+ ```bash
29
+ npm install --save react-animated-waves
30
+ ```
31
+
32
+ **Using yarn:**
33
+
34
+ ```bash
35
+ yarn add react-animated-waves
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ To use **React Animated Waves** in your project, import the `Waves` component from the library and use it in your React app. Check out an interactive demo [here](https://codesandbox.io/p/sandbox/react-animated-waves-example-skhlh4).
41
+
42
+ ```jsx
43
+ import Waves from "react-animated-waves";
44
+
45
+ <Waves amplitude={20} colors={["#FF6AC6", "#436EDB", "#FF6AC6"]} />;
46
+ ```
47
+
48
+ ## Props
49
+
50
+ The `Waves` component accepts the following props:
51
+
52
+ | Prop | Description | Default |
53
+ | ----------- | --------------------------------------------------------------------------- | ------------- |
54
+ | `amplitude` | Defines the height of the waveform. Higher values result in taller waves. | `20` |
55
+ | `colors` | An array of colors used to create a linear gradient effect on the waveform. | `['#436EDB']` |
56
+
57
+ ## Contributing
58
+
59
+ All contributions from the community are welcome. Please read the [contributing guide](CONTRIBUTING.md) for more information.
60
+
61
+ ## License
62
+
63
+ [MIT License](LICENSE).
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ type WavesProps = React.DetailedHTMLProps<React.CanvasHTMLAttributes<HTMLCanvasElement>, HTMLCanvasElement> & {
3
+ /** The colors for the waveform */
4
+ colors?: string[];
5
+ /** The amplitude of the waveform */
6
+ amplitude?: number;
7
+ };
8
+ declare const _default: React.NamedExoticComponent<WavesProps>;
9
+ export default _default;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAuBpE,KAAK,UAAU,GAAG,KAAK,CAAC,iBAAiB,CACvC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC7C,iBAAiB,CAClB,GAAG;IACF,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;;AAiKF,wBAA2B"}
@@ -0,0 +1,2 @@
1
+ import e,{memo as t,useRef as r,useEffect as n,useCallback as a}from"react";var o=function(){return o=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},o.apply(this,arguments)};"function"==typeof SuppressedError&&SuppressedError;var i=function(e,t){void 0===t&&(t=1),"#"===e[0]&&(e=e.slice(1));var r=parseInt(e,16),n=r>>8&255,a=255&r;return"rgba(".concat(r>>16&255,", ").concat(n,", ").concat(a,", ").concat(t,")")},c=t((function(t){var c=t.amplitude,u=void 0===c?20:c,l=t.colors,p=void 0===l?["#436EDB"]:l,h=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(n=Object.getOwnPropertySymbols(e);a<n.length;a++)t.indexOf(n[a])<0&&Object.prototype.propertyIsEnumerable.call(e,n[a])&&(r[n[a]]=e[n[a]])}return r}(t,["amplitude","colors"]),f=r(u),d=r(null),s=r(u);n((function(){s.current=u}),[u]);var v=a((function(e,t,r,n,a){void 0===a&&(a=0),e.strokeStyle=n,e.beginPath();for(var o=0;o<e.canvas.width;o++){var i=Math.sin(Math.PI*(o/e.canvas.width)),c=Math.pow(i,6),u=t*Math.sin(r*o+a)*c;e.lineTo(o,e.canvas.height/2+u)}e.stroke()}),[]);return n((function(){var e,t=d.current,r=t.getContext("2d"),n=t.parentElement;n&&(t.width=n.clientWidth);var a=function(){var n,o,c=.0015*Date.now();f.current=(n=f.current,o=s.current,n+.1*(o-n));var u=f.current*(1+.05*Math.sin(c));r.clearRect(0,0,t.width,t.height);for(var l=function(e){var n=r.createLinearGradient(0,0,t.width,t.height),a=p.length>1?1/(p.length-1):0;p.forEach((function(t,r){n.addColorStop(a*r,i(t,e.alpha))})),v(r,e.amplitude,e.frequency,n,Date.now()*e.speed);for(var o=function(n){var a=e.amplitude-.1*n,o=e.frequency+25e-5*n,c=.6*e.alpha-.01*n,u=r.createLinearGradient(0,0,t.width,t.height),l=p.length>1?1/(p.length-1):0;p.forEach((function(e,t){u.addColorStop(l*t,i(e,c))})),v(r,a,o,u,Date.now()*e.speed+.015*n)},c=0;c<30;c++)o(c)},h=0,d=[{amplitude:u,frequency:.02,alpha:.6,speed:.001},{amplitude:.6*u,frequency:.03,alpha:.4,speed:.004},{amplitude:.3*u,frequency:.04,alpha:.2,speed:.007}];h<d.length;h++){l(d[h])}e=requestAnimationFrame(a)};return a(),function(){cancelAnimationFrame(e)}}),[p,v]),e.createElement("canvas",o({ref:d,width:"100%",height:"auto"},h))}));export{c as default};
2
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../src/index.tsx"],"sourcesContent":["import React, { memo, useCallback, useEffect, useRef } from \"react\";\n\n// Linear interpolation function\n// This function is used to smoothly transition between two values\nconst lerp = (a: number, b: number, t: number): number => {\n return a + t * (b - a);\n};\n\n// Function to convert a hexadecimal color to RGBA\nconst hexToRgba = (hex: string, alpha: number = 1): string => {\n if (hex[0] === \"#\") {\n hex = hex.slice(1);\n }\n\n const bigint = parseInt(hex, 16);\n const r = (bigint >> 16) & 255;\n const g = (bigint >> 8) & 255;\n const b = bigint & 255;\n\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n};\n\n// Define the properties for the AnimatedWaveform component\ntype WavesProps = React.DetailedHTMLProps<\n React.CanvasHTMLAttributes<HTMLCanvasElement>,\n HTMLCanvasElement\n> & {\n /** The colors for the waveform */\n colors?: string[];\n /** The amplitude of the waveform */\n amplitude?: number;\n};\n\nconst Waves: React.FC<WavesProps> = ({\n amplitude = 20,\n colors = [\"#436EDB\"],\n ...props\n}) => {\n const amplitudeRef = useRef(amplitude);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const targetAmplitudeRef = useRef<number>(amplitude);\n\n // Update the target amplitude whenever the amplitude prop changes\n useEffect(() => {\n targetAmplitudeRef.current = amplitude;\n }, [amplitude]);\n\n // Function to draw the waveform on the canvas\n const drawWaveform = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n amplitude: number,\n frequency: number,\n color: string | CanvasGradient,\n phase = 0\n ) => {\n ctx.strokeStyle = color;\n ctx.beginPath();\n\n // Draw the waveform\n for (let i = 0; i < ctx.canvas.width; i++) {\n // Compute the pinching effect\n const sineWave = Math.sin(Math.PI * (i / ctx.canvas.width));\n const pinch = Math.pow(sineWave, 6);\n\n // Calculate the y position with sine function, pinch effect, and time-based phase shift\n const y = amplitude * Math.sin(frequency * i + phase) * pinch;\n\n ctx.lineTo(i, ctx.canvas.height / 2 + y);\n }\n\n ctx.stroke();\n },\n []\n );\n\n // Animate the waveform\n useEffect(() => {\n let animationFrameId: number;\n const canvas = canvasRef.current as HTMLCanvasElement;\n const ctx = canvas.getContext(\"2d\")!;\n const parent = canvas.parentElement;\n if (parent) canvas.width = parent.clientWidth;\n\n const animate = () => {\n const time = Date.now() * 0.0015; // Convert milliseconds to seconds and increase speed\n\n amplitudeRef.current = lerp(\n amplitudeRef.current,\n targetAmplitudeRef.current,\n 0.1\n );\n\n // Create an oscillating effect with amplitude\n const oscillatingAmplitude =\n amplitudeRef.current * (1 + Math.sin(time) * 0.05);\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Define primary waveforms with their respective amplitudes, frequencies, and colors\n const primaryWaveforms = [\n {\n amplitude: oscillatingAmplitude,\n frequency: 0.02,\n alpha: 0.6,\n speed: 0.001,\n },\n {\n amplitude: oscillatingAmplitude * 0.6,\n frequency: 0.03,\n alpha: 0.4,\n speed: 0.004,\n },\n {\n amplitude: oscillatingAmplitude * 0.3,\n frequency: 0.04,\n alpha: 0.2,\n speed: 0.007,\n },\n ];\n\n // For each primary waveform, draw the waveform and its surrounding mesh\n for (const primary of primaryWaveforms) {\n const gradient = ctx.createLinearGradient(\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n const stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;\n colors.forEach((color, index) => {\n gradient.addColorStop(\n stopIncrement * index,\n hexToRgba(color, primary.alpha)\n );\n });\n\n drawWaveform(\n ctx,\n primary.amplitude,\n primary.frequency,\n gradient,\n Date.now() * primary.speed\n );\n\n // Draw secondary waveforms around the primary waveform\n for (let i = 0; i < 30; i++) {\n const amp = primary.amplitude - i * 0.1;\n const freq = primary.frequency + i * 0.00025;\n const alpha = primary.alpha * 0.6 - i * 0.01;\n const gradient = ctx.createLinearGradient(\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n const stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;\n colors.forEach((color, index) => {\n gradient.addColorStop(\n stopIncrement * index,\n hexToRgba(color, alpha)\n );\n });\n\n drawWaveform(\n ctx,\n amp,\n freq,\n gradient,\n Date.now() * primary.speed + i * 0.015\n );\n }\n }\n\n animationFrameId = requestAnimationFrame(animate);\n };\n\n animate();\n\n // Clean up the animation frame when the component unmounts\n return () => {\n cancelAnimationFrame(animationFrameId);\n };\n }, [colors, drawWaveform]);\n\n // Render the canvas\n return (\n <canvas ref={canvasRef} width=\"100%\" height=\"auto\" {...props}></canvas>\n );\n};\n\n// Export the memoized version of the component to avoid unnecessary re-renders\nexport default memo(Waves);\n"],"names":["hexToRgba","hex","alpha","slice","bigint","parseInt","g","b","concat","index","memo","_a","_b","amplitude","_c","colors","props","__rest","amplitudeRef","useRef","canvasRef","targetAmplitudeRef","useEffect","current","drawWaveform","useCallback","ctx","frequency","color","phase","strokeStyle","beginPath","i","canvas","width","sineWave","Math","sin","PI","pinch","pow","y","lineTo","height","stroke","animationFrameId","getContext","parent","parentElement","clientWidth","animate","a","time","Date","now","oscillatingAmplitude","clearRect","primary","gradient","createLinearGradient","stopIncrement","length","forEach","addColorStop","speed","amp","freq","gradient_1","stopIncrement_1","primaryWaveforms_1","_i","requestAnimationFrame","cancelAnimationFrame","React","createElement","__assign","ref"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,170 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ /******************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+ /* global Reflect, Promise, SuppressedError, Symbol */
20
+
21
+
22
+ var __assign = function() {
23
+ __assign = Object.assign || function __assign(t) {
24
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
25
+ s = arguments[i];
26
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
27
+ }
28
+ return t;
29
+ };
30
+ return __assign.apply(this, arguments);
31
+ };
32
+
33
+ function __rest(s, e) {
34
+ var t = {};
35
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
36
+ t[p] = s[p];
37
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
38
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
39
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
40
+ t[p[i]] = s[p[i]];
41
+ }
42
+ return t;
43
+ }
44
+
45
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
46
+ var e = new Error(message);
47
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
48
+ };
49
+
50
+ // Linear interpolation function
51
+ // This function is used to smoothly transition between two values
52
+ var lerp = function (a, b, t) {
53
+ return a + t * (b - a);
54
+ };
55
+ // Function to convert a hexadecimal color to RGBA
56
+ var hexToRgba = function (hex, alpha) {
57
+ if (alpha === void 0) { alpha = 1; }
58
+ if (hex[0] === "#") {
59
+ hex = hex.slice(1);
60
+ }
61
+ var bigint = parseInt(hex, 16);
62
+ var r = (bigint >> 16) & 255;
63
+ var g = (bigint >> 8) & 255;
64
+ var b = bigint & 255;
65
+ return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(alpha, ")");
66
+ };
67
+ var Waves = function (_a) {
68
+ var _b = _a.amplitude, amplitude = _b === void 0 ? 20 : _b, _c = _a.colors, colors = _c === void 0 ? ["#436EDB"] : _c, props = __rest(_a, ["amplitude", "colors"]);
69
+ var amplitudeRef = React.useRef(amplitude);
70
+ var canvasRef = React.useRef(null);
71
+ var targetAmplitudeRef = React.useRef(amplitude);
72
+ // Update the target amplitude whenever the amplitude prop changes
73
+ React.useEffect(function () {
74
+ targetAmplitudeRef.current = amplitude;
75
+ }, [amplitude]);
76
+ // Function to draw the waveform on the canvas
77
+ var drawWaveform = React.useCallback(function (ctx, amplitude, frequency, color, phase) {
78
+ if (phase === void 0) { phase = 0; }
79
+ ctx.strokeStyle = color;
80
+ ctx.beginPath();
81
+ // Draw the waveform
82
+ for (var i = 0; i < ctx.canvas.width; i++) {
83
+ // Compute the pinching effect
84
+ var sineWave = Math.sin(Math.PI * (i / ctx.canvas.width));
85
+ var pinch = Math.pow(sineWave, 6);
86
+ // Calculate the y position with sine function, pinch effect, and time-based phase shift
87
+ var y = amplitude * Math.sin(frequency * i + phase) * pinch;
88
+ ctx.lineTo(i, ctx.canvas.height / 2 + y);
89
+ }
90
+ ctx.stroke();
91
+ }, []);
92
+ // Animate the waveform
93
+ React.useEffect(function () {
94
+ var animationFrameId;
95
+ var canvas = canvasRef.current;
96
+ var ctx = canvas.getContext("2d");
97
+ var parent = canvas.parentElement;
98
+ if (parent)
99
+ canvas.width = parent.clientWidth;
100
+ var animate = function () {
101
+ var time = Date.now() * 0.0015; // Convert milliseconds to seconds and increase speed
102
+ amplitudeRef.current = lerp(amplitudeRef.current, targetAmplitudeRef.current, 0.1);
103
+ // Create an oscillating effect with amplitude
104
+ var oscillatingAmplitude = amplitudeRef.current * (1 + Math.sin(time) * 0.05);
105
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
106
+ // Define primary waveforms with their respective amplitudes, frequencies, and colors
107
+ var primaryWaveforms = [
108
+ {
109
+ amplitude: oscillatingAmplitude,
110
+ frequency: 0.02,
111
+ alpha: 0.6,
112
+ speed: 0.001,
113
+ },
114
+ {
115
+ amplitude: oscillatingAmplitude * 0.6,
116
+ frequency: 0.03,
117
+ alpha: 0.4,
118
+ speed: 0.004,
119
+ },
120
+ {
121
+ amplitude: oscillatingAmplitude * 0.3,
122
+ frequency: 0.04,
123
+ alpha: 0.2,
124
+ speed: 0.007,
125
+ },
126
+ ];
127
+ var _loop_1 = function (primary) {
128
+ var gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
129
+ var stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;
130
+ colors.forEach(function (color, index) {
131
+ gradient.addColorStop(stopIncrement * index, hexToRgba(color, primary.alpha));
132
+ });
133
+ drawWaveform(ctx, primary.amplitude, primary.frequency, gradient, Date.now() * primary.speed);
134
+ var _loop_2 = function (i) {
135
+ var amp = primary.amplitude - i * 0.1;
136
+ var freq = primary.frequency + i * 0.00025;
137
+ var alpha = primary.alpha * 0.6 - i * 0.01;
138
+ var gradient_1 = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
139
+ var stopIncrement_1 = colors.length > 1 ? 1 / (colors.length - 1) : 0;
140
+ colors.forEach(function (color, index) {
141
+ gradient_1.addColorStop(stopIncrement_1 * index, hexToRgba(color, alpha));
142
+ });
143
+ drawWaveform(ctx, amp, freq, gradient_1, Date.now() * primary.speed + i * 0.015);
144
+ };
145
+ // Draw secondary waveforms around the primary waveform
146
+ for (var i = 0; i < 30; i++) {
147
+ _loop_2(i);
148
+ }
149
+ };
150
+ // For each primary waveform, draw the waveform and its surrounding mesh
151
+ for (var _i = 0, primaryWaveforms_1 = primaryWaveforms; _i < primaryWaveforms_1.length; _i++) {
152
+ var primary = primaryWaveforms_1[_i];
153
+ _loop_1(primary);
154
+ }
155
+ animationFrameId = requestAnimationFrame(animate);
156
+ };
157
+ animate();
158
+ // Clean up the animation frame when the component unmounts
159
+ return function () {
160
+ cancelAnimationFrame(animationFrameId);
161
+ };
162
+ }, [colors, drawWaveform]);
163
+ // Render the canvas
164
+ return (React.createElement("canvas", __assign({ ref: canvasRef, width: "100%", height: "auto" }, props)));
165
+ };
166
+ // Export the memoized version of the component to avoid unnecessary re-renders
167
+ var index = React.memo(Waves);
168
+
169
+ module.exports = index;
170
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["import React, { memo, useCallback, useEffect, useRef } from \"react\";\n\n// Linear interpolation function\n// This function is used to smoothly transition between two values\nconst lerp = (a: number, b: number, t: number): number => {\n return a + t * (b - a);\n};\n\n// Function to convert a hexadecimal color to RGBA\nconst hexToRgba = (hex: string, alpha: number = 1): string => {\n if (hex[0] === \"#\") {\n hex = hex.slice(1);\n }\n\n const bigint = parseInt(hex, 16);\n const r = (bigint >> 16) & 255;\n const g = (bigint >> 8) & 255;\n const b = bigint & 255;\n\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n};\n\n// Define the properties for the AnimatedWaveform component\ntype WavesProps = React.DetailedHTMLProps<\n React.CanvasHTMLAttributes<HTMLCanvasElement>,\n HTMLCanvasElement\n> & {\n /** The colors for the waveform */\n colors?: string[];\n /** The amplitude of the waveform */\n amplitude?: number;\n};\n\nconst Waves: React.FC<WavesProps> = ({\n amplitude = 20,\n colors = [\"#436EDB\"],\n ...props\n}) => {\n const amplitudeRef = useRef(amplitude);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const targetAmplitudeRef = useRef<number>(amplitude);\n\n // Update the target amplitude whenever the amplitude prop changes\n useEffect(() => {\n targetAmplitudeRef.current = amplitude;\n }, [amplitude]);\n\n // Function to draw the waveform on the canvas\n const drawWaveform = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n amplitude: number,\n frequency: number,\n color: string | CanvasGradient,\n phase = 0\n ) => {\n ctx.strokeStyle = color;\n ctx.beginPath();\n\n // Draw the waveform\n for (let i = 0; i < ctx.canvas.width; i++) {\n // Compute the pinching effect\n const sineWave = Math.sin(Math.PI * (i / ctx.canvas.width));\n const pinch = Math.pow(sineWave, 6);\n\n // Calculate the y position with sine function, pinch effect, and time-based phase shift\n const y = amplitude * Math.sin(frequency * i + phase) * pinch;\n\n ctx.lineTo(i, ctx.canvas.height / 2 + y);\n }\n\n ctx.stroke();\n },\n []\n );\n\n // Animate the waveform\n useEffect(() => {\n let animationFrameId: number;\n const canvas = canvasRef.current as HTMLCanvasElement;\n const ctx = canvas.getContext(\"2d\")!;\n const parent = canvas.parentElement;\n if (parent) canvas.width = parent.clientWidth;\n\n const animate = () => {\n const time = Date.now() * 0.0015; // Convert milliseconds to seconds and increase speed\n\n amplitudeRef.current = lerp(\n amplitudeRef.current,\n targetAmplitudeRef.current,\n 0.1\n );\n\n // Create an oscillating effect with amplitude\n const oscillatingAmplitude =\n amplitudeRef.current * (1 + Math.sin(time) * 0.05);\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Define primary waveforms with their respective amplitudes, frequencies, and colors\n const primaryWaveforms = [\n {\n amplitude: oscillatingAmplitude,\n frequency: 0.02,\n alpha: 0.6,\n speed: 0.001,\n },\n {\n amplitude: oscillatingAmplitude * 0.6,\n frequency: 0.03,\n alpha: 0.4,\n speed: 0.004,\n },\n {\n amplitude: oscillatingAmplitude * 0.3,\n frequency: 0.04,\n alpha: 0.2,\n speed: 0.007,\n },\n ];\n\n // For each primary waveform, draw the waveform and its surrounding mesh\n for (const primary of primaryWaveforms) {\n const gradient = ctx.createLinearGradient(\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n const stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;\n colors.forEach((color, index) => {\n gradient.addColorStop(\n stopIncrement * index,\n hexToRgba(color, primary.alpha)\n );\n });\n\n drawWaveform(\n ctx,\n primary.amplitude,\n primary.frequency,\n gradient,\n Date.now() * primary.speed\n );\n\n // Draw secondary waveforms around the primary waveform\n for (let i = 0; i < 30; i++) {\n const amp = primary.amplitude - i * 0.1;\n const freq = primary.frequency + i * 0.00025;\n const alpha = primary.alpha * 0.6 - i * 0.01;\n const gradient = ctx.createLinearGradient(\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n const stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;\n colors.forEach((color, index) => {\n gradient.addColorStop(\n stopIncrement * index,\n hexToRgba(color, alpha)\n );\n });\n\n drawWaveform(\n ctx,\n amp,\n freq,\n gradient,\n Date.now() * primary.speed + i * 0.015\n );\n }\n }\n\n animationFrameId = requestAnimationFrame(animate);\n };\n\n animate();\n\n // Clean up the animation frame when the component unmounts\n return () => {\n cancelAnimationFrame(animationFrameId);\n };\n }, [colors, drawWaveform]);\n\n // Render the canvas\n return (\n <canvas ref={canvasRef} width=\"100%\" height=\"auto\" {...props}></canvas>\n );\n};\n\n// Export the memoized version of the component to avoid unnecessary re-renders\nexport default memo(Waves);\n"],"names":["useRef","useEffect","useCallback","memo"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("react"),t=function(){return t=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},t.apply(this,arguments)};"function"==typeof SuppressedError&&SuppressedError;var r=function(e,t){void 0===t&&(t=1),"#"===e[0]&&(e=e.slice(1));var r=parseInt(e,16),n=r>>8&255,a=255&r;return"rgba(".concat(r>>16&255,", ").concat(n,", ").concat(a,", ").concat(t,")")},n=e.memo((function(n){var a=n.amplitude,o=void 0===a?20:a,c=n.colors,i=void 0===c?["#436EDB"]:c,u=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(n=Object.getOwnPropertySymbols(e);a<n.length;a++)t.indexOf(n[a])<0&&Object.prototype.propertyIsEnumerable.call(e,n[a])&&(r[n[a]]=e[n[a]])}return r}(n,["amplitude","colors"]),l=e.useRef(o),f=e.useRef(null),p=e.useRef(o);e.useEffect((function(){p.current=o}),[o]);var h=e.useCallback((function(e,t,r,n,a){void 0===a&&(a=0),e.strokeStyle=n,e.beginPath();for(var o=0;o<e.canvas.width;o++){var c=Math.sin(Math.PI*(o/e.canvas.width)),i=Math.pow(c,6),u=t*Math.sin(r*o+a)*i;e.lineTo(o,e.canvas.height/2+u)}e.stroke()}),[]);return e.useEffect((function(){var e,t=f.current,n=t.getContext("2d"),a=t.parentElement;a&&(t.width=a.clientWidth);var o=function(){var a,c,u=.0015*Date.now();l.current=(a=l.current,c=p.current,a+.1*(c-a));var f=l.current*(1+.05*Math.sin(u));n.clearRect(0,0,t.width,t.height);for(var s=function(e){var a=n.createLinearGradient(0,0,t.width,t.height),o=i.length>1?1/(i.length-1):0;i.forEach((function(t,n){a.addColorStop(o*n,r(t,e.alpha))})),h(n,e.amplitude,e.frequency,a,Date.now()*e.speed);for(var c=function(a){var o=e.amplitude-.1*a,c=e.frequency+25e-5*a,u=.6*e.alpha-.01*a,l=n.createLinearGradient(0,0,t.width,t.height),f=i.length>1?1/(i.length-1):0;i.forEach((function(e,t){l.addColorStop(f*t,r(e,u))})),h(n,o,c,l,Date.now()*e.speed+.015*a)},u=0;u<30;u++)c(u)},d=0,v=[{amplitude:f,frequency:.02,alpha:.6,speed:.001},{amplitude:.6*f,frequency:.03,alpha:.4,speed:.004},{amplitude:.3*f,frequency:.04,alpha:.2,speed:.007}];d<v.length;d++){s(v[d])}e=requestAnimationFrame(o)};return o(),function(){cancelAnimationFrame(e)}}),[i,h]),e.createElement("canvas",t({ref:f,width:"100%",height:"auto"},u))}));module.exports=n;
2
+ //# sourceMappingURL=index.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.min.js","sources":["../src/index.tsx"],"sourcesContent":["import React, { memo, useCallback, useEffect, useRef } from \"react\";\n\n// Linear interpolation function\n// This function is used to smoothly transition between two values\nconst lerp = (a: number, b: number, t: number): number => {\n return a + t * (b - a);\n};\n\n// Function to convert a hexadecimal color to RGBA\nconst hexToRgba = (hex: string, alpha: number = 1): string => {\n if (hex[0] === \"#\") {\n hex = hex.slice(1);\n }\n\n const bigint = parseInt(hex, 16);\n const r = (bigint >> 16) & 255;\n const g = (bigint >> 8) & 255;\n const b = bigint & 255;\n\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n};\n\n// Define the properties for the AnimatedWaveform component\ntype WavesProps = React.DetailedHTMLProps<\n React.CanvasHTMLAttributes<HTMLCanvasElement>,\n HTMLCanvasElement\n> & {\n /** The colors for the waveform */\n colors?: string[];\n /** The amplitude of the waveform */\n amplitude?: number;\n};\n\nconst Waves: React.FC<WavesProps> = ({\n amplitude = 20,\n colors = [\"#436EDB\"],\n ...props\n}) => {\n const amplitudeRef = useRef(amplitude);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const targetAmplitudeRef = useRef<number>(amplitude);\n\n // Update the target amplitude whenever the amplitude prop changes\n useEffect(() => {\n targetAmplitudeRef.current = amplitude;\n }, [amplitude]);\n\n // Function to draw the waveform on the canvas\n const drawWaveform = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n amplitude: number,\n frequency: number,\n color: string | CanvasGradient,\n phase = 0\n ) => {\n ctx.strokeStyle = color;\n ctx.beginPath();\n\n // Draw the waveform\n for (let i = 0; i < ctx.canvas.width; i++) {\n // Compute the pinching effect\n const sineWave = Math.sin(Math.PI * (i / ctx.canvas.width));\n const pinch = Math.pow(sineWave, 6);\n\n // Calculate the y position with sine function, pinch effect, and time-based phase shift\n const y = amplitude * Math.sin(frequency * i + phase) * pinch;\n\n ctx.lineTo(i, ctx.canvas.height / 2 + y);\n }\n\n ctx.stroke();\n },\n []\n );\n\n // Animate the waveform\n useEffect(() => {\n let animationFrameId: number;\n const canvas = canvasRef.current as HTMLCanvasElement;\n const ctx = canvas.getContext(\"2d\")!;\n const parent = canvas.parentElement;\n if (parent) canvas.width = parent.clientWidth;\n\n const animate = () => {\n const time = Date.now() * 0.0015; // Convert milliseconds to seconds and increase speed\n\n amplitudeRef.current = lerp(\n amplitudeRef.current,\n targetAmplitudeRef.current,\n 0.1\n );\n\n // Create an oscillating effect with amplitude\n const oscillatingAmplitude =\n amplitudeRef.current * (1 + Math.sin(time) * 0.05);\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Define primary waveforms with their respective amplitudes, frequencies, and colors\n const primaryWaveforms = [\n {\n amplitude: oscillatingAmplitude,\n frequency: 0.02,\n alpha: 0.6,\n speed: 0.001,\n },\n {\n amplitude: oscillatingAmplitude * 0.6,\n frequency: 0.03,\n alpha: 0.4,\n speed: 0.004,\n },\n {\n amplitude: oscillatingAmplitude * 0.3,\n frequency: 0.04,\n alpha: 0.2,\n speed: 0.007,\n },\n ];\n\n // For each primary waveform, draw the waveform and its surrounding mesh\n for (const primary of primaryWaveforms) {\n const gradient = ctx.createLinearGradient(\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n const stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;\n colors.forEach((color, index) => {\n gradient.addColorStop(\n stopIncrement * index,\n hexToRgba(color, primary.alpha)\n );\n });\n\n drawWaveform(\n ctx,\n primary.amplitude,\n primary.frequency,\n gradient,\n Date.now() * primary.speed\n );\n\n // Draw secondary waveforms around the primary waveform\n for (let i = 0; i < 30; i++) {\n const amp = primary.amplitude - i * 0.1;\n const freq = primary.frequency + i * 0.00025;\n const alpha = primary.alpha * 0.6 - i * 0.01;\n const gradient = ctx.createLinearGradient(\n 0,\n 0,\n canvas.width,\n canvas.height\n );\n const stopIncrement = colors.length > 1 ? 1 / (colors.length - 1) : 0;\n colors.forEach((color, index) => {\n gradient.addColorStop(\n stopIncrement * index,\n hexToRgba(color, alpha)\n );\n });\n\n drawWaveform(\n ctx,\n amp,\n freq,\n gradient,\n Date.now() * primary.speed + i * 0.015\n );\n }\n }\n\n animationFrameId = requestAnimationFrame(animate);\n };\n\n animate();\n\n // Clean up the animation frame when the component unmounts\n return () => {\n cancelAnimationFrame(animationFrameId);\n };\n }, [colors, drawWaveform]);\n\n // Render the canvas\n return (\n <canvas ref={canvasRef} width=\"100%\" height=\"auto\" {...props}></canvas>\n );\n};\n\n// Export the memoized version of the component to avoid unnecessary re-renders\nexport default memo(Waves);\n"],"names":["hexToRgba","hex","alpha","slice","bigint","parseInt","g","b","concat","memo","_a","_b","amplitude","_c","colors","props","__rest","amplitudeRef","useRef","canvasRef","targetAmplitudeRef","useEffect","current","drawWaveform","useCallback","ctx","frequency","color","phase","strokeStyle","beginPath","i","canvas","width","sineWave","Math","sin","PI","pinch","pow","y","lineTo","height","stroke","animationFrameId","getContext","parent","parentElement","clientWidth","animate","a","time","Date","now","oscillatingAmplitude","clearRect","primary","gradient","createLinearGradient","stopIncrement","length","forEach","index","addColorStop","speed","amp","freq","gradient_1","stopIncrement_1","primaryWaveforms_1","_i","requestAnimationFrame","cancelAnimationFrame","React","createElement","__assign","ref"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "react-animated-waves",
3
+ "version": "1.0.0",
4
+ "description": "A React component for creating beautiful audio visualizations or UI loading states using animated waves",
5
+ "main": "dist/index.min.js",
6
+ "module": "dist/index.es.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "author": "Rohit Agrawal <https://github.com/agrawal-rohit>",
12
+ "repository": "https://github.com/agrawal-rohit/react-animated-waves.git",
13
+ "homepage": "https://github.com/agrawal-rohit/react-animated-waves.git",
14
+ "license": "MIT",
15
+ "private": false,
16
+ "scripts": {
17
+ "cz": "git-cz",
18
+ "test": "jest --coverage",
19
+ "start": "rollup -c rollup.config.js -w",
20
+ "build": "tsc && rollup -c rollup.config.js",
21
+ "test:watch": "jest --coverage --watch",
22
+ "semantic-release": "semantic-release"
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18",
26
+ "react-dom": ">=18"
27
+ },
28
+ "devDependencies": {
29
+ "@rollup/plugin-commonjs": "^25.0.7",
30
+ "@rollup/plugin-json": "^6.1.0",
31
+ "@rollup/plugin-node-resolve": "^15.2.3",
32
+ "@rollup/plugin-typescript": "^11.1.6",
33
+ "@semantic-release/changelog": "^6.0.3",
34
+ "@semantic-release/git": "^10.0.1",
35
+ "@testing-library/jest-dom": "^6.2.0",
36
+ "@testing-library/react": "^14.1.2",
37
+ "@types/jest": "^29.5.11",
38
+ "@types/node": "^20.11.1",
39
+ "@types/react": "^18.2.48",
40
+ "@types/react-dom": "^18.2.18",
41
+ "@typescript-eslint/eslint-plugin": "^6.18.1",
42
+ "@typescript-eslint/parser": "^6.18.1",
43
+ "commitizen": "^4.3.0",
44
+ "cz-conventional-changelog": "^3.3.0",
45
+ "eslint": "^8.56.0",
46
+ "eslint-config-prettier": "^9.1.0",
47
+ "eslint-config-standard": "^17.1.0",
48
+ "eslint-plugin-import": "^2.29.1",
49
+ "eslint-plugin-n": "^16.6.2",
50
+ "eslint-plugin-prettier": "^5.1.3",
51
+ "eslint-plugin-promise": "^6.1.1",
52
+ "eslint-plugin-react": "^7.33.2",
53
+ "eslint-plugin-react-hooks": "^4.6.0",
54
+ "eslint-plugin-standard": "^5.0.0",
55
+ "husky": "^8.0.3",
56
+ "identity-obj-proxy": "^3.0.0",
57
+ "jest": "^29.7.0",
58
+ "jest-environment-jsdom": "^29.7.0",
59
+ "postcss": "^8.4.33",
60
+ "prettier": "^3.2.2",
61
+ "react": "^18.2.0",
62
+ "react-dom": "^18.2.0",
63
+ "rollup": "^4.9.5",
64
+ "rollup-plugin-peer-deps-external": "^2.2.4",
65
+ "rollup-plugin-postcss": "^4.0.2",
66
+ "rollup-plugin-sourcemaps": "^0.6.3",
67
+ "rollup-plugin-terser": "^7.0.2",
68
+ "rollup-plugin-typescript2": "^0.36.0",
69
+ "semantic-release": "^23.0.0",
70
+ "ts-jest": "^29.1.1",
71
+ "typescript": "^5.3.3"
72
+ },
73
+ "config": {
74
+ "commitizen": {
75
+ "path": "./node_modules/cz-conventional-changelog"
76
+ }
77
+ },
78
+ "eslintIgnore": [
79
+ "node_modules/",
80
+ "dist/"
81
+ ],
82
+ "husky": {
83
+ "hooks": {
84
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
85
+ }
86
+ },
87
+ "release": {
88
+ "branches": [
89
+ "main",
90
+ {
91
+ "name": "beta",
92
+ "prerelease": true
93
+ }
94
+ ],
95
+ "prepare": [
96
+ "@semantic-release/changelog",
97
+ "@semantic-release/npm",
98
+ {
99
+ "path": "@semantic-release/git",
100
+ "assets": [
101
+ "dist/**/*.{js,ts}",
102
+ "package.json",
103
+ "package-lock.json",
104
+ "yarn.lock",
105
+ "CHANGELOG.md"
106
+ ],
107
+ "message": "chore(release): ${nextRelease.version} [skip ci]"
108
+ }
109
+ ]
110
+ }
111
+ }