canvas镜像渲染有坐标系变换(scale+translate)和像素重排(imagedata)两种方式:前者开销小适合实时绘制,后者精确可控适用于导出或滤镜;css翻转仅作用于渲染层,不干预canvas逻辑。

Canvas实现画布镜像渲染,核心是控制绘图上下文的坐标系或像素数据。两种主流方式:变换坐标系(scale + translate) 和 手动重排像素(ImageData),适用场景不同,选对方法能避免错位、跨域或性能问题。
用scale()配合translate做坐标系镜像
这是最常用、开销最小的方式,适合实时绘制和简单翻转。
- 水平镜像:先平移原点到画布右边界,再x轴缩放-1 ——
ctx.translate(width, 0); ctx.scale(-1, 1); - 垂直镜像:先平移原点到底边,再y轴缩放-1 ——
ctx.translate(0, height); ctx.scale(1, -1); - 中心点镜像:先移到中心,缩放,再移回 ——
ctx.translate(cx, cy); ctx.scale(-1, -1); ctx.translate(-cx, -cy); - 注意每次翻转后要调用
ctx.setTransform(1, 0, 0, 1, 0, 0)重置变换,否则后续绘图会叠加变形
用ImageData手动重排像素实现精确镜像
当需要导出翻转后的图像、叠加滤镜、或规避坐标系翻转导致的文字反向/阴影偏移时,该方式更可控。
- 水平翻转:对每行像素,把第
j列复制到w - j - 1列位置,RGBA四通道逐个赋值 - 垂直翻转:把第
i行复制到h - i - 1行,行内像素顺序不变 - 复用
createImageData(w, h)避免重复创建对象;用putImageData()渲染前确保数据已填满 - 若图像来自跨域资源,需提前设置
img.crossOrigin = "anonymous",否则读取像素会报错
CSS辅助方案:适用于静态图片展示
如果只是让或
- 水平翻转:
transform: scaleX(-1);(兼容性好,IE也支持filter: FlipH) - 垂直翻转:
transform: scaleY(-1);或transform: rotateX(180deg) - 注意:CSS翻转不影响Canvas内部绘制逻辑,仅作用于元素渲染层
常见陷阱与应对
镜像看似简单,但几个细节容易引发白屏、错位或模糊:
- scale负值后未平移 → 图形被翻到画布外,看不见
- 文字使用scale(-1, 1)后左右颠倒 → 可改用rotateY(180deg)或在翻转前调整文本锚点
- 多次叠加scale导致浮点误差累积 → 每次操作前用
setTransform()清除状态 - requestAnimationFrame中频繁创建ImageData → 改为复用已有实例,减少GC压力











