Can't draw rectangle with mouse at exact point on canvas when page is able to scroll
username
Although the code works fine if we draw the rectangle without scrolling the canvas or the page. However, if we scroll, the rectangle doesn't appear on the screen from where we started dragging the mouse.
//Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//Variables
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
//Mousedown
$(canvas).on('mousedown', function(e) {
last_mousex = parseInt(e.clientX-canvasx);
last_mousey = parseInt(e.clientY-canvasy);
mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function(e) {
mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function(e) {
mousex = parseInt(e.clientX-canvasx);
mousey = parseInt(e.clientY-canvasy);
if(mousedown) {
ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas
ctx.beginPath();
var width = mousex-last_mousex;
var height = mousey-last_mousey;
ctx.rect(last_mousex,last_mousey,width,height);
ctx.strokeStyle = 'black';
ctx.lineWidth = 10;
ctx.stroke();
}
//Output
$('#output').html('current: '+mousex+', '+mousey+'<br/>last: '+last_mousex+', '+last_mousey+'<br/>mousedown: '+mousedown);
});
canvas {
cursor: crosshair;
border: 1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="500"></canvas>
<div id="output"></div>
Anders Carstenson
Calculate the mouse position using this answer , it works fine. It takes scrolling into account.
function getCursorPosition(canvas, event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return { x, y };
}
//Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//Variables
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
//Mousedown
$(canvas).on('mousedown', function(e) {
var pos = getCursorPosition(canvas, e);
last_mousex = pos.x;
last_mousey = pos.y;
mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function(e) {
mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function(e) {
var pos = getCursorPosition(canvas, e);
mousex = pos.x;
mousey = pos.y;
if(mousedown) {
ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas
ctx.beginPath();
var width = mousex-last_mousex;
var height = mousey-last_mousey;
ctx.rect(last_mousex,last_mousey,width,height);
ctx.strokeStyle = 'black';
ctx.lineWidth = 10;
ctx.stroke();
}
//Output
$('#output').html('current: '+mousex+', '+mousey+'<br/>last: '+last_mousex+', '+last_mousey+'<br/>mousedown: '+mousedown);
});
canvas {
cursor: crosshair;
border: 1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="500"></canvas>
<div id="output"></div>