You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.0 KiB
TypeScript

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<HTMLDivElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(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 (
<div className={styles.root} ref={rootRef}>
<canvas className={styles.canvas} ref={canvasRef}></canvas>
</div>
);
}