"use client"; import { useThree } from "@react-three/fiber"; import { useEffect } from "react"; /** * Batida das cenas WebGL em `frameloop="demand"`: enquanto `active`, pede um quadro a no máximo `fps` por * segundo (fundo ambiente, sem gastar 60 quadros por segundo); com `active` falso, nenhum quadro é desenhado. * Quem precisa de mais (entrada, rolagem, cursor) pede o próximo quadro com `invalidate()` dentro do useFrame. */ export default function FramePulse({ active, fps = 30, }: { active: boolean; fps?: number; }) { const invalidate = useThree((state) => state.invalidate); useEffect(() => { if (!active) return; const gap = 1000 / fps - 2; let id = 0; let last = 0; const beat = (now: number) => { id = requestAnimationFrame(beat); if (now - last < gap) return; last = now; invalidate(); }; id = requestAnimationFrame(beat); return () => cancelAnimationFrame(id); }, [active, fps, invalidate]); return null; }