diff --git a/src/components/DataRoom/SeeMore/SlidingWave.tsx b/src/components/DataRoom/SeeMore/SlidingWave.tsx
index fce2de39b..fbf04f88c 100644
--- a/src/components/DataRoom/SeeMore/SlidingWave.tsx
+++ b/src/components/DataRoom/SeeMore/SlidingWave.tsx
@@ -30,13 +30,7 @@ export default function SlidingWave({
-
-
-
-
-
-
-
+
>
)
diff --git a/src/components/DataRoom/SeeMore/Wave.tsx b/src/components/DataRoom/SeeMore/Wave.tsx
index 3a31f928a..ecad432c4 100644
--- a/src/components/DataRoom/SeeMore/Wave.tsx
+++ b/src/components/DataRoom/SeeMore/Wave.tsx
@@ -1,66 +1,105 @@
import useContainerSize from '@/hooks/useContainerSize'
-import React, { useEffect, useRef } from 'react'
+import React, { useEffect, useRef, useMemo, useCallback } from 'react'
type WaveProps = {
height?: number
- color?: string
+ colors?: string[]
amplitude?: number
frequency?: number
speed?: number
}
const DEFAULT_HEIGHT = 600
-const DEFAULT_COLOR = '#12FF80'
+const DEFAULT_COLORS = ['#12FF80', '#008A40', '#003C1C']
const DEFAULT_AMPLITUDE = 100
const DEFAULT_FREQUENCY = 1
-const DEFAULT_SPEED = 3
+const DEFAULT_SPEED = 0.8
const STROKE_WIDTH = 4
const Wave = ({
height = DEFAULT_HEIGHT,
- color = DEFAULT_COLOR,
+ colors = DEFAULT_COLORS,
amplitude = DEFAULT_AMPLITUDE,
frequency = DEFAULT_FREQUENCY,
speed = DEFAULT_SPEED,
}: WaveProps) => {
+ const canvasRef = useRef(null)
const containerRef = useRef(null)
const { width } = useContainerSize(containerRef)
+ const animationRef = useRef()
- useEffect(() => {
- let startTime: number | null = null
- let animationFrameId: number
-
- const animate = (time: number) => {
- if (!startTime) startTime = time
- const elapsed = time - startTime
-
- // Only create the path if width is valid
- if (width > 0) {
- const path = Array.from({ length: width + 1 }, (_, i) => {
- const y = height / 2 + amplitude * Math.sin((i / width) * 2 * Math.PI * frequency + (elapsed * speed) / 1000)
- return `${i},${y}`
- }).join(' L')
-
- const pathElement = containerRef.current?.querySelector('path')
- if (pathElement) {
- pathElement.setAttribute('d', `M${path}`)
- }
+ const dpr = useMemo(() => window.devicePixelRatio || 1, [])
+
+ const paths = useMemo(() => {
+ if (width === 0) return [[], [], []]
+ const calculatePath = (amplitudeOffset: number) =>
+ Array.from(
+ { length: width + 1 },
+ (_, i) => (amplitude - amplitudeOffset) * Math.sin((i / width) * 2 * Math.PI * frequency),
+ )
+ return [calculatePath(80), calculatePath(40), calculatePath(0)]
+ }, [width, amplitude, frequency])
+
+ const setupCanvas = useCallback(() => {
+ const canvas = canvasRef.current
+ const ctx = canvas?.getContext('2d')
+ if (!ctx || !canvas || width === 0) return
+
+ canvas.width = width * dpr
+ canvas.height = height * dpr
+ canvas.style.width = `${width}px`
+ canvas.style.height = `${height}px`
+ ctx.scale(dpr, dpr)
+ }, [width, height, dpr])
+
+ const drawWave = useCallback(
+ (ctx: CanvasRenderingContext2D, path: number[], color: string, shift: number) => {
+ ctx.beginPath()
+ ctx.lineWidth = STROKE_WIDTH
+ ctx.strokeStyle = color
+
+ for (let i = 0; i <= width; i++) {
+ ctx.lineTo(i, height / 2 + path[(i + Math.floor(shift)) % width])
}
- animationFrameId = requestAnimationFrame(animate)
- }
+ ctx.stroke()
+ },
+ [width, height],
+ )
+
+ const animate = useCallback(
+ (time: number) => {
+ const canvas = canvasRef.current
+ const ctx = canvas?.getContext('2d')
+ if (!ctx || !canvas) return
- animationFrameId = requestAnimationFrame(animate)
- return () => cancelAnimationFrame(animationFrameId)
- }, [width, height, amplitude, frequency, speed])
+ const shift = (time * speed) % width
+
+ ctx.clearRect(0, 0, width, height)
+
+ paths.forEach((path, index) => {
+ drawWave(ctx, path, colors[index % colors.length], shift)
+ })
+
+ animationRef.current = requestAnimationFrame(animate)
+ },
+ [width, height, paths, speed, colors, drawWave],
+ )
+
+ useEffect(() => {
+ setupCanvas()
+ animationRef.current = requestAnimationFrame(animate)
+
+ return () => {
+ if (animationRef.current) {
+ cancelAnimationFrame(animationRef.current)
+ }
+ }
+ }, [setupCanvas, animate])
return (
- {width > 0 && (
-
- )}
+
)
}
diff --git a/src/components/DataRoom/SeeMore/styles.module.css b/src/components/DataRoom/SeeMore/styles.module.css
index 98c2dca6e..fba121f9d 100644
--- a/src/components/DataRoom/SeeMore/styles.module.css
+++ b/src/components/DataRoom/SeeMore/styles.module.css
@@ -38,18 +38,7 @@
width: 100%;
transform: translateY(-50%);
right: 0;
- --wave-index: 30;
- z-index: calc(var(--wave-index) - (var(--n) * 10));
-}
-
-.wave:nth-child(1) {
- --n: 0;
-}
-.wave:nth-child(2) {
- --n: 1;
-}
-.wave:nth-child(3) {
- --n: 2;
+ z-index: 30;
}
@media (max-width: 900px) {