import { useEffect, useRef, useState } from 'react'; import styles from './gradients.module.css'; import { initGrainFilter } from './grainPostProcessing'; import { InitThreeOptions, initThree } from './initThree'; import { initScene } from './initScene'; import { initGradient } from './initGradients'; import Stats from 'stats.js'; const threeCanvas = ( canvas: HTMLCanvasElement, viewportSize: InitThreeOptions, initTimeOffset: number = 0 ) => { const { renderer, clock } = initThree(canvas, viewportSize); const { scene, camera, updateSize: updateCameraSize } = initScene(renderer); const { render: renderGradient, updateSize: updateGradientSize, unload: unloadGradinet, } = initGradient(scene, renderer); const { render: renderFrame, resize: resizeFrame } = initGrainFilter( renderer, scene, camera ); //const stats = new Stats(); // the number will decide which information will be displayed // 0 => FPS Frames rendered in the last second. The higher the number the better. // 1 => MS Milliseconds needed to render a frame. The lower the number the better. // 2 => MB MBytes of allocated memory. (Run Chrome with --enable-precise-memory-info) // 3 => CUSTOM User-defined panel support. //stats.showPanel(0); //document.body.appendChild(stats.dom); let elapsedTime = 0; let delta = 0; let isActive = true; const animate = () => { if (!isActive) return; //stats.begin(); elapsedTime = clock.elapsedTime + initTimeOffset; delta = clock.getDelta(); renderGradient(elapsedTime, delta); renderFrame(elapsedTime, delta); //stats.end(); requestAnimationFrame(animate); }; const resizeCanvas = (width: number, height: number) => { renderer.setSize(width, height); updateCameraSize(); updateGradientSize(); resizeFrame(); }; animate(); resizeCanvas(viewportSize.width, viewportSize.height); const unload = () => { isActive = false; unloadGradinet(); renderer.dispose(); }; return { resizeCanvas, unload, }; }; export function Gradients() { const rootRef = useRef(null); const canvasRef = useRef(null); const [timeOffset] = useState(Math.random() * 1000); useEffect(() => { try { const canvas = threeCanvas( canvasRef.current as HTMLCanvasElement, { width: rootRef.current?.clientWidth || 0, height: rootRef.current?.clientHeight || 0, }, timeOffset ); const resize = () => { canvas.resizeCanvas( rootRef.current?.clientWidth || 0, rootRef.current?.clientHeight || 0 ); }; window.addEventListener('resize', resize); return () => { window.removeEventListener('resize', resize); canvas.unload(); }; } catch (e) { console.error(e); } }, [timeOffset]); return (
); }