feat(render): wheel + trackpad-pinch zoom in every mode

Reusable zoom control (zoomControl.js): RK.attachZoom(host) adds wheel/pinch zoom
to a render host; RK.applyZoom(host) scales whatever canvas is mounted (2D or
WebGL) via CSS transform (pixelated so pixel art stays crisp), re-applied on mode
switch. Trackpad pinch = ctrl+wheel, handled the same way; double-click resets.
Wired into the tavern stage, so it works across Tiled/ASCII/Fancy/Iso/3D. Client-only.
This commit is contained in:
jwinterm
2026-07-11 08:02:40 -04:00
parent 1b59d2f927
commit 0e553a49d6
2 changed files with 42 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
(function (root) {
'use strict';
var RK = root.RK = root.RK || {};
var MIN = 0.4, MAX = 4.0;
// Apply the host's current zoom to whatever canvas is mounted in it (2D or WebGL). Re-callable
// after a renderer/mode switch so the new canvas inherits the zoom.
RK.applyZoom = function (host) {
if (!host) return;
var z = host._rkZoom || 1;
var c = host.querySelector('canvas');
if (!c) return;
c.style.transformOrigin = 'center center';
c.style.transform = z === 1 ? '' : 'scale(' + z + ')';
c.style.imageRendering = 'pixelated'; // keep pixel art crisp when zoomed
};
// Wheel + trackpad-pinch zoom on a render host, shared by every mode. Trackpad pinch arrives as
// a wheel event with ctrlKey set; a normal wheel over the canvas zooms instead of scrolling.
RK.attachZoom = function (host) {
if (!host || host._rkZoomAttached) return;
host._rkZoomAttached = true;
host._rkZoom = host._rkZoom || 1;
host.style.overflow = 'hidden';
host.title = 'Scroll / pinch to zoom · double-click to reset';
host.addEventListener('wheel', function (e) {
e.preventDefault();
var factor = Math.exp(-e.deltaY * 0.0015); // smooth, direction-correct
host._rkZoom = Math.max(MIN, Math.min(MAX, (host._rkZoom || 1) * factor));
RK.applyZoom(host);
}, { passive: false });
host.addEventListener('dblclick', function () {
host._rkZoom = 1;
RK.applyZoom(host);
});
};
})(window);
+2
View File
@@ -14,6 +14,7 @@
<script src="js/render/atlas.js"></script>
<script src="js/render/charSprites.js"></script>
<script src="js/render/catSprites.js"></script>
<script src="js/render/zoomControl.js"></script>
<script src="js/render/assetPacks.js"></script>
<script src="js/render/avatarVisuals.js"></script>
<script src="js/render/designedRoom.js"></script>
@@ -216,6 +217,7 @@
if (currentMode !== mode) { r.destroy(); return; } // switched again while loading
currentRenderer = r;
draw();
if (RK.attachZoom) { RK.attachZoom(stageEl); RK.applyZoom(stageEl); } // wheel/pinch zoom, all modes
var active = r.name || mode;
setStatus(active === mode
? 'Render mode: ' + active