ref: 27f0dafcf0d78b286ccc7812c59fbc5d3e95ebe5
parent: 4feb5fdf0cc6c9612e2928f1e2a2335fbbd03a71
author: Ben Harris <bjh21@bjh21.me.uk>
date: Thu Oct 6 06:11:32 EDT 2022
js: Map mouse co-ordinates correctly even when CSS scales our canvas Our system for mapping mouse coordinates to canvas coordinates assumed that the puzzle canvas had the same dimensions in CSS as its own internal width and height. This is true in the current wrapper HTML, but it's very easy to accidentally change and there are circumstances where we might want to deliberately change it in future. To fix this, we now inspect the CSS size of the canvas when processing mouse events, and map the coordinates through the scaling and translation necessary to convert CSS pixels into canvas pixels.
--- a/emccpre.js
+++ b/emccpre.js
@@ -166,6 +166,21 @@
y: event.pageY - ecoords.y};
}
+// Higher-level mouse helper function to specifically map mouse
+// coordinates into the coordinates on a canvas that appear under it.
+// This depends on the details of how a canvas gets scaled by CSS.
+function canvas_mouse_coords(event, element) {
+ var rcoords = relative_mouse_coords(event, element);
+ // Assume that the canvas is as large as possible within its CSS
+ // box without changing its aspect ratio.
+ var scale = Math.max(element.width / element.offsetWidth,
+ element.height / element.offsetHeight);
+ var xoffset = (element.offsetWidth - element.width / scale) / 2;
+ var yoffset = (element.offsetHeight - element.height / scale) / 2;
+ return {x: (rcoords.x - xoffset) * scale,
+ y: (rcoords.y - yoffset) * scale}
+}
+
// Enable and disable items in the CSS menus.
function disable_menu_item(item, disabledFlag) {
if (disabledFlag)
@@ -255,7 +270,7 @@
if (event.button >= 3)
return;
- var xy = relative_mouse_coords(event, onscreen_canvas);
+ var xy = canvas_mouse_coords(event, onscreen_canvas);
var logbutton = event.button;
if (event.shiftKey)
logbutton = 1; // Shift-click overrides to middle button
@@ -272,7 +287,7 @@
onscreen_canvas.onmousemove = function(event) {
var down = buttons_down();
if (down) {
- var xy = relative_mouse_coords(event, onscreen_canvas);
+ var xy = canvas_mouse_coords(event, onscreen_canvas);
mousemove(xy.x, xy.y, down);
}
};
@@ -283,7 +298,7 @@
return;
if (button_phys2log[event.button] !== null) {
- var xy = relative_mouse_coords(event, onscreen_canvas);
+ var xy = canvas_mouse_coords(event, onscreen_canvas);
mouseup(xy.x, xy.y, button_phys2log[event.button]);
button_phys2log[event.button] = null;
}