"use client"; import { motion } from "framer-motion"; import { useEffect, useId, useRef, useState } from "react"; const Block = ({ x, y, ...props }: Omit, "x" | "y"> & { x: number; y: number; }) => { return ( ); }; export const GridPattern = ({ yOffset = 0, interactive = false, ...props }) => { const id = useId(); const ref = useRef>(null); const currentBlock = useRef<[x: number, y: number]>(); const counter = useRef(0); const [hoveredBlocks, setHoveredBlocks] = useState< Array<[x: number, y: number, key: number]> >([]); const staticBlocks = [ [1, 1], [2, 2], [4, 3], [6, 2], [7, 4], [5, 5], ]; useEffect(() => { if (!interactive) { return; } function onMouseMove(event: MouseEvent) { if (!ref.current) { return; } const rect = ref.current.getBoundingClientRect(); let x = event.clientX - rect.left; let y = event.clientY - rect.top; if (x < 0 || y < 0 || x > rect.width || y > rect.height) { return; } x = x - rect.width / 2 - 32; y = y - yOffset; x += Math.tan(32 / 160) * y; x = Math.floor(x / 96); y = Math.floor(y / 160); if (currentBlock.current?.[0] === x && currentBlock.current?.[1] === y) { return; } currentBlock.current = [x, y]; setHoveredBlocks((blocks) => { const key = counter.current++; const block = [x, y, key] as (typeof hoveredBlocks)[number]; return [...blocks, block].filter( (block) => !(block[0] === x && block[1] === y && block[2] !== key), ); }); } window.addEventListener("mousemove", onMouseMove); return () => { window.removeEventListener("mousemove", onMouseMove); }; }, [yOffset, interactive]); return ( ); };