如何使用requestAnimationFrame实现矩形循环旋转动画?
实现Canvas矩形循环旋转动画
我来帮你搞定这个循环旋转的动画效果!你的基础代码已经具备了旋转的核心逻辑,只需要补上requestAnimationFrame的循环控制逻辑,让角度持续更新并循环重绘画面就可以了。
问题分析
原代码只绘制了一次固定角度的旋转矩形,没有实现角度的动态变化和画面的持续重绘,所以看不到动画效果。我们需要补充以下关键环节:
- 一个跟踪当前旋转角度的变量
- 由
requestAnimationFrame驱动的循环函数 - 每次循环更新角度后,完整重绘画布(避免残留绘制痕迹)
- 角度超出360度时重置,实现循环效果
修改后的完整代码
const canvas = document.getElementById("canvas") const ctx = canvas.getContext('2d') const width = canvas.width const height = canvas.height const backgroundColor = '#c35033' const overlayColor = '#bcddda' // 定义当前旋转角度,初始值设为0 let currentAngle = 0; // 启动动画循环 requestAnimationFrame(animate); function animate() { // 1. 先清除画布并重绘背景,避免旋转轨迹残留 fillRectangle(ctx, backgroundColor, 0, 0, width, height); // 2. 更新旋转角度:每次增加0.05弧度(可调整数值控制旋转速度) currentAngle += 0.05; // 3. 角度循环:超过2π(对应360度)时重置为0 if (currentAngle > Math.PI * 2) { currentAngle = 0; } // 4. 绘制当前角度的青色旋转矩形 fillSemiTransparentOverlay(currentAngle, width, overlayColor); // 5. 递归调用,让动画持续运行 requestAnimationFrame(animate); } function fillSemiTransparentOverlay(angle, width, overlayColor) { ctx.save() ctx.translate(width / 2, width / 2) ctx.rotate(angle) ctx.translate(-width / 2, -width / 2) ctx.fillStyle = overlayColor ctx.fillRect(-width * (3 / 2), -width / 2, width * 2, width * 2) ctx.restore() } function fillRectangle(context, color, x, y, width, height) { context.fillStyle = color context.fillRect(x, y, width, height) }
<canvas id="canvas" width="500" height="500" />
关键细节解释
- 角度动态更新:用
currentAngle变量记录当前旋转状态,每次循环增加一个小弧度值,数值越大旋转速度越快。 - 画布重绘逻辑:每次动画循环都要先重绘背景,否则旋转的矩形会在画布上留下连续轨迹,导致画面混乱。
- 循环角度控制:当角度超过
Math.PI * 2(对应360度)时重置为0,确保旋转动作无限循环。 - requestAnimationFrame优势:通过递归调用
animate函数,让浏览器以设备最优帧率(通常60fps)执行动画,比setInterval更流畅且更节省系统资源。
可选优化:基于时间的速度控制
如果想让旋转速度在不同帧率的设备上保持一致,可以改用时间差计算角度增量:
// 在animate函数外记录起始时间 let lastTime = 0; function animate(timestamp) { // 计算两次调用的时间差 const deltaTime = timestamp - lastTime; lastTime = timestamp; // 基于时间更新角度:比如每秒旋转π弧度(180度) currentAngle += (Math.PI / 1000) * deltaTime; // ... 其他代码保持不变 }
内容的提问来源于stack exchange,提问作者user9944766
相关产品推荐
相关产品推荐

