diff --git a/index.html b/index.html
index f0194d2..0fd6071 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
-
+
diff --git a/package.json b/package.json
index 624f041..43e16ab 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "amerc-site",
- "version": "0.59.0-a11y",
+ "version": "0.60.0-canvasperf",
"private": true,
"type": "module",
"scripts": {
diff --git a/src/Scene2D.jsx b/src/Scene2D.jsx
index c8b40cf..dfbf13d 100644
--- a/src/Scene2D.jsx
+++ b/src/Scene2D.jsx
@@ -7,7 +7,7 @@ import Account from './Account.jsx';
import TavernGame from './TavernGame.jsx';
import { api } from './api.js';
-const RELEASE = '0.59.0-a11y';
+const RELEASE = '0.60.0-canvasperf';
const NAV = [
{ id: 'home', label: 'Tavern' },
diff --git a/src/TavernGame.jsx b/src/TavernGame.jsx
index c5888d5..a7a4832 100644
--- a/src/TavernGame.jsx
+++ b/src/TavernGame.jsx
@@ -57,12 +57,13 @@ export default function TavernGame({ onHotspot, stats }) {
useEffect(() => { statsRef.current = stats; }, [stats]);
const [ready, setReady] = useState(false);
useEffect(() => {
- const keys = Object.keys(SRC); const S = {}; let loaded = 0, raf, f = 0, buf;
+ const keys = Object.keys(SRC); const S = {}; let loaded = 0, raf, f = 0, buf, paused = false, io;
const start = () => {
setReady(true);
buf = document.createElement('canvas'); buf.width = W; buf.height = H; buildStatic(buf, S);
const ctx = canvasRef.current.getContext('2d'); ctx.imageSmoothingEnabled = false;
const render = () => {
+ if (paused) return;
f++;
ctx.drawImage(buf, 0, 0);
// bartender (a clothed guard tending bar) behind the bar (idle bob)
@@ -107,9 +108,15 @@ export default function TavernGame({ onHotspot, stats }) {
raf = requestAnimationFrame(render);
};
render();
+ // pause the 60fps loop while the tavern is scrolled out of view (CPU/battery)
+ io = new IntersectionObserver(([e]) => {
+ if (e.isIntersecting) { if (paused) { paused = false; render(); } }
+ else if (!paused) { paused = true; cancelAnimationFrame(raf); }
+ }, { threshold: 0 });
+ io.observe(canvasRef.current);
};
keys.forEach((k) => { const im = new Image(); im.onload = () => { if (++loaded === keys.length) start(); }; im.src = SRC[k]; S[k] = im; });
- return () => cancelAnimationFrame(raf);
+ return () => { cancelAnimationFrame(raf); if (io) io.disconnect(); };
}, []);
return (