本文介绍如何使用正弦函数(sin)在 html canvas 中实现平滑的往复运动:物体在边界处减速至停止、反向加速通过中点,形成自然的“呼吸式”动画。核心是构造归一化的正弦缓动函数,并结合时间戳驱动位置计算。
本文介绍如何使用正弦函数(sin)在 html canvas 中实现平滑的往复运动:物体在边界处减速至停止、反向加速通过中点,形成自然的“呼吸式”动画。核心是构造归一化的正弦缓动函数,并结合时间戳驱动位置计算。
要让一个圆点在 Canvas 上做正弦式往复运动(即:在左右边界处速度趋近于零,经过中点时速度最快),关键在于用正弦函数映射时间到空间位置,而非简单叠加 sin() 到坐标上(如原代码中的 x * Math.sin(q) 会导致非物理、不可控的震荡)。
我们采用一个标准的正弦缓动函数(ease-in-out sine):
const easeSin = (t) => Math.sin(t - Math.PI / 2) * 0.5 + 0.5;
假设画布宽度足够,我们希望圆点在水平方向于 left = radius 和 right = canvasWidth - radius 之间往复运动(避免超出边界)。则有效运动区间长度为:
const range = canvasWidth - radius * 2;
于是当前 x 坐标可直接通过线性插值得到:
x = radius + ease * range; // ease ∈ [0, 1]
这样,当 ease = 0 → x = radius(左边界);ease = 1 → x = canvasWidth - radius(右边界);而 ease 按正弦规律变化,就自然实现了“慢–快–慢”的加速度曲线。
<canvas width="400" height="200" style="border: 2px solid #333;"></canvas><script> const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); const rad = 20; const y = 100; // 正弦缓动函数:输入时间 t(ms),输出 [0, 1] 的平滑周期值 const easeSin = (t) => Math.sin(t * 0.001 - Math.PI / 2) * 0.5 + 0.5; function motion(time) { const ease = easeSin(time); // 自动随时间循环 const x = rad + ease * (canvas.width - rad * 2); // 清屏 & 绘制 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath(); ctx.fillStyle = "steelblue"; ctx.arc(x, y, rad, 0, Math.PI * 2); ctx.fill(); ctx.closePath(); requestAnimationFrame(motion); } requestAnimationFrame(motion);</script>
? 注意:
- 使用 requestAnimationFrame 的回调参数 time(高精度时间戳,单位毫秒)作为输入,比手动维护 q 或 x 更稳定、无累积误差;
- 时间缩放因子 0.001 控制运动速度(值越小越慢),可按需调整;
- 若需多物体独立运动,可为每个对象维护偏移时间(如 time + offset);
- 此方法本质是参数化运动,完全脱离帧率依赖,动画更精准流畅。
通过这种基于数学函数的驱动方式,你不仅能实现正弦往复,还可轻松切换为 easeInCubic、easeOutElastic 等其他缓动效果——只需替换 easeSin 函数即可。这是现代 Canvas 动画的专业实践基础。
2026阿里开发者评选出的全国最佳教培机构小程序开发工具实测对比:附教培机构小程序制作教程
轻抖app如何实名认证 轻抖实名认证方法
2026全国3款AI/SAAS商城小程序开发工具推荐:附商城小程序开发教程
RFID硬件选型与实操:标签打印机和手持终端:这两个设备选错很麻烦
专访GEO落地工程师罗长才:当静止轨道已然成为技术融合的枢纽
2026年7月全国精选3款AI/SAAS实体店小程序制作工具推荐:附门店小程序制作教程