summaryrefslogtreecommitdiff
path: root/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/components')
-rw-r--r--app/components/WaveEffect.tsx71
1 files changed, 71 insertions, 0 deletions
diff --git a/app/components/WaveEffect.tsx b/app/components/WaveEffect.tsx
new file mode 100644
index 0000000..853e25e
--- /dev/null
+++ b/app/components/WaveEffect.tsx
@@ -0,0 +1,71 @@
+"use client"
+
+import type React from "react"
+import { useRef, useEffect } from "react"
+
+interface WaveEffectProps {
+ color: string
+ triggerWave: boolean
+ mousePosition: { x: number; y: number }
+}
+
+const WaveEffect: React.FC<WaveEffectProps> = ({ color, triggerWave, mousePosition }) => {
+ const canvasRef = useRef<HTMLCanvasElement>(null)
+
+ useEffect(() => {
+ const canvas = canvasRef.current
+ if (!canvas) return
+
+ const ctx = canvas.getContext("2d")
+ if (!ctx) return
+
+ canvas.width = window.innerWidth
+ canvas.height = window.innerHeight
+
+ let animationFrameId: number
+ const waves: { x: number; y: number; radius: number; opacity: number }[] = []
+
+ const createWave = (x: number, y: number) => {
+ waves.push({ x, y, radius: 0, opacity: 0.5 })
+ }
+
+ const drawWaves = () => {
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
+
+ waves.forEach((wave, index) => {
+ ctx.beginPath()
+ ctx.arc(wave.x, wave.y, wave.radius, 0, Math.PI * 2)
+ ctx.strokeStyle = `rgba(${color}, ${wave.opacity})`
+ ctx.lineWidth = 2
+ ctx.stroke()
+
+ // Slow down the expansion rate
+ wave.radius += 1
+
+ // Slow down the fade-out rate
+ wave.opacity -= 0.005
+
+ if (wave.opacity <= 0) {
+ waves.splice(index, 1)
+ }
+ })
+
+ animationFrameId = requestAnimationFrame(drawWaves)
+ }
+
+ if (triggerWave) {
+ createWave(mousePosition.x, mousePosition.y)
+ }
+
+ drawWaves()
+
+ return () => {
+ cancelAnimationFrame(animationFrameId)
+ }
+ }, [color, triggerWave, mousePosition])
+
+ return <canvas ref={canvasRef} className="absolute top-0 left-0 w-full h-full pointer-events-none" />
+}
+
+export default WaveEffect
+