javascript动画基础(四)--三角学在动画中的运用(3)

来源:互联网 发布:怎么加入淘宝联盟 编辑:程序博客网 时间:2024/05/17 03:55

前面已经简单介绍了Math.sin,Math.cos和Math.atan2这三个用的最多的三角函数javascript方法,接下来,我们看看sin和cos的取值范围


上面的图很清楚的可以看出,不过不看我相信大家也知道,sin和cos的取值范围在-1和1之间,所以根据上图才有了正弦波和余弦波的说法。

根据正弦和余弦取值范围的这个特性,我们就可以做出很多动画效果,比如呼吸灯的效果,平滑上下运动,心跳效果(脉冲运动),甚至是不规则的运动轨迹都可以,首先来看看简单的平滑上下运动的效果

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title><style>canvas{border: 1px solid #ccc;}</style></head><body><canvas id="myCanvas" width=500 height=500></canvas></body><script>window.onload = function(){var myCanvas = document.getElementById('myCanvas');var ctx = myCanvas.getContext('2d');<span style="color:#ff0000;">var angleSpeed = 0;</span>var x = myCanvas.width/2;var y = myCanvas.height/2;//平滑上下移动的方块(function jump(){setTimeout(jump,1000/60);ctx.clearRect(0,0,myCanvas.width,myCanvas.height);//改变y的值,y值其实在250+50*[-1,1]之间变动,50其实就是波动范围y = myCanvas.height/2 + <span style="color:#ff0000;">Math.sin(angleSpeed)*50</span>;ctx.save()ctx.translate(x,y);ctx.beginPath();ctx.fillStyle = "red";ctx.fillRect(0,0,50,50);ctx.fill();ctx.restore();angleSpeed += 0.1;}());}</script></html>
运行上面的代码,可以看到一个红色的小方块在画布中平滑上下运动。

代码用到了canvas画布的矩阵变换translate(x,y)函数,这里有必须稍微说明一下:

方法描述scale(x,y)缩放当前绘图至更大或更小rotate(弧度)旋转当前绘图translate(x,y)重新映射画布上的 (0,0) 位置transform()替换绘图的当前转换矩阵setTransform()将当前转换重置为单位矩阵。然后运行 transform()
具体的用法大家可以自己实验,不要需要说明一下这个几个矩阵变换API在使用的时候的注意事项

1.  变换方法是对下一次绘图起作用

2.  变换方法变换的整个画布,而不是哪一个图形,所以经常需要配合save()和restore()方法一起使用,这一点很重要

3.  需要注意使用clearRect()方法清除画布

4.  transform方法一共六个参数,1,4参数表示缩放,也就是scale ; 2,3参数表示斜拉skew,这个canvas没有提供单独方法,单独实际情况可以参考css3矩阵变换的skew;5,6参数表示位移,也就是translate;1,2,3,4参数按照cos,sin,-sin,cos 顺序就是旋转,也就是rotate

具体的API使用情况这里就不多做介绍,不过一定要注意第二点,矩阵变换方法变换的是整个画布

ok,上面的注意点如果你知道了,那么,直接跳过


上面的代码只是在y轴做上下的平滑运动,那么再上个列子,来看一下脉冲运动

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>pulse</title><style>canvas{border: 1px solid #ccc;}</style></head><body><canvas id="myCanvas" width=500 height=500></canvas></body><script>window.onload = function(){var myCanvas = document.getElementById('myCanvas');var ctx = myCanvas.getContext('2d');var range = 0.5;//脉冲范围var angleSpeed = 0; //角度变化速度var raduis = 100; //半径//默认缩放大小,这个参数其实是为了让scale(x,y)里面的参数不变为负数var centerScale = 1; var x = myCanvas.width/2;var y = myCanvas.height/2;//脉冲运动(function pulse(){setTimeout(pulse,1000/60);ctx.clearRect(0,0,myCanvas.width,myCanvas.height);ctx.save()ctx.translate(x,y);//注意sin和cos的区别,这里使用sin从小变大,如果你想从大变小,使用cos//Math.sin(angleSpeed)*range 其实变动范围就在[-0.5,0.5]之间了ctx.scale(centerScale + Math.sin(angleSpeed)*range,centerScale + Math.sin(angleSpeed)*range);ctx.beginPath();ctx.fillStyle = "#99CCFF";ctx.arc(0,0,raduis,0,2*Math.PI,false);ctx.fill();ctx.restore();angleSpeed += 0.02;}());}</script></html>

上面代码使用scale()方法,实现了圆的放大变小,但是还是要提醒大家,scale缩放实际上缩放的是画布,是以画布左上的点作为缩放的源点,所以上面代码中ctx.translate(x,y)这一句并不只是简单的把画布移动到中间,还会让scale的缩放依据自身的圆点来做放大缩小

再来看一个随机波动的效果,这个效果就像一只小鸟在画布上飞来飞去。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>RandomWave</title><style>canvas{border: 1px dashed #ccc;background-color: #eee;}</style></head><body><canvas id="myCanvas" width=500 height=500></canvas></body><script>window.onload = function(){var myCanvas = document.getElementById('myCanvas');var ctx = myCanvas.getContext('2d');var range = 50;//脉冲范围var angleSpeedX = 0; //x角度变化速度var angleSpeedY = 0; //y角度变化速度var raduis = 50; //半径var originX = myCanvas.width/2; var originY = myCanvas.height/2;var x = 0;var y = 0;//不规则波形运动(function randomWave(){setTimeout(randomWave,1000/60);ctx.clearRect(0,0,myCanvas.width,myCanvas.height);x = originX + Math.sin(angleSpeedX) * range;y = originY + Math.sin(angleSpeedY) * range;ctx.save();ctx.translate(x,y);ctx.beginPath();ctx.fillStyle = "#FF9966";ctx.arc(0,0,raduis,0,2*Math.PI,false);ctx.fill();ctx.restore();angleSpeedX += 0.05;angleSpeedY += 0.15;}());}</script></html>

虽然叫做随机波动,其实通过数学原理还是可以预测出它的飞行轨迹的,只是看起来好像随机而已,因为上面代码中变化的角度,angleSpeedX,和angleSpeedY都不一样,而且变动使用的都是sin进行变化,但是如果你想想,angleSpeedX,和angleSpeedY变化一样,并且x,y的变化一个使用cos,一个使用sin

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>circleWave</title><style>canvas{border: 1px dashed #ccc;background-color: #eee;}</style></head><body><canvas id="myCanvas" width=500 height=500></canvas></body><script>window.onload = function(){var myCanvas = document.getElementById('myCanvas');var ctx = myCanvas.getContext('2d');var range = 50;//脉冲范围var angleSpeedX = 0; //x角度变化速度var angleSpeedY = 0; //y角度变化速度var raduis = 50; //半径var originX = myCanvas.width/2; var originY = myCanvas.height/2;var x = 0;var y = 0;//圆形轨迹移动(function circleWave(){setTimeout(circleWave,1000/60);ctx.clearRect(0,0,myCanvas.width,myCanvas.height);x = originX + Math.cos(angleSpeedX) * range;y = originY + Math.sin(angleSpeedY) * range;ctx.save();ctx.translate(x,y);ctx.beginPath();ctx.fillStyle = "#FF99CC";ctx.arc(0,0,raduis,0,2*Math.PI,false);ctx.fill();ctx.restore();angleSpeedX += 0.05;angleSpeedY += 0.05;}());}</script></html>

如果上面的代码把originX和originY改成不一样的长度,那么你会发现会出现椭圆轨迹的运动的小圆球

0 0