Fix new render loop on resize

Fixes a bug where a new render loop is created every time the page is
resized (oops). This would cause performance problems if the
page is resized a lot.

Fixes the background not filling the screen on mobile Firefox when
zoomed out or scrolling into overflow.
This commit is contained in:
Evan Goode 2025-04-07 17:51:14 -04:00
parent abc8d1e9b8
commit 6231951026

View File

@ -173,40 +173,44 @@ async function background(el: HTMLDivElement) {
const prmQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
const handleChangePrm = () => {
shouldAnimate = isSupported && !prmQuery.matches;
render();
};
handleChangePrm();
prmQuery.addEventListener("change", handleChangePrm);
function render() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
if (shouldAnimate) {
const time = performance.now() / 1000;
timeUniform.value = time;
angleUniform.value =
((performance.timeOrigin + performance.now()) / 1000 / 30) %
(2 * Math.PI);
}
renderer.render(scene, camera);
if (shouldAnimate) {
requestAnimationFrame(render);
}
}
let dimensions = { width: window.innerWidth, height: window.innerHeight };
let dimensions: { width: number, height: number } | null = null;
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
dimensions = { width: Math.round(width), height: Math.round(height) };
render();
}
});
resizeObserver.observe(el);
function render() {
if (dimensions === null) {
return;
}
camera.aspect = dimensions.width / dimensions.height;
camera.updateProjectionMatrix();
renderer.setSize(dimensions.width, dimensions.height);
const time = performance.now() / 1000;
timeUniform.value = time;
angleUniform.value =
((performance.timeOrigin + performance.now()) / 1000 / 30) %
(2 * Math.PI);
renderer.render(scene, camera);
}
function renderLoop() {
if (shouldAnimate) {
render();
}
requestAnimationFrame(renderLoop);
}
render();
requestAnimationFrame(renderLoop);
}
export default background;