You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JavaScript实现Canvas中笑脸沿圆形边缘旋转?

实现笑脸旋转动画的方案

要实现笑脸的旋转动画,核心是利用Canvas的变换API结合requestAnimationFrame做逐帧渲染,而不是普通的循环。下面是具体实现步骤和完整代码:

核心思路

  1. 用requestAnimationFrame创建动画循环,它会根据浏览器刷新频率自动调度帧更新,比setInterval更流畅。
  2. 使用Canvas的translate()将坐标系原点移到笑脸中心位置,再用rotate()实现旋转,让笑脸绕自身中心转动。
  3. 每帧渲染前清空画布,避免留下上一帧的残影。

完整代码实现

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:00:18