JSFiddle - React, Tailwind, and code Playground
HTML
<canvas id="c" width="400" height="400"></canvas>
<div id="debug"></div>
CSS
#c {
outline: 1px solid #ccc;
width: 400px;
height: 400px;
margin: 10px;
}
JavaScript
/* Trying to make a Google Maps-style app.
* Attempting to allow the following:
* -panning (works)
* -zooming (works)
* The problem:
* -centering the map on mouse coordinates after zooming
*/
var canvas, ctx, colorOffset;
var c_width, c_height
var globalPan = { startX : 0, startY : 0, currentX : 0, currentY : 0 };
var mouse = { x : 0, y : 0 };
var globalZoom = 1.0;
var isPanning = false;
function draw() {
ctx.clearRect(0,0,c_width,c_height);
ctx.save();
//Update for panning and zoom
/*THE PROBLEM - no matter what I do, this doesn't have the desired effect. It *sort of* works, but it's just a little... off. */
ctx.translate(
(mouse.x*globalZoom) / globalZoom,
(mouse.y*globalZoom) / globalZoom
);
//ctx.translate(
// mouse.x / globalZoom,
// mouse.y / globalZoom
//);
ctx.scale(globalZoom, globalZoom);
ctx.translate(
-mouse.x / globalZoom,
-mouse.y / globalZoom
);
/* end of problem */
ctx.translate(
globalPan.currentX / globalZoom,
globalPan.currentY / globalZoom
);
//Draw shapes
//Bounding box; all drawings are contained herewithin
ctx.strokeStyle = "#333";
ctx.strokeRect(0,0,c_width,c_height);
//Circles
//Color is just to show that we are animating
colorOffset = (new Date()).getSeconds() * 20;
for (var i = 12; i > 0; i--) {
ctx.beginPath();
ctx.strokeStyle = "hsl(" + (30 * i + colorOffset) + ", 100%, 50%)";
ctx.arc(200,200,10 * i, 0, Math.PI * 2, false);
ctx.stroke();
}
//Reset context so it doesn't keep translating and zooming endlessly
ctx.restore();
//Debugging stuff
debug.innerHTML = "globalPan.startX: " + globalPan.startX
+ "<br>globalPan.startY: " + globalPan.startY
+ "<br>globalPan.currentX: " + globalPan.currentX
+ "<br>globalPan.currentY: " + globalPan.currentY
...