1. 动画数学基础:坐标系与向量入门

做前端动画这么多年,我越来越觉得数学不是拦路虎,而是工具箱。今天咱们就从最基础的坐标系和向量开始聊。别怕,这些东西说白了就是「在平面上怎么描述一个点,以及这个点怎么动」。

1.1 二维平面坐标系

你想想看,在屏幕上定位一个元素,是不是得告诉浏览器「距离左边多少像素,距离顶部多少像素」?这就是二维坐标系在干活。

二维坐标系由两条互相垂直的轴组成:

  • X轴:水平方向,向右为正方向
  • Y轴:垂直方向,向上为正方向(但在屏幕坐标系中,向下为正)

每个点用 (x, y) 表示。比如 (3, 2) 表示从原点向右走3步,再向上走2步。

重点:屏幕坐标系和数学坐标系不一样。屏幕的Y轴是向下的。我做第一个动画项目时,就因为搞混了这个,小球一直往反方向飞。嗯,调试了半小时才发现。

1.2 向量的基本概念

向量是什么?说白了就是「带箭头的线段」。它有两大属性:

  • 方向:箭头指向哪
  • 大小:线段有多长

在代码里,向量通常用两个数字表示:(dx, dy)。比如 (3, 4) 表示向右移动3,向上移动4。

我的习惯:把向量想象成「位移指令」。你告诉一个点:「往右走3,往上走4」,它就到了新位置。这样理解,动画里的移动就变得很直观。

1.3 向量的加法

向量加法很简单:对应分量相加。

比如:(2, 3) + (1, 4) = (3, 7)

这在动画里有什么用?我举个例子:

  • 一个物体当前速度是 (2, 3)
  • 你给它加一个风力 (1, 4)
  • 最终速度就是 (3, 7)

你看,这就是向量加法的实际应用。我曾经在做一个粒子系统时,用向量加法叠加了重力、风力和初始速度,效果非常自然。

// 向量加法示例
const v1 = { x: 2, y: 3 };
const v2 = { x: 1, y: 4 };
const result = { x: v1.x + v2.x, y: v1.y + v2.y };
// result = { x: 3, y: 7 }

1.4 向量的数乘

数乘就是用一个数字去缩放向量。比如 2 * (3, 4) = (6, 8)

这有什么用?

  • 控制速度大小:速度向量乘以0.5,就减速一半
  • 控制加速度:加速度向量乘以时间步长,得到速度变化量
  • 方向不变,只改变大小

注意:数乘只改变向量的大小,不改变方向(除非乘以负数,方向会反转)。我曾经在做一个缓动动画时,忘了这个细节,结果物体运动方向反了,看起来像被弹回去一样。

// 向量数乘示例
const v = { x: 3, y: 4 };
const scalar = 2;
const result = { x: v.x * scalar, y: v.y * scalar };
// result = { x: 6, y: 8 }

1.5 实战:用向量控制小球运动

咱们来写一个简单的小球运动。用向量表示位置和速度,每帧更新位置。

// 小球运动示例
let position = { x: 100, y: 100 };  // 位置向量
let velocity = { x: 2, y: 3 };      // 速度向量

function update() {
  // 位置 = 位置 + 速度
  position.x += velocity.x;
  position.y += velocity.y;
  
  // 绘制小球
  drawCircle(position.x, position.y, 10);
}

你看,就这么几行代码,小球就开始动了。这就是向量的力量。

避坑指南:我曾经在帧循环里直接修改了速度向量,导致后续计算出错。建议每次更新时,用临时变量保存计算结果,不要直接修改原始向量。

1.6 总结

这一章我们学了:

  • 二维坐标系:描述点的位置
  • 向量:描述方向和大小
  • 向量加法:叠加多个运动
  • 向量数乘:控制运动速度

说白了,向量就是动画的「语言」。你告诉物体怎么走,它就怎么走。下一章我们会深入向量的更多操作,比如点积和叉积,它们在光照和碰撞检测中非常有用。

记住:数学不是背公式,而是理解概念。我做了这么多年动画,最深的体会就是——把数学概念想明白,代码自然就写出来了。