如何在保留HTML5 Canvas缩放功能的前提下实现平移(Pan)效果
Canvas添加平移功能实现方案
需要补充的核心逻辑
- 新增3个状态变量记录拖拽状态:
isDragging(是否正在拖拽)、lastX/lastY(上一次鼠标在画布上的坐标) - 监听鼠标按下事件,触发时标记拖拽激活,记录当前鼠标位置
- 监听鼠标移动事件,拖拽激活状态下计算鼠标像素偏移量,将偏移量除以当前缩放比例
scale,得到画布坐标的实际偏移值,更新原点orgnx/orgny后重绘 - 监听鼠标抬起、鼠标离开画布事件,触发时关闭拖拽状态
关键注意点
平移时的鼠标像素偏移不能直接赋值给orgnx/orgny,必须除以当前的scale值,才能适配缩放后的坐标尺度,否则会出现放大后拖拽过快、缩小后拖拽过慢的问题。之前直接修改orgnx/orgny不生效,就是因为没有同步更新画布的变换矩阵,也没有做偏移量的尺度换算。
完整修改后的代码
<html> <head/> <body> <center> <canvas id="canvas" width="500" height="500"></canvas> </center> <script> var zoomIntensity = 0.1; var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var width = canvas.clientWidth; var height = canvas.clientHeight; var scale = 1; var orgnx = 0; var orgny = 0; var visibleWidth = width; var visibleHeight = height; // 新增拖拽状态变量 var isDragging = false; var lastX = 0; var lastY = 0; draw(); function draw() { // 每次重绘先重置变换矩阵,避免累积误差 context.setTransform(1, 0, 0, 1, 0, 0); // 统一应用缩放变换,兼容现有缩放逻辑 context.translate(orgnx, orgny); context.scale(scale, scale); context.translate(-orgnx, -orgny); context.fillStyle = "white"; context.fillRect(orgnx, orgny, width / scale, height / scale); context.fillStyle = "green"; context.fillRect(250,50,100,100); } canvas.onwheel = function(event) { event.preventDefault(); var x = event.clientX - canvas.offsetLeft; var y = event.clientY - canvas.offsetTop; var scroll = event.deltaY < 0 ? 1 : -2; var zoom = Math.exp(scroll * zoomIntensity); orgnx -= x / (scale * zoom) - x / scale; orgny -= y / (scale * zoom) - y / scale; // Updating scale and visisble width and height scale *= zoom; visibleWidth = width / scale; visibleHeight = height / scale; draw(); } // 新增鼠标按下事件 canvas.onmousedown = function(event) { isDragging = true; lastX = event.clientX - canvas.offsetLeft; lastY = event.clientY - canvas.offsetTop; } // 新增鼠标移动事件 canvas.onmousemove = function(event) { if (!isDragging) return; var currentX = event.clientX - canvas.offsetLeft; var currentY = event.clientY - canvas.offsetTop; // 计算像素偏移,换算为画布坐标偏移 var deltaX = (currentX - lastX) / scale; var deltaY = (currentY - lastY) / scale; // 更新原点 orgnx -= deltaX; orgny -= deltaY; // 更新上一次坐标 lastX = currentX; lastY = currentY; draw(); } // 新增鼠标抬起/离开事件,关闭拖拽 canvas.onmouseup = function() { isDragging = false; } canvas.onmouseout = function() { isDragging = false; } </script> </body> </html>
内容的提问来源于stack exchange,提问作者ammar26
相关产品推荐
相关产品推荐

