英文:
Does mousemove event act differently according to mouse direction?
问题
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) {
// In case 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 below.
I would expect the mousemove
direction shouldn't change how the drawing happens. Is there something obvious that I might be missing?
英文:
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?
答案1
得分: 1
注意笔画的位置!
从技术上讲,它在您在坐标中指定的矩形的外部。
因此,在您的 mousemove
函数中,当您执行 clearRect
时,您正在清除红线内部的区域,而不是红线本身。
在您的 mousedown
函数中,您会对左上角进行一些微调,然后继续更宽/更深,而不是标称的宽度/高度。
也许尝试一下在 mousemove
中进行微调?
例如,您可以尝试这样做:
...
rect.h = e.pageY - rect.startY;
ctx.clearRect(rect.startX-3, rect.startY-3, rect.w+6, rect.h+6);
ctx.beginPath();
...
如果这不起作用,尝试将 clearRect
替换为绘制不同颜色的矩形。这样,您可以检查它试图删除的位置,并确保它在您预期的位置。
英文:
Watch out for the position of the stroke!
It is technically outside the rectangle that you specify in the coordinates.
Therefore, in your mousemove
function, when you clearRect
, you are clearing the area inside the red lines, and not the red lines themselves.
Further up, in your mousedown
function, you do some good fudging to start to the left/top, and proceed wider/deeper than the nominal width/height.
Perhaps try fudging your mousemove?
For example, you could try this:
...
rect.h = e.pageY - rect.startY;
ctx.clearRect(rect.startX-3, rect.startY-3, rect.w+6, rect.h+6);
ctx.beginPath();
...
If that doesn't work, try replacing the clearRect
with a rect
that draws a different colour. That way, you can check where it is trying to delete, and make sure that it is where you expect.
答案2
得分: 1
以下是翻译好的内容:
有几点需要注意:
- 正如ProfDFrancis所指出的,您的描边实际上超出了边界框矩形,因此您需要扩展清除区域。
- 您清除的是新矩形,而不是先前的矩形,因此如果指针移动超过1像素,将留下残留。
- 您在指针偏移方面不一致 -
pageX
和clientX
不能互换使用,因此对于rect.w
和rect.h
(似乎考虑了元素偏移,如mousedown
处理程序中的情况)的注释计算是正确的。
您可以像这样做:
if(isDrawing === true) {
const strokeSize = 3;
// 计算描边触及的所有像素的边界框 - 请确保获得慷慨的边界以处理抗锯齿
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();
// 等等
}
英文:
There's a few things:
- As ProfDFrancis has pointed out, your stroke actually extends outside the bounding box rectangle, so you need to expand your cleared area
- You're clearing the new rectangle rather than the previous rectangle, so if the pointer movements are more than 1px at a time you will leave artifacts
- You're being inconsistent with your pointer offsets –
pageX
andclientX
are not interchangeable, so your commented-out calculation forrect.w
andrect.h
(which appears to take the element offset into consideration, as in themousedown
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论