物理动画简介
物理动画,简单来说,就是模拟现实世界的一种动画效果。
要实现Canvas动画,实际上只有两步:
- 使用clearRect()方法,清除
- 使用requeatAnimationFrame()方法,重绘
三角函数
- 常见的三角函数:正弦函数(sinθ)、余弦函数(cosθ)、正切函数(tanθ)
- 常见的三角函数对应的JavaScript:
- sinθ:Math.sin(θ*Math.PI/180)
- cosθ:Math.cos(θ*Math.PI/180)
- tanθ:Math.tan(θ*Math.PI/180)
- arcsin(x/R):Math.asin(x/R)*(180/Math.PI)
- arccos(x/R):Math.acos(x/R)*(180/Math.PI)
- arctan(x/R):Math.atan(x/R)*(180/Math.PI)
- 在Canvas中,凡是涉及到角度,全部采用‘弧度制’表示,研发中常用:度数*Math.PI,一目了然
- 再次强调,Canvas使用的W3C坐标系,不是数学坐标系
Math.atan()与Math.atan2()
- Math.atan()方法存在的问题
Math.atan()反正切函数存在一个问题就是:无法区分角的象限,举个例子:
这四个角的tan值分别如下
tan(A) = -0.5
tan(B) = 0.5
tan(C) = -0.5
tan(D) = 0.5
用图像更好理解一些,下面是一段截取出来的y=tanx的图像的一部分(-π,π)部分
在这个图像中,任意画一条横线,与图像至少有两个交点,换句话说,在-180度到180度之间,一个tan值对应两个角度
这时候就要用到另一个反正切函数:Math.atan2(y,x)
- Math.atan2(y,x)
注意:Math.atan2(y,x)的参数顺序,y表示对边的边长,x表示邻边的边长,且x、y要区分正负
- 返回值:-PI 到 PI 之间的值,是从 X 轴正向逆时针旋转到点 (x,y) 时经过的角度。
- 不过我个人更喜欢记忆成:顺时针为正,逆时针为负
- 也就是从x轴正向向上逆时针旋转形成的角度,该方法分求值均为负数,顺时针则为正数
- 在实际开发中,使用:Math.atan2(y,x)方法比Math.atan()方法更多一些
三角函数应用
在Canvas中,三角函数常见的用途有三个
- 两点间的距离:本质是使用勾股定理
- 圆周运动
- 波形运动
圆周运动
- Canvas中圆周运动共有两种形式:正圆运动和椭圆运动
- 通过圆的标准方程,可以得到圆上任意一点的坐标如下
- 通过椭圆的标准方程,可以得到椭圆上任意一点的坐标如下
x = centerX + Math.cos(angle)*radiusX;
y = centerY + Math.sin(angle)*radiusY;
正圆和椭圆的不同之处在于:正圆的半径在x轴和y轴两个方向是相同的,但是椭圆的半径在两个方向上是不同的
波形运动
- 正弦函数和余弦函数的波形都是很像的,因此以正弦函数为例
- 在Canvas中,根据正弦函数作用对象的不同,常见的波形运动可以分为3种:
- 作用于X轴坐标:物体左右摇摆,类似于水草在水流中左右摇摆
- 作用于Y轴坐标:物体的运动轨迹刚好就是正弦函数的波形
- 作用于缩放属性
作用于X轴坐标
参考语法:
x = centerX + Math.sin(angle) * range
angle += speed
(centerX,centerY)表示物体中心坐标
angle表示角度
range表示振幅
speed表示角度改变的速度
作用于Y轴坐标
参考语法:
y = centerY + Math.sin(angle) * range
angle += speed
(centerX,centerY)表示物体中心坐标
angle表示角度
range表示振幅
speed表示角度改变的速度
作用于缩放属性
当正弦函数作用于物体的缩放属性时,物体会不断的放大然后缩小,从而呈现一种脉冲动画效果
参考语法:
scaleX = 1 + Math.sin(angle) * range
scaleY = 1 + Math.sin(angle) * range
angle += speed
scaleX表示物体在X轴方向缩放的倍数
scaleY表示物体在Y轴方向缩放的倍数
angle表示角度
range表示振幅
speed表示角度改变的大小
匀速运动
匀速运动
- 误区点1:匀速运动和匀速圆周运动
匀速运动又称为匀速直线运动,是指物体仔一条直线上运动,并且在单位时间内位移的距离是相等的,即匀速运动需要具备两个条件:
- 速度大小相等
- 速度方向相等
匀速运动是一种加速度为零的运动,匀速圆周运动不是匀速运动,因为速度是矢量,有方向,匀速圆周运动的速度方向是一直在改变的,匀速圆周运动是匀速率圆周运动,并不是匀速运动
- 参考语法:
object.x += vx
object.y += vy
object.x表示物体x轴坐标,vx表示物体在x轴方向上的速度,注意,速度是矢量,需要区分方向,我们可以用正数表示正方向,负数表示负方向。
再次强调,Canvas使用的是W3C坐标系,y轴正方向向下
速度的合成与分解
采用矢量分解与合成方法,计算采用三角函数
vx = speed * Math.cos(angle * Math.PI/180);
vy = speed * Math.sin(angle * Math.PI/180);
object.x += vx;
object.y += vy;
加速运动
- 加速运动,指的是方向相同、速度大小变化的运动。速度递增的是加速运动,速度递减的是减速运动。
- 加速运动分为两种:匀加速运动和变加速运动。
- 匀速运动和加速运动的比较
右图展现了一种匀加速运动,取图像上任意一段,Δv/Δt的值恒定不变,即加速度恒定不变,因为v是矢量,所以加速度a也是矢量,存在方向
- 加速度的合成和分解,参考速度的合成与分解
重力
- 重力加速度:重力加速度是加速度的一种,方向永远垂直向下,指向地心,重力加速度的实质就是物体受地心引力形成的
Canvas动画循环注意事项:
- 对于需要不断改变的变量,一般在动画循环之前定义
- 对于需要不断改变的变量,一般在动画循环中图形绘制之后才递增或者递减
摩擦力
- 摩擦力,指的是阻碍物体相对运动的力。其中摩擦力的方向与物体相对运动的方向相反。摩擦力只会改变速度的大小而不会改变它的方向
- 参考语法
vx *= friction;
vy *= friction;
object.x += vx;
object.y += vy;
friction就是摩擦系数