在上一节咱们介绍了canvas动画中有关三角函数的内容,以及一个跟随鼠标旋转的箭头动画。这一节主要介绍三角函数的波形运动。包括:html
平滑运动canvas
线性运动bash
脉冲运动dom
sin函数的波形想必骚年们不会感到陌生,其图形以下所示:函数
若是想要取得sin
函数在[0, 2π]之间的值,非连续的状况下,能够这样估算。动画
for(var angle=0; angle<Math.PI*2; angle+=0.1){ console.log(Math.sin(angle)); //打印出角度对应的sin值 }
首先介绍Math.sin(angle)
的第一个应用——平滑运动。this
平滑是指物体一种流畅的运动状态,与之相反的是机械式的简单的从0到1再到-1和0的这么一种状态。平滑的运动更加趋近与天然的运动状态,相似水草在水流中的左右摇摆,在摆动的过程当中是有速度的变化的。spa
咱们用Math.sin
函数模仿的第一个运动,就是这种相似水草摆动的运动。另外,由于sin
函数的值介于[-1,1]之间。因此在实际代码中须要乘以一个较大的值(也就是振幅,你懂得),使其的摆动看起来明显一些。水草摆动的以下图所示,在线演示地址。prototype
具体代码以下rest
//水草类 function Aqu(color, num, amp){ this.startPoint = []; this.endPointX = []; this.endPointY = []; this.amp = []; this.beta = 0; this.color = (color == undefined)?"#3b154e":color; this.num = (num == undefined)?80:num; } Aqu.prototype.init = function(){ for(var i=0; i<this.num; i++){ this.startPoint[i] = Math.random()*20 + i*10; this.endPointX[i] = this.startPoint[i]; this.endPointY[i] = canvas.height/1.5 - Math.random()*50; this.amp[i] = Math.random()*10 + 40; } } Aqu.prototype.draw = function(ctx){ ctx.save(); ctx.lineWidth = 14; ctx.lineCap = "round"; ctx.globalAlpha = 0.8; ctx.strokeStyle =this.color; //Math.sin的应用 this.beta += del*0.0012; var l = Math.sin(this.beta); for(var i=0; i<this.num; i++){ ctx.beginPath(); ctx.moveTo(this.startPoint[i], canvas.height); //周期性改变水草的顶点X坐标 this.endPointX[i] = this.startPoint[i] + l*this.amp[i] ctx.quadraticCurveTo(this.startPoint[i],canvas.height-120,this.endPointX[i],this.endPointY[i]); ctx.stroke(); } ctx.restore(); } var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'); canvas.height = 400; canvas.width = 800; //实例水草 var oAqu = new Aqu(); //初始化 oAqu.init(); var oldTime = new Date().getTime(), del = null, newTime = null; (function drawFrmae(){ window.requestAnimationFrame(drawFrmae); ctx.clearRect(0, 0, canvas.width, canvas.height); newTime = new Date().getTime(); del = new Date().getTime() - oldTime; oldTime = newTime; oAqu.draw(ctx); }())
相比于机械的加减是否是更加的流畅呢?固然,你也经过改变Math.sin(this.beta)中的递增角度值,控制摆动的速度。
线性运动是最简单的一种运动,物体匀速朝某个方向运动,就是线性运动。
原理很简单,具体代码请查看linear-vertical-motion.html
<script> window.onload = function(){ var canvas = document.getElementById('canvas'), context = canvas.getContext('2d'); var angle = 0, range = 50, xspeed = 1, yspeed = 0.05; var ball = new Ball(); (function drawFrame(){ window.requestAnimationFrame(drawFrame,canvas); context.clearRect(0,0,canvas.width,canvas.height); ball.x += xspeed; //水平,沿x轴方向水平运动 if(ball.x > canvas.width + ball.radius){ ball.x = -ball.radius; } //垂直, 因为angle角度没发生变化,因此纵坐标保持不变 ball.y = canvas.height/2+Math.sin(angle)*range; // angle += 0.05; //取消注释看看发生了什么? ball.draw(context); })(); } </script>
其实,这里若是你把angle += 0.05
的注释取消,你会发现球的运动轨迹就与sin函数的图像一致了。
除了做用于物体的速度,sin函数仍然能够做用于物体的大小变化。脉冲运动即是将sin函数运用于物体大小的变化中。
具体代码以下,详细代码请查看plusing-motion.html
window.onload = function(){ var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var angle = 0, range = 0.5, speed = 0.05, centerScale = 1; var ball = new Ball(); ball.x = canvas.width/2; ball.y = canvas.height/2; (function drawFrame(){ window.requestAnimationFrame(drawFrame,canvas); context.clearRect(0,0,canvas.width,canvas.height); //sin值的变化,致使 ball.scaleX , ball.scaleY属性变化 ball.scaleX = ball.scaleY = centerScale + Math.sin(angle)*range; angle += speed; ball.draw(context); })(); }
由此你应该知道,除了位置属性,咱们还能够将sin函数与其余的属性相结合,来造成不一样的运动形式。