"use client"; import { useEffect, useRef } from "react"; export default function FilmGrain() { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext("2d"); if (!ctx) return; let animId: number; let lastFrame = 0; const fps = 24; // Cinematic film fps const frameInterval = 1000 / fps; const resize = () => { canvas.width = window.innerWidth / 2; canvas.height = window.innerHeight / 2; }; resize(); window.addEventListener("resize", resize); const render = (timestamp: number) => { animId = requestAnimationFrame(render); const delta = timestamp - lastFrame; if (delta < frameInterval) return; lastFrame = timestamp - (delta % frameInterval); const { width, height } = canvas; const imageData = ctx.createImageData(width, height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { const noise = Math.random() * 20; data[i] = noise; data[i + 1] = noise; data[i + 2] = noise; data[i + 3] = 12; // Very subtle } ctx.putImageData(imageData, 0, 0); }; animId = requestAnimationFrame(render); return () => { cancelAnimationFrame(animId); window.removeEventListener("resize", resize); }; }, []); return (