HTML5 responsive canvas mouse position and resize
canvas, html, javascript, jquery
Solution
Use the following function to get the proper mouse position even if the canvas is re-scaled. This will resolve the path start issue.
function getMouesPosition(e) {
var mouseX = e.offsetX * canvas.width / canvas.clientWidth | 0;
var mouseY = e.offsetY * canvas.height / canvas.clientHeight | 0;
return {x: mouseX, y: mouseY};
}
var clearButton = document.getElementById('doodle-bin');
var canvascontainer = document.getElementById('doodle-canvas-container');
var canvas = document.getElementById('doodle-canvas');
var context = canvas.getContext('2d');
var radius = (document.getElementById('doodle-canvas-container').clientWidth + document.getElementById('doodle-canvas-container').clientHeight) / 150;
var dragging = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
canvas.width = 1280;
canvas.height = 720;
canvas.style.width = '100%';
canvas.style.height = '100%';
/* CLEAR CANVAS */
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
clearButton.addEventListener('click', clearCanvas);
function getMouesPosition(e) {
var mouseX = e.offsetX * canvas.width / canvas.clientWidth | 0;
var mouseY = e.offsetY * canvas.height / canvas.clientHeight | 0;
return {x: mouseX, y: mouseY};
}
var putPoint = function (e) {
if (dragging) {
context.lineTo(getMouesPosition(e).x, getMouesPosition(e).y);
context.lineWidth = radius * 2;
context.stroke();
context.beginPath();
context.arc(getMouesPosition(e).x, getMouesPosition(e).y, radius, 0, Math.PI * 2);
context.fill();
context.beginPath();
context.moveTo(getMouesPosition(e).x, getMouesPosition(e).y);
}
};
var engage = function (e) {
dragging = true;
putPoint(e);
};
var disengage = function () {
dragging = false;
context.beginPath();
};
canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
document.addEventListener('mouseup', disengage);
canvas.addEventListener('contextmenu', disengage);
body{margin:0;overflow:hidden}canvas{border:1px solid #ccc}
<button id="doodle-bin">Clear</button>
<div id="doodle-canvas-container">
<canvas id="doodle-canvas"></canvas>
</div>
Problem
I have a drawing interface which the drawings need to be saved at 1280x720px. However, I want the canvas to be able to be scalable in relation to that aspect ratio. A problem is that when I draw, the start of the path is not on the cursor. I've looked everywhere and cannot find a solution. Here is the javascript: ``` var clearButton = document.getElementById('doodle-bin'); var canvascontainer = document.getElementById('doodle-canvas-container'); var canvas = document.getElementById('doodle-canvas'); var context = canvas.getContext('2d'); var radius = (document.getElementById('doodle-canvas-container').clientWidth + document.getElementById('doodle-canvas-container').clientHeight)/150; var dragging = false; context.mozImageSmoothingEnabled = false; context.imageSmoothingEnabled = false; canvas.width = 1280; canvas.height = 720; canvas.style.width = '100%'; canvas.style.height = '100%'; /* CLEAR CANVAS */ function clearCanvas() { context.clearRect(0, 0, canvas.width, canvas.height); } clearButton.addEventListener('click', clearCanvas); var putPoint = function (e) { if (dragging) { context.lineTo(e.offsetX, e.offsetY); context.lineWidth = radius * 2; context.stroke(); context.beginPath(); context.arc(e.offsetX, e.offsetY, radius, 0, Math.PI * 2); context.fill(); context.beginPath(); context.moveTo(e.offsetX, e.offsetY); } }; var engage = function (e) { dragging = true; putPoint(e); }; var disengage = function () { dragging = false; context.beginPath(); }; canvas.addEventListener('mousedown', engage); canvas.addEventListener('mousemove', putPoint); canvas.addEventListener('mouseup', disengage); document.addEventListener('mouseup', disengage); canvas.addEventListener('contextmenu', disengage); ```