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

如何在Canvas中实现图片沿贝塞尔曲线运动并同步路径角度旋转?

实现原理

要实现图片沿二次贝塞尔曲线运动时同步调整朝向,核心是计算路径在当前运动点的切线方向,将图片旋转到和切线方向对齐即可:

  1. 通过二次贝塞尔曲线的导数公式,计算当前运动点的x/y轴方向变化率,使用Math.atan2()得到对应的旋转弧度
  2. 绘制图片前操作Canvas上下文状态:先平移到当前运动点坐标,再按计算出的角度旋转,绘制完成后恢复上下文状态避免影响后续渲染

完整修改后代码

JavaScript 代码

var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');

var statue = new Image();
statue.src = 'https://i.ibb.co/3TvCH8n/liberty.png';

// 计算二次贝塞尔曲线指定百分比位置的坐标
function getQuadraticBezierXYatPercent(startPt, controlPt, endPt, percent) {
  var x =
    Math.pow(1 - percent, 2) * startPt.x +
    2 * (1 - percent) * percent * controlPt.x +
    Math.pow(percent, 2) * endPt.x;
  var y =
    Math.pow(1 - percent, 2) * startPt.y +
    2 * (1 - percent) * percent * controlPt.y +
    Math.pow(percent, 2) * endPt.y;
  return { x: x, y: y };
}

// 新增:计算二次贝塞尔曲线指定百分比位置的切线角度(弧度)
function getQuadraticBezierTangentAtPercent(startPt, controlPt, endPt, percent) {
  const dx = 2 * (1 - percent) * (controlPt.x - startPt.x) + 2 * percent * (endPt.x - controlPt.x);
  const dy = 2 * (1 - percent) * (controlPt.y - startPt.y) + 2 * percent * (endPt.y - controlPt.y);
  return Math.atan2(dy, dx);
}

const startPt = { x: 600, y: 200 };
const controlPt = { x: 300, y: 100 };
const endPt = { x: 0, y: 200 };

var percent = 0;

statue.addEventListener('load', () => {
  animate();
});

function animate() {
  ctx.clearRect(0, 0, c.width, c.height);
  percent > 1 ? (percent = 0) : (percent += 0.003);
  var point = getQuadraticBezierXYatPercent(startPt, controlPt, endPt, percent);
  // 计算当前点的旋转角度
  var rotateAngle = getQuadraticBezierTangentAtPercent(startPt, controlPt, endPt, percent);
  // 如有需要可调整角度偏移,比如rotateAngle += Math.PI / 2适配图片初始朝向

  // 操作上下文状态实现旋转绘制
  ctx.save();
  ctx.translate(point.x, point.y);
  ctx.rotate(rotateAngle);
  ctx.drawImage(
    statue,
    0,
    0,
    statue.width,
    statue.height,
    -50, // 因为已经平移到运动点,只需按图片大小负偏移一半实现中心对齐
    -50,
    100,
    100
  );
  ctx.restore();

  requestAnimationFrame(animate);
}

HTML 代码

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="600" height="200" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

</body>
</html>

路径示意图

路径示意图


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:09:00