Canvas Zoom (Custom scale)
by Noreh AD
HTML
<canvas id="canvas"></canvas>
CSS
body {
background: gainsboro;
margin: 0;
}
canvas {
background: white;
box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
}
JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 400;
var zoom = {
scale : 1,
screen : {
x : 0,
y : 0,
},
world : {
x : 0,
y : 0,
},
};
var mouse = {
screen : {
x : 0,
y : 0,
},
world : {
x : 0,
y : 0,
},
};
var scale = {
length : function(number) {
return Math.floor(number * zoom.scale);
},
x : function(number) {
return Math.floor((number - zoom.world.x) * zoom.scale + zoom.screen.x);
},
y : function(number) {
return Math.floor((number - zoom.world.y) * zoom.scale + zoom.screen.y);
},
x_INV : function(number) {
return Math.floor((number - zoom.screen.x) * (1 / zoom.scale) + zoom.world.x);
},
y_INV : function(number) {
return Math.floor((number - zoom.screen.y) * (1 / zoom.scale) + zoom.world.y);
},
};
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.rect(scale.x(50), scale.y(50), scale.length(100), scale.length(100));
context.fillStyle = 'skyblue';
context.fill();
context.beginPath();
context.arc(scale.x(350), scale.y(250), scale.length(50), 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
}
canvas.addEventListener("wheel", zoomUsingCustomScale);
function zoomUsingCustomScale(e) {
trackMouse(e);
trackWheel(e);
scaleShapes();
}
function trackMouse(e) {
mouse.screen.x = e.clientX;
mouse.screen.y = e.clientY;
mouse.world.x = scale.x_INV(mouse.screen.x);
mouse.world.y = scale.y_INV(mouse.screen.y);
}
function trackWheel(e) {
if (e.deltaY < 0) {
zoom.scale = Math.min(5, zoom.scale * 1.1);
} else {
zoom.scale = Math.max(0.1, zoom.scale * (1/1.1));
}
}
function scaleShapes() {
zoom.screen.x = mouse.screen.x;
zoom.screen.y = mouse.screen.y;
zoom.world.x = mouse.world.x;
zoom.world.y = mouse.world.y;
mouse.world.x = scale.x_INV(mouse.screen.x);
mouse.world.y =...