Canvas物理动画

449 阅读5分钟

物理动画简介

物理动画,简单来说,就是模拟现实世界的一种动画效果。

要实现Canvas动画,实际上只有两步:

  1. 使用clearRect()方法,清除
  2. 使用requeatAnimationFrame()方法,重绘

三角函数

图片1.png

  1. 常见的三角函数:正弦函数(sinθ)、余弦函数(cosθ)、正切函数(tanθ)
  2. 常见的三角函数对应的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)
  1. 在Canvas中,凡是涉及到角度,全部采用‘弧度制’表示,研发中常用:度数*Math.PI,一目了然
  2. 再次强调,Canvas使用的W3C坐标系,不是数学坐标系

Math.atan()与Math.atan2()

  1. Math.atan()方法存在的问题

Math.atan()反正切函数存在一个问题就是:无法区分角的象限,举个例子:

图片2.png

这四个角的tan值分别如下

tan(A) = -0.5

tan(B) = 0.5

tan(C) = -0.5

tan(D) = 0.5

用图像更好理解一些,下面是一段截取出来的y=tanx的图像的一部分(-π,π)部分

AD4CA46B-3770-4F6C-A984-FE0262E44B0B.png

在这个图像中,任意画一条横线,与图像至少有两个交点,换句话说,在-180度到180度之间,一个tan值对应两个角度

这时候就要用到另一个反正切函数:Math.atan2(y,x)

  1. 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中,三角函数常见的用途有三个

  • 两点间的距离:本质是使用勾股定理
  • 圆周运动
  • 波形运动

圆周运动

  1. Canvas中圆周运动共有两种形式:正圆运动和椭圆运动
  2. 通过圆的标准方程,可以得到圆上任意一点的坐标如下

lADPDhYBQQWoXi3NAnzNBP8_1279_636.jpg_720x720g.jpg

  1. 通过椭圆的标准方程,可以得到椭圆上任意一点的坐标如下

x = centerX + Math.cos(angle)*radiusX;

y = centerY + Math.sin(angle)*radiusY;

图片1 (1).png

正圆和椭圆的不同之处在于:正圆的半径在x轴和y轴两个方向是相同的,但是椭圆的半径在两个方向上是不同的

波形运动

  1. 正弦函数和余弦函数的波形都是很像的,因此以正弦函数为例
  2. 在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. 误区点1:匀速运动和匀速圆周运动
    匀速运动又称为匀速直线运动,是指物体仔一条直线上运动,并且在单位时间内位移的距离是相等的,即匀速运动需要具备两个条件:
  • 速度大小相等
  • 速度方向相等
    匀速运动是一种加速度为零的运动,匀速圆周运动不是匀速运动,因为速度是矢量,有方向,匀速圆周运动的速度方向是一直在改变的,匀速圆周运动是匀速率圆周运动,并不是匀速运动
  1. 参考语法:
object.x += vx
object.y += vy

object.x表示物体x轴坐标,vx表示物体在x轴方向上的速度,注意,速度是矢量,需要区分方向,我们可以用正数表示正方向,负数表示负方向。

再次强调,Canvas使用的是W3C坐标系,y轴正方向向下

速度的合成与分解

采用矢量分解与合成方法,计算采用三角函数

图片1 (2).png

vx = speed * Math.cos(angle * Math.PI/180);
vy = speed * Math.sin(angle * Math.PI/180);
object.x += vx;
object.y += vy;

加速运动

  1. 加速运动,指的是方向相同、速度大小变化的运动。速度递增的是加速运动,速度递减的是减速运动。
  2. 加速运动分为两种:匀加速运动和变加速运动。
  3. 匀速运动和加速运动的比较

图片2 (1).png

右图展现了一种匀加速运动,取图像上任意一段,Δv/Δt的值恒定不变,即加速度恒定不变,因为v是矢量,所以加速度a也是矢量,存在方向

  1. 加速度的合成和分解,参考速度的合成与分解

重力

  1. 重力加速度:重力加速度是加速度的一种,方向永远垂直向下,指向地心,重力加速度的实质就是物体受地心引力形成的

Canvas动画循环注意事项:

  1. 对于需要不断改变的变量,一般在动画循环之前定义
  2. 对于需要不断改变的变量,一般在动画循环中图形绘制之后才递增或者递减

摩擦力

  1. 摩擦力,指的是阻碍物体相对运动的力。其中摩擦力的方向与物体相对运动的方向相反。摩擦力只会改变速度的大小而不会改变它的方向
  2. 参考语法
vx *= friction;
vy *= friction;
object.x += vx;
object.y += vy;

friction就是摩擦系数