Canvas视图缩放/平移通过context变换矩阵实现:scale()改变坐标单位,translate()移动坐标系原点;需手动处理鼠标坐标反向变换、文字线条缩放及状态管理。

Canvas 本身没有内置的“视图缩放/平移”概念,所有变换都通过 context 的变换矩阵实现。核心是用 scale() 和 translate() 操作绘图上下文,配合坐标系理解——缩放和平移影响的是后续所有绘制操作的坐标解释方式,不是直接移动画布像素。
缩放:用 scale(sx, sy) 改变单位长度
调用 ctx.scale(2, 2) 后,原来画一个宽 10px 的矩形,实际会渲染成 20px 宽;所有坐标(x、y)、尺寸(width、height)都会被乘以对应缩放系数。注意:缩放中心默认是原点 (0, 0),不是画布中心或鼠标位置。
- 若想以某点 (cx, cy) 为中心缩放:先
translate(cx, cy)→ 再scale(sx, sy)→ 最后translate(-cx, -cy) - 多次缩放会叠加:
scale(2); scale(1.5)等价于scale(3) - 缩放后文字、线条粗细也会变,需手动重设
lineWidth或用setTransform()隔离
平移:用 translate(dx, dy) 移动坐标系原点
ctx.translate(100, 50) 表示:从此刻起,(0, 0) 这个“左上角”被挪到了画布上原本的 (100, 50) 处。再画 fillRect(0, 0, 10, 10),实际出现在 (100, 50) 位置。
- 平移不影响图形自身尺寸,只改变绘制起点
- 常与缩放组合使用,例如“拖动画布”本质就是持续修改平移量
- 可用
ctx.getTransform()获取当前变换矩阵,便于记录或恢复
实用技巧:保存/恢复状态 + 手动管理变换
频繁缩放+平移容易混乱,推荐用 save()/restore() 配合显式矩阵控制:
立即学习“Java免费学习笔记(深入)”;
- 每次交互前
ctx.save(),绘制完ctx.restore(),避免累积误差 - 更精确的做法:用
ctx.setTransform(1, 0, 0, 1, 0, 0)重置为初始状态,再按需设置新变换 - 维护独立的
scale和offset = {x, y}变量,绘制时统一应用:ctx.setTransform(scale, 0, 0, scale, offset.x, offset.y);
鼠标坐标要反向变换才能匹配视图
用户点击画布 (clientX, clientY),这个坐标是屏幕像素位置,但你的图形逻辑可能在缩放+平移后的坐标系中。必须把屏幕坐标“转换回”逻辑坐标:
- 获取 canvas 相对于页面的位置:
const rect = canvas.getBoundingClientRect(); - 计算相对于 canvas 左上角的坐标:
const x = clientX - rect.left;const y = clientY - rect.top; - 减去平移量、除以缩放值:
const logicX = (x - offset.x) / scale;const logicY = (y - offset.y) / scale;


















