实现画布拖拽js
实现画布拖拽的基本思路
通过监听鼠标事件(mousedown、mousemove、mouseup)实现画布拖拽功能。核心逻辑是记录鼠标按下时的初始位置,计算移动时的偏移量,并更新画布位置。
HTML 结构准备
创建一个包含画布的容器,画布元素需设置绝对定位以便移动:
<div id="canvas-container" style="position: relative; overflow: hidden; width: 800px; height: 600px;">
<canvas id="canvas" width="1600" height="1200" style="position: absolute;"></canvas>
</div>
JavaScript 实现
const canvas = document.getElementById('canvas');
const container = document.getElementById('canvas-container');
let isDragging = false;
let lastX = 0;
let lastY = 0;
let offsetX = 0;
let offsetY = 0;
// 鼠标按下事件
canvas.addEventListener('mousedown', (e) => {
isDragging = true;
lastX = e.clientX;
lastY = e.clientY;
e.preventDefault(); // 阻止默认行为(如文本选中)
});
// 鼠标移动事件
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const deltaX = e.clientX - lastX;
const deltaY = e.clientY - lastY;
offsetX += deltaX;
offsetY += deltaY;
lastX = e.clientX;
lastY = e.clientY;
updateCanvasPosition();
});
// 鼠标释放事件
document.addEventListener('mouseup', () => {
isDragging = false;
});
// 更新画布位置
function updateCanvasPosition() {
canvas.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
}
边界限制处理
为避免画布被拖出可视区域,可在 updateCanvasPosition 中添加边界检查:
function updateCanvasPosition() {
const maxX = 0;
const maxY = 0;
const minX = container.clientWidth - canvas.width;
const minY = container.clientHeight - canvas.height;
offsetX = Math.min(maxX, Math.max(minX, offsetX));
offsetY = Math.min(maxY, Math.max(minY, offsetY));
canvas.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
}
平滑惯性拖拽(可选)
通过记录移动速度并在鼠标释放后继续缓动,实现更自然的拖拽效果:
let velocityX = 0;
let velocityY = 0;
let lastTime = 0;
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const now = Date.now();
const deltaTime = now - lastTime;
if (deltaTime > 0) {
velocityX = (e.clientX - lastX) / deltaTime * 10;
velocityY = (e.clientY - lastY) / deltaTime * 10;
}
lastTime = now;
// 其余逻辑同上...
});
function animate() {
if (!isDragging && (Math.abs(velocityX) > 0.1 || Math.abs(velocityY) > 0.1)) {
offsetX += velocityX;
offsetY += velocityY;
velocityX *= 0.95; // 摩擦系数
velocityY *= 0.95;
updateCanvasPosition();
}
requestAnimationFrame(animate);
}
animate();
触摸屏支持
为兼容移动设备,需添加触摸事件:
canvas.addEventListener('touchstart', (e) => {
isDragging = true;
lastX = e.touches[0].clientX;
lastY = e.touches[0].clientY;
e.preventDefault();
});
document.addEventListener('touchmove', (e) => {
if (!isDragging) return;
const deltaX = e.touches[0].clientX - lastX;
const deltaY = e.touches[0].clientY - lastY;
offsetX += deltaX;
offsetY += deltaY;
lastX = e.touches[0].clientX;
lastY = e.touches[0].clientY;
updateCanvasPosition();
});
document.addEventListener('touchend', () => {
isDragging = false;
});





