canvas 的 scale() 方法缩放整个坐标系而非仅图片,使后续绘制的位置、尺寸、线宽、字体等均按比例变化;其核心是重定义“1单位”对应的像素值,并需配合 translate 和 save/restore 精确控制缩放中心与镜像轴。

Canvas 的 scale() 方法不是放大图片,而是缩放整个坐标系——后续所有绘制操作(位置、尺寸、线宽、字体大小)都会按比例变化。理解这一点,才能避免图形错位、文字模糊、鼠标坐标失准等问题。
scale 的核心作用是重定义“1个单位”代表多少像素
默认情况下,画布上 1 单位 = 1 像素。调用 ctx.scale(2, 1.5) 后,x 方向 1 单位变成 2 像素,y 方向 1 单位变成 1.5 像素。这意味着:
- 原本在
(10, 20)绘制的点,现在实际出现在屏幕的(20, 30)位置 - 画一条
1px宽的线,会显示为2px宽(x 方向缩放影响线宽) -
fillText("A", 50, 50)中的坐标和字体大小全被放大,文字可能变粗、锯齿明显
负值 scale 实现镜像,但必须配合 translate 调整原点
单独用 scale(-1, 1) 会让图形水平翻转,但因原点仍在左上角,图形大概率被翻到画布外。正确做法是先移动原点到对称轴,再缩放,最后移回:
- 以画布右边界为轴水平镜像:
ctx.translate(canvas.width, 0); ctx.scale(-1, 1); - 以画布中心为轴双向镜像:
ctx.translate(centerX, centerY); ctx.scale(-1, -1); ctx.translate(-centerX, -centerY); - 镜像后绘制图片或路径,建议用
save()/restore()隔离状态,避免影响其他内容
控制缩放中心点的关键:平移–缩放–反向平移
默认缩放围绕画布左上角(0, 0)。若想以某点(如鼠标位置或图形中心)为锚点缩放,必须手动调整坐标系:
- 用
ctx.translate(x, y)把原点移到目标中心点 - 执行
ctx.scale(sx, sy) - 再用
ctx.translate(-x, -y)把原点移回 - 整个过程建议包裹在
save()和restore()中,防止状态污染
常见陷阱与应对方式
缩放容易引发意料之外的问题,尤其在交互场景中:
- 多次
scale()会累积(如scale(2)再scale(0.5)不一定还原,浮点误差可能导致微小偏移)——优先用setTransform(1, 0, 0, 1, 0, 0)重置变换矩阵 - 放大位图时出现模糊——改用高分辨率图像源,或结合 CSS
image-rendering: crisp-edges控制渲染质量 - 鼠标点击坐标需逆变换——屏幕坐标除以当前缩放系数,再减去平移偏移,才能映射回原始逻辑坐标
- 文字缩放易失真——复杂文本建议用 CSS 层覆盖,或使用矢量字体 +
measureText动态适配











