离屏画布、Promise 队列、requestAnimationFrame,这套方案帮你彻底解决 Canvas 旋转过程中画质模糊、旋转错乱、卡顿延迟等常见问题。
目录
🌟 效果演示

注:暂不支持任意角度(非90°倍数)的连续旋转。
1️⃣ 常规写法痛点
常规旋转代码:
ctx.rotate(angle)
ctx.drawImage(img, x, y)
实际踩坑:
❌ 宽高不适配导致图片截断
❌ 瞬间旋转频繁触发闪烁
真实项目中旋转效果👇
-
图片锯齿严重
-
页面一顿一顿的
本套高性能 Canvas 旋转方案,核心亮点:
✅ 离屏画布快照
✅ 自动计算旋转尺寸
✅ Promise 队列避免多次触发冲突
✅ requestAnimationFrame 丝滑渲染
✅支持动态角度旋转,旋转后图像清晰
2️⃣ 方案设计思路
核心原则:
先拍快照 -> 计算旋转尺寸 -> 离屏旋转 -> 主线程绘制
整体思路:
-
snapshot 离屏 Canvas 负责记录当前画布;
-
offscreen 离屏 Canvas 负责旋转后结果;
-
Promise 队列 确保多个旋转顺序执行;
-
requestAnimationFrame 避免旋转阻塞渲染。
3️⃣ 核心方案完整实现
直接上代码,按需 copy👇
3.1 核心类封装
export default class CanvasRotationHelper {
constructor() {
this.snapshot = document.createElement("canvas")
this.snapshotCtx = this.snapshot.getContext("2d")
this.offscreen = document.createElement("canvas")
this.offscreenCtx = this.offscreen.getContext("2d")
this._rotationQueue = Promise.resolve()
}
}
3.2 核心旋转逻辑
-
队列控制:
_rotationQueue.then()保证串行执行旋转,防抖 + 防错乱
rotateCanvas(canvas, degrees) {
this._rotationQueue = this._rotationQueue.then(() => {
return new Promise((resolve, reject) => {
try {
} catch (e) {
reject(e)
}
})
})
return this._rotationQueue
}
-
快照记录:
const ow = canvas.width
const oh = canvas.height
this.snapshot.width = ow
this.snapshot.height = oh
this.snapshotCtx.setTransform(1, 0, 0, 1, 0, 0)
this.snapshotCtx.clearRect(0, 0, ow, oh)
this.snapshotCtx.drawImage(

最低0.47元/天 解锁文章
435

被折叠的 条评论
为什么被折叠?



