0

0

如何用 HTML Canvas 绘制并动画化一个“摇晃铃铛”图标

心靈之曲

心靈之曲

发布时间:2026-03-13 09:16:03

|

809人浏览过

|

来源于php中文网

原创

本文详解如何在 html canvas 中手绘铃铛轮廓,并通过分离钟体与钟舌(clapper)实现逼真的“ ringing ”动画效果:钟舌沿弧线摆动,钟体轻微旋转,无需依赖外部图片资源。

本文详解如何在 html canvas 中手绘铃铛轮廓,并通过分离钟体与钟舌(clapper)实现逼真的“ ringing ”动画效果:钟舌沿弧线摆动,钟体轻微旋转,无需依赖外部图片资源。

要实现一个视觉可信、性能可控的“铃铛摇晃”动画,关键不在于简单位移或缩放整张图片,而在于语义化拆解结构:将铃铛视为两个独立运动部件——静态/微旋的钟体(dome)周期性摆动的钟舌(clapper)。这种分离建模既符合物理直觉,也便于精准控制动画节奏与幅度。

以下是一个完全基于 Canvas 2D API 的纯代码实现(不依赖外部 PNG),包含可复用的铃铛矢量绘制逻辑和自然摆动动画:

<canvas id="canvas" width="400" height="400"></canvas>
<style>
  #canvas { border: 1px solid #eee; display: block; margin: 20px auto; }
</style>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// 铃铛核心参数(单位:像素)
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const domeRadius = 80;
const clapperLength = 65;
const clapperWidth = 8;
const clapperRadius = 12; // 钟舌末端圆球半径

// 摆动相位(0 ~ 1),用于正弦插值
let phase = 0;
const phaseSpeed = 0.03;

function drawBell() {
  // 清空画布
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // === 绘制钟体(dome)===
  ctx.save();
  // 微小旋转模拟震动感(±3°)
  const domeRotation = Math.sin(phase * 3) * 0.05;
  ctx.translate(centerX, centerY);
  ctx.rotate(domeRotation);
  ctx.translate(-centerX, -centerY);

  // 钟体:上半圆 + 两侧竖线 + 底部弧线
  ctx.beginPath();
  ctx.arc(centerX, centerY - 15, domeRadius, Math.PI, 0, false); // 上半圆顶
  ctx.lineTo(centerX + domeRadius, centerY + 30);
  ctx.bezierCurveTo(
    centerX + domeRadius * 0.8, centerY + 50,
    centerX - domeRadius * 0.8, centerY + 50,
    centerX - domeRadius, centerY + 30
  );
  ctx.closePath();
  ctx.fillStyle = '#f5f5f5';
  ctx.fill();
  ctx.strokeStyle = '#aaa';
  ctx.lineWidth = 2;
  ctx.stroke();

  // 钟体高光
  ctx.beginPath();
  ctx.ellipse(centerX - 20, centerY - 30, 12, 6, 0, 0, Math.PI * 2);
  ctx.fillStyle = 'rgba(255,255,255,0.7)';
  ctx.fill();

  ctx.restore();

  // === 绘制钟舌(clapper)===
  const swingAngle = Math.sin(phase * 4) * 0.4; // 摆幅 ±23°
  const clapperX = centerX + Math.sin(swingAngle) * clapperLength * 0.7;
  const clapperY = centerY + 20 + Math.cos(swingAngle) * clapperLength * 0.7;

  // 钟舌杆(带透视倾斜)
  ctx.save();
  ctx.translate(clapperX, clapperY);
  ctx.rotate(swingAngle);
  ctx.beginPath();
  ctx.rect(-clapperWidth / 2, 0, clapperWidth, clapperLength);
  ctx.fillStyle = '#888';
  ctx.fill();
  ctx.restore();

  // 钟舌末端圆球
  ctx.beginPath();
  ctx.arc(
    centerX + Math.sin(swingAngle) * clapperLength,
    centerY + 20 + Math.cos(swingAngle) * clapperLength,
    clapperRadius,
    0,
    Math.PI * 2
  );
  ctx.fillStyle = '#555';
  ctx.fill();
}

function animate() {
  phase += phaseSpeed;
  drawBell();
  requestAnimationFrame(animate);
}

// 启动动画
animate();
</script>

关键设计说明

  • 钟体微旋:使用 Math.sin(phase * 3) 生成高频小幅旋转(±0.05 弧度),模拟金属共振震动,避免生硬平移;
  • 钟舌摆动:以正弦函数驱动角度变化,再通过三角函数计算末端坐标,确保轨迹为自然圆弧;
  • 视觉增强:添加高光椭圆、灰阶渐变填充、抗锯齿描边,显著提升图标质感;
  • 零依赖:全部图形由路径(arc, bezierCurveTo, rect)动态生成,无外部图片请求,加载即用。

⚠️ 注意事项

Joker AIx
Joker AIx

一站式AI创意生产平台,覆盖图像、视频、音频、文案全品类创作

下载

立即学习前端免费学习笔记(深入)”;

  • 若需适配响应式尺寸,请在 resize 事件中重设 canvas.width/height 并重新计算所有相对坐标(避免仅用 CSS 缩放 canvas,会导致模糊);
  • 摆动频率(phaseSpeed)建议控制在 0.02–0.05 区间,过快易引发视觉疲劳,过慢则失去“ringing”即时感;
  • 如需多铃铛实例,应将绘图逻辑封装为类(如 class Bell { constructor(x,y) { ... } render() { ... } }),避免全局变量污染。

通过结构化建模与数学驱动动画,你不仅能实现一个生动的铃铛图标,更掌握了一种可迁移的 Canvas 动效设计范式:拆解物理对象 → 映射运动模型 → 用几何与三角函数实现 → 分层渲染合成

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

95

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

106

2025.09.18

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

891

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

32

2025.12.06

html5动画制作有哪些制作方法
html5动画制作有哪些制作方法

html5动画制作方法有使用CSS3动画、使用JavaScript动画库、使用HTML5 Canvas等。想了解更多html5动画制作方法相关内容,可以阅读本专题下面的文章。

550

2023.10.23

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

1

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

41

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

171

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

50

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号