I'm experimenting in canvas and trying to create pan effect. I've managed to pan succesfully, but I'm curious if I'm doing it correctly. Since I've come up with the following code myself, I don't know if there is a better way to accomplish the task.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 400;
var global = {
scale : 1,
offset : {
x : 0,
y : 0,
},
};
var pan = {
start : {
x : null,
y : null,
},
offset : {
x : 0,
y : 0,
},
};
function draw() {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(pan.offset.x, pan.offset.y);
context.beginPath();
context.rect(50, 50, 100, 100);
context.fillStyle = 'skyblue';
context.fill();
context.beginPath();
context.arc(350, 250, 50, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
}
draw();
canvas.addEventListener("mousedown", startPan);
canvas.addEventListener("mouseleave", endPan);
canvas.addEventListener("mouseup", endPan);
function startPan(e) {
canvas.addEventListener("mousemove", trackMouse);
canvas.addEventListener("mousemove", draw);
pan.start.x = e.clientX;
pan.start.y = e.clientY;
}
function endPan(e) {
canvas.removeEventListener("mousemove", trackMouse);
canvas.removeEventListener("mousemove", draw);
pan.start.x = null;
pan.start.y = null;
global.offset.x = pan.offset.x;
global.offset.y = pan.offset.y;
}
function trackMouse(e) {
var offsetX = e.clientX - pan.start.x;
var offsetY = e.clientY - pan.start.y;
pan.offset.x = global.offset.x + offsetX;
pan.offset.y = global.offset.y + offsetY;
}
body {
background: gainsboro;
margin: 0;
}
canvas {
background: white;
box-shadow: 1px 1px 1px rgba(0,0,0,.2);
}
<canvas id="canvas"></canvas>
Updated version of the pan (using the tips Flambino provided):
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 400;
var global = {
scale : 1,
offset : {
x : 0,
y : 0,
},
};
var panning = {
start : {
x : null,
y : null,
},
offset : {
x : 0,
y : 0,
},
};
function draw() {
context.beginPath();
context.rect(50, 50, 100, 100);
context.fillStyle = 'skyblue';
context.fill();
context.beginPath();
context.arc(350, 250, 50, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
}
draw();
canvas.addEventListener("mousedown", startPan);
function pan() {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(panning.offset.x, panning.offset.y);
draw();
}
function startPan(e) {
window.addEventListener("mousemove", trackMouse);
window.addEventListener("mousemove", pan);
window.addEventListener("mouseup", endPan);
panning.start.x = e.clientX;
panning.start.y = e.clientY;
}
function endPan(e) {
window.removeEventListener("mousemove", trackMouse);
window.removeEventListener("mousemove", pan);
window.removeEventListener("mouseup", endPan);
panning.start.x = null;
panning.start.y = null;
global.offset.x = panning.offset.x;
global.offset.y = panning.offset.y;
}
function trackMouse(e) {
var offsetX = e.clientX - panning.start.x;
var offsetY = e.clientY - panning.start.y;
panning.offset.x = global.offset.x + offsetX;
panning.offset.y = global.offset.y + offsetY;
}
body {
background: gainsboro;
margin: 0;
}
canvas {
background: white;
box-shadow: 1px 1px 1px rgba(0,0,0,.2);
}
<canvas id="canvas"></canvas>