Spaces:
Build error
Build error
| "use client"; | |
| import { animate } from "motion"; | |
| import { useEffect, useRef } from "react"; | |
| import initCanvas from "@/utils/init-canvas"; | |
| export default function EndpointsExtract({ size = 20 }: { size?: number }) { | |
| const canvasRef = useRef<HTMLCanvasElement>(null); | |
| useEffect(() => { | |
| const canvas = canvasRef.current; | |
| if (!canvas) return; | |
| const ctx = initCanvas(canvas); | |
| let isRunning = false; | |
| let isActive = false; | |
| let diff = 0; | |
| const defaultRowAlphas = [ | |
| 0.4, 0.04, 0.2, 0.4, 0.2, 0, 0, 0.04, 0.04, 0, 0, 0.2, 0.4, 0.2, 0.04, | |
| 0.4, | |
| ]; | |
| const differs = Array.from({ length: 16 }, () => 0.2 + Math.random() * 0.2); | |
| const scaler = size / 20; | |
| const render = () => { | |
| ctx.fillStyle = "#FF4C00"; | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| for (let i = 0; i < 16; i++) { | |
| if ([5, 6, 9, 10].includes(i)) continue; | |
| ctx.globalAlpha = defaultRowAlphas[i] + diff * differs[i]; | |
| ctx.globalAlpha = | |
| Math.min(ctx.globalAlpha, 0.4) - Math.max(ctx.globalAlpha - 0.4, 0); | |
| ctx.fillRect( | |
| (3 + (i % 4) * 4) * scaler, | |
| (3 + Math.floor(i / 4) * 4) * scaler, | |
| 2 * scaler, | |
| 2 * scaler, | |
| ); | |
| } | |
| ctx.globalAlpha = 1; | |
| ctx.fillRect(7, 7, 6, 2); | |
| ctx.globalAlpha = 0.4; | |
| ctx.fillRect(7, 11, 2 + diff * 4, 2); | |
| if (isRunning) { | |
| requestAnimationFrame(render); | |
| } | |
| }; | |
| const timeouts: number[] = []; | |
| let runCount = 0; | |
| const duration = 300; | |
| const cycle = () => { | |
| isRunning = true; | |
| animate(diff, 1, { | |
| duration: duration / 1000, | |
| onUpdate: (value) => { | |
| diff = value < 0.5 ? value * 2 : 1 - (value - 0.5) * 2; | |
| }, | |
| }); | |
| timeouts.forEach((timeout) => { | |
| window.clearTimeout(timeout); | |
| }); | |
| timeouts.push( | |
| window.setTimeout( | |
| () => { | |
| isRunning = false; | |
| }, | |
| Math.max(duration, 300), | |
| ), | |
| ); | |
| runCount += 1; | |
| if (runCount === 3 || !isActive) return; | |
| timeouts.push( | |
| window.setTimeout(() => { | |
| cycle(); | |
| }, duration), | |
| ); | |
| }; | |
| const activate = () => { | |
| if (isActive) return; | |
| isActive = true; | |
| runCount = 0; | |
| cycle(); | |
| render(); | |
| }; | |
| const deactivate = () => { | |
| if (!isActive) return; | |
| isActive = false; | |
| }; | |
| render(); | |
| canvas.addEventListener("resize", render); | |
| const group = canvasRef.current!.closest(".group"); | |
| if (group) { | |
| group.addEventListener("mouseenter", activate); | |
| group.addEventListener("mouseleave", deactivate); | |
| return () => { | |
| group.removeEventListener("mouseenter", activate); | |
| group.removeEventListener("mouseleave", deactivate); | |
| }; | |
| } | |
| }, [size]); | |
| return <canvas ref={canvasRef} style={{ width: size, height: size }} />; | |
| } | |