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