I have the following piece of code
canvas1.addEventListener('mousedown', function(e) {
var x = e.clientX - canvas1.getBoundingClientRect().left;
var y = e.clientY - canvas1.getBoundingClientRect().top;
if (rect.currentActiveBox == currentActiveBox) {
// Incase we try to draw another box first clear out the previous box.
console.log('clearing ', rect);
ctx.clearRect(rect.startX - 6 , rect.startY - 6, rect.w + 8, rect.h + 8);
}
rect.startX = x;
rect.startY = y;
isDrawing = true;
rect.currentActiveBox = currentActiveBox;
rects[currentActiveBox] = JSON.parse(JSON.stringify(rect));
});
canvas1.addEventListener('mousemove', function(e) {
if(isDrawing === true) {
// rect.w = (e.pageX - this.offsetLeft) - rect.startX;
// rect.h = (e.pageY - this.offsetTop) - rect.startY ;
rect.w = e.pageX - rect.startX;
rect.h = e.pageY - rect.startY;
ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h);
ctx.beginPath();
ctx.strokeStyle = "red";
ctx.lineWidth = 3;
ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
rects[currentActiveBox] = JSON.parse(JSON.stringify(rect));
}
});
which just draws a box as shown below
However this only works if I drag the mouse from top
to bottom
manner. If I try dragging the mouse from bottom
up
, I get ghost boxes as shown bellow.
I would expect the mousemove
direction shouldn't change how the drawing happens. Is there something obvious that I might be missing?
There's a few things:
pageX
and clientX
are not interchangeable, so your commented-out calculation for rect.w
and rect.h
(which appears to take the element offset into consideration, as in the mousedown
handler) is correct.You could do something like:
if(isDrawing === true) {
const strokeSize = 3;
// Compute bounding box for all pixels touched by the stroke –
// be sure to get a generous border to cope with antialiasing
const clearLeft = Math.min(rect.startX, rect.startX + rect.w) - strokeSize;
const clearTop = Math.min(rect.startY, rect.startY + rect.h) - strokeSize;
const clearRight = Math.max(rect.startX, rect.startX + rect.w) + strokeSize;
const clearBottom = Math.max(rect.startY, rect.startY + rect.h) + strokeSize;
ctx.clearRect(clearLeft, clearTop, clearRight - clearLeft, clearBottom - clearTop);
rect.w = e.pageX - this.offsetLeft - rect.startX;
rect.h = e.pageY - this.offsetTop - rect.startY;
ctx.beginPath();
// etc
}