01import useMousePosition from './useMouse';02import Needle from './needle';0304export default function MagneticGrid() {05const { x, y } = useMousePosition();0607// 生成一个 8x12 的网格数组 (共96个指针)08const gridSize = Array.from({ length: 96 });0910return (11<div className="bg-[#111111] flex flex-col items-center justify-center font-mono text-[#444] p-4">12<div className="mb-8 md:mb-12 text-center tracking-widest uppercase">13<h1 className="text-white text-xl font-light">磁力罗盘矩阵</h1>14<div className="text-xs text-[#666]">交互式 React 效果</div>15</div>1617<div className="grid grid-cols-8 gap-2 md:gap-4 p-2 md:p-8 border border-[#333]" style={{ boxShadow: '0 0 50px rgba(0,0,0,0.5)' }}>18{gridSize.map((_, i) => (19<Needle key={i} mouseX={x} mouseY={y} />20))}21</div>22</div>23);24}
由于该效果是基于鼠标位置来实现的,因此,我们首先应该封装一个 useMousePosition 自定义 hook 来获取鼠标位置,这个我们在之前已经学习过了,就不再赘述
其次,每一个指针,都需要跟当前的鼠标位置进行计算,因此,我们应该单独封装一个 Needle 组件,专门处理指针的旋转角度计算问题
在该组件中,由于我们需要高频次的计算指针的旋转角度,因此我们需要使用 useEffect 来响应鼠标位置的变化,然后基于鼠标位置和指针的中心坐标,计算出指针的旋转角度即可
1export default function Needle({ mouseX, mouseY }: NeedleProps) {2const needleRef = useRef<HTMLDivElement>(null);3const [rotation, setRotation] = useState(0);45useEffect(() => {6...7}, [mouseX, mouseY]); // 当鼠标位置改变时,重新计算角度
其他的内容请结合代码中的注释理解与学习