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

如何在HTML Canvas中绘制带摇晃动画的铃铛?

实现Canvas铃铛下半部分的摇晃震动动画

要实现仅铃铛下半部分震动的效果,核心思路是分离固定区域和动画区域,结合Canvas变换API做局部动画,以下是具体实现方案和示例:

实现提示

  • 拆分铃铛绘制:将铃铛分为顶部固定区域(如挂环、上半壳体)和底部动画区域,避免整体移动
  • 利用save()/restore()隔离变换上下文,只对下半部分应用动画,不影响其他绘制内容
  • 用正弦函数生成平滑的周期性偏移/旋转角度,模拟自然摇晃,可添加衰减系数让震动逐渐停止,更贴近真实物理效果

完整示例代码

HTML

<canvas id="canvas"></canvas>

CSS

#canvas {
  border: 1px solid silver;
  width: 100%;
  height: 150px;
}

JavaScript

const canvas = document.getElementById('canvas');
const c = canvas.getContext('2d');
// 设置canvas实际尺寸
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;

const bellImg = new Image();
bellImg.src = "https://png.pngtree.com/png-vector/20190411/ourmid/pngtree-vector-bell-icon-png-image_927119.jpg";

// 动画参数
const baseX = 50;
const baseY = 10;
const bellWidth = 80;
const bellHeight = 100;
// 铃铛上半部分高度(根据实际图片调整)
const fixedPartHeight = 30;
// 摇晃角度相关
let startTime = Date.now();
let shakeAngle = 0;
// 衰减系数,控制震动逐渐减弱
let decay = 0.995;

function drawBell() {
  window.requestAnimationFrame(drawBell);
  
  c.clearRect(0, 0, canvas.width, canvas.height);
  
  // 1. 绘制固定的上半部分(裁剪图片的上半段)
  c.drawImage(
    bellImg,
    0, 0, bellImg.width, bellImg.height * fixedPartHeight / bellHeight,
    baseX, baseY, bellWidth, fixedPartHeight
  );
  
  // 2. 绘制摇晃的下半部分
  c.save();
  // 以铃铛底部连接点为旋转中心
  const rotateCenterX = baseX + bellWidth / 2;
  const rotateCenterY = baseY + fixedPartHeight;
  
  // 计算当前摇晃角度:正弦函数生成周期变化,叠加衰减
  const elapsed = (Date.now() - startTime) / 100;
  shakeAngle = Math.sin(elapsed) * 0.1 * decay;
  decay = decay > 0.01 ? decay : 1; // 衰减到一定程度重置,可改为停止动画
  
  // 应用旋转变换
  c.translate(rotateCenterX, rotateCenterY);
  c.rotate(shakeAngle);
  c.translate(-rotateCenterX, -rotateCenterY);
  
  // 裁剪并绘制铃铛下半部分
  c.drawImage(
    bellImg,
    0, bellImg.height * fixedPartHeight / bellHeight, bellImg.width, bellImg.height * (bellHeight - fixedPartHeight) / bellHeight,
    baseX, baseY + fixedPartHeight, bellWidth, bellHeight - fixedPartHeight
  );
  
  c.restore();
}

// 图片加载完成后启动动画
bellImg.onload = drawBell;

关键代码说明

  • 通过drawImage的裁剪参数,把铃铛图片分成上下两部分分别绘制,上半部分固定,下半部分应用旋转变换
  • 用Date.now()获取时间戳,结合Math.sin()生成周期性的旋转角度,模拟摇晃的自然节奏
  • 加入decay衰减系数,让摇晃幅度逐渐减小,还原真实铃铛摇晃的物理特性
  • save()和restore()确保旋转变换只作用于下半部分,不影响后续绘制

内容的提问来源于stack exchange,提问作者user565

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 16:46:27