返回

让火柴人在 Canvas 上翩翩起舞:用二阶贝塞尔曲线呈现灵动跳绳效果

Android

用 Canvas 和贝塞尔曲线打造栩栩如生的火柴人跳绳动画

绘制一个灵动的火柴人

在 Canvas 画布上勾勒出火柴人,让我们使用二阶贝塞尔曲线来打造流畅、富有表现力的线条。从头部开始,绘制一条曲线连接到身体,然后依次延伸出手臂和双腿,形成一个动作感十足的火柴人。

创造跳动的跳绳

跳绳由两条交叉的直线组成,赋予它动感。利用 JavaScript 的 requestAnimationFrame() 方法,不断更新火柴人的位置和跳绳的角度,创造出绳子摆动的效果。通过精妙地调整角度和位置,绳子仿佛在空中灵动地飞舞。

让火柴人动起来

现在,火柴人和跳绳都准备就绪,让我们注入生命!通过 JavaScript 动画循环,持续更新火柴人的位置,让它仿佛在跳绳。随着跳绳的摆动,火柴人也随之律动,仿佛在空中轻盈地跳跃。

自定义你的动画

这个动画只是一个起点,你可以根据自己的喜好进行定制。改变火柴人的颜色、跳绳的长度,或者添加背景元素,打造一个属于你自己的独特动画世界。通过发挥你的想象力,创造出无限的可能性。

常见问题解答

  • 如何控制火柴人的跳跃高度?
    调整 dy 变量以更改火柴人的跳跃高度。更高的 dy 值会导致更高的跳跃。
  • 如何改变绳子的速度?
    调整 angle 增量的值以控制绳子的摆动速度。较小的值会产生更慢的摆动。
  • 如何添加背景音乐?
    使用 HTML5 的 <audio> 元素在背景中播放音乐,为你的动画增添额外的趣味性。
  • 如何将动画保存为 GIF?
    使用在线工具或库将动画导出为 GIF 文件,以便轻松地在社交媒体或其他平台上分享。
  • 我可以使用不同的贝塞尔曲线来绘制火柴人吗?
    当然,尝试使用不同的控制点来创建不同的曲线形状,探索各种身体姿态。

结论

通过 Canvas 和二阶贝塞尔曲线,你已经掌握了在网页上创建令人惊叹的火柴人跳绳动画所需的技能。随着你继续练习和探索,你的动画将变得更加复杂和引人入胜,为你的网站或应用程序带来活力。

代码示例:

// HTML
<canvas id="canvas" width="500" height="500"></canvas>

// JavaScript
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 火柴人坐标
let x = 100;
let y = 100;

// 跳绳角度
let angle = 0;

// 运动速度
let dx = 5;
let dy = -5;

// 绘制火柴人
function drawFireman() {
  // 头部
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.quadraticCurveTo(x + 10, y - 15, x + 20, y);
  ctx.stroke();

  // 身体
  ctx.beginPath();
  ctx.moveTo(x + 20, y);
  ctx.quadraticCurveTo(x + 30, y + 10, x + 40, y);
  ctx.stroke();

  // 手臂
  ctx.beginPath();
  ctx.moveTo(x + 20, y);
  ctx.quadraticCurveTo(x + 10, y - 10, x + 20, y - 20);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(x + 40, y);
  ctx.quadraticCurveTo(x + 50, y - 10, x + 40, y - 20);
  ctx.stroke();

  // 腿
  ctx.beginPath();
  ctx.moveTo(x + 20, y);
  ctx.quadraticCurveTo(x + 10, y + 10, x + 20, y + 20);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(x + 40, y);
  ctx.quadraticCurveTo(x + 50, y + 10, x + 40, y + 20);
  ctx.stroke();
}

// 绘制跳绳
function drawRope() {
  // 左绳
  ctx.beginPath();
  ctx.moveTo(x - Math.sin(angle) * 20, y + Math.cos(angle) * 20);
  ctx.lineTo(x + Math.sin(angle) * 20, y + Math.cos(angle) * 20);
  ctx.stroke();

  // 右绳
  ctx.beginPath();
  ctx.moveTo(x + Math.sin(angle) * 20, y + Math.cos(angle) * 20);
  ctx.lineTo(x - Math.sin(angle) * 20, y + Math.cos(angle) * 20);
  ctx.stroke();
}

// 动画循环
function animate() {
  // 清除画布
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 更新火柴人位置
  x += dx;
  y += dy;

  // 更新跳绳角度
  angle += 0.1;

  // 绘制火柴人和跳绳
  drawFireman();
  drawRope();

  // 继续动画循环
  requestAnimationFrame(animate);
}

// 启动动画
animate();