https://github.com/ddoemonn/react-waves
🌊 Animated wave component with React
https://github.com/ddoemonn/react-waves
animation canvas react tailwindcss ui wave waves
Last synced: 2 months ago
JSON representation
🌊 Animated wave component with React
- Host: GitHub
- URL: https://github.com/ddoemonn/react-waves
- Owner: ddoemonn
- License: mit
- Created: 2024-08-08T00:28:11.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-08T00:47:39.000Z (almost 2 years ago)
- Last Synced: 2024-08-08T03:06:45.681Z (almost 2 years ago)
- Topics: animation, canvas, react, tailwindcss, ui, wave, waves
- Language: TypeScript
- Homepage:
- Size: 72.3 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# react-waves
The Waves component is a customizable, animated wave generator built with React. It allows you to create beautiful, overlapping wave animations with ease, perfect for adding dynamic backgrounds or decorative elements to your web applications.
https://github.com/user-attachments/assets/7f5f3f6e-70c4-4949-88d1-ea0ee9cdf05e
## Features
- Create multiple overlapping waves
- Customize colors, speeds, amplitudes, and heights for each wave
- Responsive design
- Smooth animations using HTML5 Canvas
- TypeScript support
## Component Code
Here's the full implementation of the Waves component:
```typescript
'use client';
import React, { useEffect, useRef } from 'react';
interface Wave {
color: string;
speed?: number;
amplitude?: number;
height: number;
}
interface WavesProps {
height: number;
width: number;
waves: Wave[];
baseSpeed?: number;
baseAmplitude?: number;
}
const Waves: React.FC = ({
height,
width,
waves,
baseSpeed = 0.5,
baseAmplitude = 20,
}) => {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let animationFrameId: number;
let startTime: number | null = null;
const setCanvasSize = () => {
if (canvas) {
canvas.width = width;
canvas.height = height;
}
};
const drawWaves = (timestamp: number) => {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, width, height);
waves.forEach((wave, index) => {
ctx.beginPath();
ctx.moveTo(0, height);
const waveSpeed = wave.speed || baseSpeed;
const waveAmplitude = wave.amplitude || baseAmplitude;
const waveHeight = wave.height;
for (let x = 0; x < width; x++) {
const frequency = 0.01 + index * 0.005;
const y = Math.sin(x * frequency + elapsed * waveSpeed * 0.002 + (index * Math.PI * 2) / waves.length) * waveAmplitude;
ctx.lineTo(x, waveHeight + y);
}
ctx.lineTo(width, height);
ctx.lineTo(0, height);
ctx.fillStyle = wave.color;
ctx.globalAlpha = 0.5; // Set transparency
ctx.fill();
ctx.globalAlpha = 1; // Reset transparency
});
animationFrameId = requestAnimationFrame(drawWaves);
};
setCanvasSize();
animationFrameId = requestAnimationFrame(drawWaves);
return () => {
cancelAnimationFrame(animationFrameId);
};
}, [height, width, waves, baseSpeed, baseAmplitude]);
return (
);
};
export default Waves;
```
Note the `'use client';` directive at the top of the file. This is necessary when using this component in a Next.js 13+ project with the App Router, as it marks this component as a Client Component.
## Usage
Here's a basic example of how to use the Waves component:
```jsx
import React from 'react';
import Waves from '@/components/Waves';
const WavesExample = () => {
const waves = [
{ color: '#3B82F6', height: 100, speed: 0.3 },
{ color: '#60A5FA', height: 150, amplitude: 15 },
{ color: '#93C5FD', height: 200, speed: 0.6 },
{ color: '#BFDBFE', height: 250, amplitude: 10 },
];
return (
);
};
export default WavesExample;
```
### Props
The `Waves` component accepts the following props:
- `height` (number): The height of the canvas in pixels.
- `width` (number): The width of the canvas in pixels.
- `waves` (array): An array of wave objects, each with the following properties:
- `color` (string): The color of the wave (e.g., '#3B82F6').
- `height` (number): The vertical position of the wave.
- `speed` (number, optional): The speed of the wave animation.
- `amplitude` (number, optional): The amplitude of the wave.
- `baseSpeed` (number, optional): The default speed for waves without a specified speed.
- `baseAmplitude` (number, optional): The default amplitude for waves without a specified amplitude.
### Advanced Usage
You can create more complex wave compositions by using multiple `Waves` components:
```jsx
import React from 'react';
import Waves from '@components/Waves';
const AdvancedWavesExample = () => {
const wavesSets = [
[
{ color: '#3B82F6', height: 100, speed: 0.3 },
{ color: '#60A5FA', height: 150, amplitude: 15 },
{ color: '#93C5FD', height: 200, speed: 0.6 },
{ color: '#BFDBFE', height: 250, amplitude: 10 },
],
[
{ color: '#10B981', height: 80, amplitude: 25 },
{ color: '#34D399', height: 120, speed: 0.8 },
{ color: '#6EE7B7', height: 160, amplitude: 10 },
{ color: '#A7F3D0', height: 200, speed: 0.4 },
],
[
{ color: '#8B5CF6', height: 70, speed: 0.5 },
{ color: '#A78BFA', height: 140, amplitude: 20 },
{ color: '#C4B5FD', height: 210, speed: 0.7 },
{ color: '#DDD6FE', height: 280, amplitude: 15 },
{ color: '#EDE9FE', height: 350, speed: 0.3 },
],
];
return (
{wavesSets.map((waves, index) => (
))}
);
};
export default AdvancedWavesExample;
```
This example creates three different wave sets, each with its own color scheme and properties.
## Customization
You can easily customize the appearance and behavior of the waves by adjusting the properties of each wave object. Experiment with different colors, speeds, amplitudes, and heights to create unique wave effects that match your design requirements.
## Browser Support
The Waves component should work in all modern browsers that support HTML5 Canvas. For older browsers, consider adding a fallback or polyfill for Canvas support.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License.