Canvas不支持多轴旋转,所有旋转均为XY平面仿射变换;手势需解耦为平移、旋转、缩放三参数并按序应用;绕任意点旋转须先平移原点;图形对齐依赖坐标系重定位与反向变换;应使用setTransform或save/restore避免状态污染。

Canvas 本身不直接支持“多轴旋转”或手势识别——它只是二维绘图表面,所有旋转都基于平面(XY 轴)的仿射变换。所谓“多轴”是视觉错觉或坐标系叠加的结果,实际仍靠 translate、rotate、scale 和矩阵组合实现。关键在于:手势数据需先解析为逻辑参数(如旋转角、缩放系数、偏移量),再映射到 Canvas 变换链中;图形对齐则依赖坐标系原点重定位与绘制坐标的同步调整。
把手势动作拆解为三个独立控制量
真实的手势(比如双指拖拽+旋转+捏合)应解耦为:
-
平移量(dx, dy):由双指中心点位移得出,用于
ctx.translate(dx, dy) -
旋转角(θ):由双指连线角度变化计算,单位弧度,传给
ctx.rotate(θ) -
缩放系数(s):由双指间距比值得出,用于
ctx.scale(s, s)
注意:这三个操作必须按 平移 → 旋转 → 缩放 顺序应用,否则缩放会放大/缩小位移值,造成漂移。建议每次重绘前用 ctx.setTransform(1,0,0,1,0,0) 彻底清空状态,再按序重建变换。
绕任意点旋转必须重设坐标系原点
Canvas 的 rotate() 永远绕当前坐标系原点(默认左上角)旋转,不是图形中心。要让图形“绕自身中心转”,必须:
- 先
ctx.translate(centerX, centerY)把原点移到图形中心 - 再
ctx.rotate(angle) - 最后绘制时,图形坐标以
(0, 0)为基准(例如fillRect(-w/2, -h/2, w, h))
若还需支持“绕画布某点(如手指按压点)旋转”,就在第一步把 translate 的参数换成该点坐标即可,无需手算矩阵。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
图形对齐靠“反向变换”而非反复 rotate
比如实现 2.5D 中精灵始终面向镜头(billboard 效果),不能对每个图像调 rotate()——那样会破坏朝向。正确做法是:只平移,不旋转图像本身。
- 根据相机位置和角度,用三角函数算出该图形在屏幕上的目标坐标
(screenX, screenY) - 用
ctx.drawImage(img, screenX - img.width/2, screenY - img.height/2)居中绘制 - 所有精灵共用同一套屏幕坐标逻辑,自然保持“正对镜头”视觉效果
避免状态污染,用 save/restore 或 setTransform 控制边界
连续手势操作下,变换容易累积出错。推荐两种清理方式:
-
局部隔离:对单个图形绘制前
ctx.save(),绘制后ctx.restore() -
全局重置:每帧开始时用
ctx.setTransform(1, 0, 0, 1, 0, 0)彻底还原,默认单位矩阵
不要依赖多次 rotate() 叠加来模拟复杂旋转——误差会随帧数放大。固定以世界坐标→屏幕坐标的一次性映射为主,变换仅服务于定位,不参与语义逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










