如何使用JavaScript实现Canvas中笑脸沿圆形边缘旋转?
实现笑脸旋转动画的方案
要实现笑脸的旋转动画,核心是利用Canvas的变换API结合requestAnimationFrame做逐帧渲染,而不是普通的循环。下面是具体实现步骤和完整代码:
核心思路
- 用
requestAnimationFrame创建动画循环,它会根据浏览器刷新频率自动调度帧更新,比setInterval更流畅。 - 使用Canvas的
translate()将坐标系原点移到笑脸中心位置,再用rotate()实现旋转,让笑脸绕自身中心转动。 - 每帧渲染前清空画布,避免留下上一帧的残影。
完整代码实现
HTML部分
<canvas id="smileCanvas" width="400" height="400"></canvas>
JavaScript部分
const canvas = document.getElementById('smileCanvas'); const ctx = canvas.getContext('2d'); // 修改绘制函数,基于原点(0,0)绘制,适配后续变换 function drawSmile() { ctx.fillStyle = "yellow"; ctx.beginPath(); ctx.arc(0, 0, 50, 0, 2 * Math.PI); // 黄色脸盘 ctx.stroke(); ctx.fill(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(0, 0, 20, 0, Math.PI); // 嘴巴 ctx.stroke(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(-20, -20, 10, 0, 2 * Math.PI); // 左眼 ctx.stroke(); ctx.fill(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(20, -20, 10, 0, 2 * Math.PI); // 右眼 ctx.stroke(); ctx.fill(); } let rotationAngle = 0; // 旋转角度初始值 function animate() { // 清空整个画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 保存当前画布状态,隔离变换影响 ctx.save(); // 将坐标系原点移到画布中心(笑脸位置) ctx.translate(canvas.width / 2, canvas.height / 2); // 旋转画布,参数为弧度值 ctx.rotate(rotationAngle); // 绘制笑脸 drawSmile(); // 恢复画布初始状态 ctx.restore(); // 更新旋转角度,每帧转0.05弧度(约2.86度) rotationAngle += 0.05; // 请求下一帧动画 requestAnimationFrame(animate); } // 启动动画 animate();
关键细节说明
- 变换顺序:必须先执行
translate再执行rotate,如果顺序颠倒,笑脸会绕画布原点做圆周运动,而非自身中心旋转。 - 状态管理:
save()和restore()用来隔离每帧的变换操作,防止后续绘制受之前变换的影响。 - 角度单位:Canvas的
rotate()方法只接受弧度值,若想用角度计算,需通过角度 * Math.PI / 180转换为弧度。
内容的提问来源于stack exchange,提问作者Johny Chau
相关产品推荐
相关产品推荐

