拖放事件时在画布上绘制的形状移动太远
Posted
技术标签:
【中文标题】拖放事件时在画布上绘制的形状移动太远【英文标题】:Shapes drawn on canvas moves too far when drag and drop event 【发布时间】:2022-01-09 09:51:23 【问题描述】:我在拖动一个矩形时遇到了一个问题,如果我将它移动了一点点,它将重新绘制到离当前新鼠标位置太远的位置。 如何修正距离计算?
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
</head>
<body>
<canvas id="face-canvas" style="border:1px solid #000000;"></canvas>
<script type="module">
(() =>
let canvas = document.getElementById("face-canvas");
canvas.height = 300;
canvas.width = 300;
let cnt = canvas.getContext("2d");
let isDragging = false;
let offsetX = canvas.getBoundingClientRect().left;
let offsetY = canvas.getBoundingClientRect().top;
let startX = 0, startY = 0;
let selectedObjIndex = 0;
let drawn_obj = [];
drawn_obj.push(...drawBox(20, 15, 50, 50, "#1df"), index: 1)
drawn_obj.push(...drawBox(80, 40, 50, 50, "#a33"), index: 2)
document.addEventListener("mousedown", (event) => onMouseDown(event));
document.addEventListener("mousemove", (event) => onMouseMove(event));
document.addEventListener("mouseup", (event) => onMouseUp(event));
function onMouseDown(event)
event.preventDefault();
event.stopPropagation();
startX = Math.abs(parseInt(event.clientX - offsetX));
startY = Math.abs(parseInt(event.clientY - offsetY));
selectedObjIndex = selectedObj(startX, startY);
if(selectedObjIndex > 0)
isDragging = true;
console.log("ffffffff")
function onMouseMove(event)
if(isDragging && selectedObjIndex > 0)
let moveX = parseInt(event.clientX - offsetX);
let moveY = parseInt(event.clientY - offsetY);
let newX = parseInt(moveX - startX);
let newY = parseInt(moveY - startY);
drawn_obj[selectedObjIndex - 1].x += newX;
drawn_obj[selectedObjIndex - 1].y += newY;
console.log("newX, newY", newX, newY)
redrawAll();
function onMouseUp()
event.preventDefault();
event.stopPropagation();
isDragging = false;
function selectedObj(x, y)
for(let i = 0; i < drawn_obj.length; ++i)
if(x >= drawn_obj[i].x && x <= (drawn_obj[i].x + drawn_obj[i].w) &&
y >= drawn_obj[i].y && y <= (drawn_obj[i].y + drawn_obj[i].h))
return drawn_obj[i].index;
return 0;
function redrawAll()
cnt.clearRect(0, 0, canvas.width, canvas.height);
for(let i = 0; i < drawn_obj.length; ++i)
drawBox(drawn_obj[i].x, drawn_obj[i].y, drawn_obj[i].w, drawn_obj[i].h, drawn_obj[i].color);
function drawBox(x, y, w, h, color)
cnt.fillStyle = color;
cnt.fillRect(x, y, w, h);
return x: x, y: y, w: w, h: h, color: color
)();
</script>
</body>
</html>
【问题讨论】:
明显的问题是使用+=
,每次移动都会不断增加坐标。这就是为什么它如此迅速地从画布上加速。您只需使用=
并将鼠标坐标更正为最初单击的对象内的点的偏移量。
@tromgy 它现在正在工作,但是现在当我从任何位置拖动形状时,在拖动过程中光标将设置到它的角落,我怎样才能将光标保持在使用点击它?
【参考方案1】:
您可以这样做:
-
在顶层函数中为对象内部的偏移量添加两个变量:
let objectOffsetX = 0;
let objectOffsetY = 0;
-
在收到点击事件时计算它们:
function onMouseDown(event)
event.preventDefault();
event.stopPropagation();
startX = event.clientX - offsetX;
startY = event.clientY - offsetY;
selectedObjIndex = selectedObj(startX, startY);
objectOffsetX = startX - drawn_obj[selectedObjIndex - 1].x;
objectOffsetY = startY - drawn_obj[selectedObjIndex - 1].y;
if(selectedObjIndex > 0)
isDragging = true;
console.log("ffffffff")
-
当鼠标移动时,使用画布偏移和对象偏移计算新的对象位置:
function onMouseMove(event)
if(isDragging && selectedObjIndex > 0)
let newX = event.clientX - offsetX - objectOffsetX;
let newY = event.layerY - offsetY - objectOffsetY;
drawn_obj[selectedObjIndex - 1].x = newX;
drawn_obj[selectedObjIndex - 1].y = newY;
console.log("newX, newY", newX, newY)
redrawAll();
您可能会注意到我简化了一些代码,您实际上不需要使用parseInt
,您已经将所有内容都作为(整数)数字,而不是字符串。
你可以看到codepen的整个过程
【讨论】:
所以基本上我有两个问题:01)+=
,每一步都在增加。 02)我必须计算形状偏移,以便在移动时保持鼠标光标。以上是关于拖放事件时在画布上绘制的形状移动太远的主要内容,如果未能解决你的问题,请参考以下文章