如何在Canvas对象与鼠标位置不同时实现鼠标拖动同步移动?
实现Canvas圆形的拖动功能(保持点击时的相对距离)
核心思路
要实现这个需求,我们需要通过监听鼠标的三个关键事件来控制圆形的拖动逻辑:
mousedown:记录点击瞬间的鼠标位置、圆心位置,计算两者的偏移量(这是保持相对距离的关键),并标记开始拖动状态mousemove:如果处于拖动状态,根据当前鼠标位置和之前的偏移量,实时更新圆心坐标并重新绘制圆形mouseup:结束拖动状态
同时要处理Canvas全屏显示的问题,以及窗口大小变化时的适配。
完整代码实现
<!DOCTYPE html> <html> <head> <style> /* 去掉页面边距,让Canvas占满全屏 */ body { margin: 0; overflow: hidden; } canvas { display: block; } </style> </head> <body> <canvas id="dragCanvas"></canvas> <script> const canvas = document.getElementById('dragCanvas'); const ctx = canvas.getContext('2d'); // 设置Canvas全屏 function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; // 窗口大小变化后重新绘制圆形 drawCircle(); } resizeCanvas(); window.addEventListener('resize', resizeCanvas); // 初始圆心位置 let circleX = 500; let circleY = 500; const circleRadius = 30; // 圆形半径,可调整 // 拖动状态变量 let isDragging = false; let offsetX, offsetY; // 绘制圆形的函数 function drawCircle() { // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制圆形 ctx.beginPath(); ctx.arc(circleX, circleY, circleRadius, 0, Math.PI * 2); ctx.fillStyle = '#2ecc71'; ctx.fill(); ctx.strokeStyle = '#27ae60'; ctx.lineWidth = 2; ctx.stroke(); } // 监听鼠标按下事件 canvas.addEventListener('mousedown', (e) => { // 获取鼠标相对于Canvas的坐标(排除页面滚动等影响) const rect = canvas.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; // 计算鼠标与圆心的偏移量(点击时的相对位置) offsetX = mouseX - circleX; offsetY = mouseY - circleY; // 标记开始拖动 isDragging = true; }); // 监听鼠标移动事件 canvas.addEventListener('mousemove', (e) => { if (!isDragging) return; const rect = canvas.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; // 根据偏移量更新圆心位置,保持点击时的相对距离 circleX = mouseX - offsetX; circleY = mouseY - offsetY; // 重新绘制圆形 drawCircle(); }); // 监听鼠标松开事件 canvas.addEventListener('mouseup', () => { isDragging = false; }); // 初始绘制圆形 drawCircle(); </script> </body> </html>
代码说明
- 全屏Canvas设置:通过CSS去掉页面边距,JS监听
resize事件动态调整Canvas尺寸,确保始终占满窗口 - 拖动逻辑:
- 按下鼠标时,计算鼠标与圆心的偏移量
offsetX和offsetY,这个值在拖动过程中保持不变,保证圆形和鼠标的相对距离一致 - 拖动过程中,用当前鼠标位置减去偏移量,得到新的圆心坐标,再重新绘制圆形
- 松开鼠标后,取消拖动状态,停止更新位置
- 按下鼠标时,计算鼠标与圆心的偏移量
- 坐标计算:使用
getBoundingClientRect()获取Canvas的位置,确保鼠标坐标是相对于Canvas的,避免页面滚动或边框导致的坐标偏差
内容的提问来源于stack exchange,提问作者Péter Vatler
相关产品推荐
相关产品推荐

