PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > HTML5+CSS3教程 > 正文

    《html5 canvas动画》 —— 弹性动画

    作者:admin来源:segmentfault浏览:时间:2020-09-30 00:07:50我要评论
    导读:在上一章我们介绍了缓动动画,并且对弹性动画的概念做了简单的介绍。弹性动画(spring)与缓动动画都是基于距离的百分比动画,两者的不同之处...
    在上一章我们介绍了缓动动画,并且对弹性动画的概念做了简单的介绍。弹性动画(spring)与缓动动画都是基于距离的百分比动画,两者的不同之处在于,一个作用于速度(ease), 一个作用于加速度(spring)。弹性动画是动画中相当有用的的一个物理概念,通过它你可以做很多酷炫的效果,本节的主要内容如下:
    1. 简单的弹性动画

    2. 鼠标跟随弹性动画

    3. offset spring

    4. 总结

    1.简单的弹性动画

    之前我们已经说过弹性动画的作用元素是加速度。该加速度的变化基于距离的百分比。有了上一节对缓动动画的理解,想必大家对于我们要做什么应该都一清二楚了。这里我们先做一个基于坐标轴的弹性动画。先上效果图:
    《html5 canvas动画》 —— 弹性动画

    具体代码如下:
     

    1. <canvas id="canvas" width="500" height="500" style="background-color: #000;"
    2.     your browser not support canvas! 
    3. </canvas> 
    4.  
    5. <script type="text/javascript" src="../js/utils.js"></script> 
    6. <script type="text/javascript" src="../js/ball.js"></script> 
    7.    <script> 
    8.        window.onload = function () { 
    9.           var canvas = document.getElementById('canvas'), 
    10.              context = canvas.getContext('2d'), 
    11.              ball = new Ball(), 
    12.              spring = 0.03,  //弹性系数 B5教程网 www.bcty365.com 
    13.              targetX = canvas.width / 2,  //目标位置 
    14.              f = 0.95, 
    15.              vx = 0;  
    16.  
    17.              ball.y = canvas.height / 2; 
    18.  
    19.       (function drawFrame () { 
    20.         window.requestAnimationFrame(drawFrame, canvas); 
    21.         context.clearRect(0, 0, canvas.width, canvas.height); 
    22.          
    23.          
    24.         var dx = targetX - ball.x,  //目标位置减去小球的位置 
    25.             ax = dx * spring;  //距离乘以弹性系数 
    26.  
    27.         vx += ax; 
    28.         vx *= f; 
    29.         ball.x += vx; 
    30.         ball.draw(context); 
    31.       }()); 
    32.     }; 
    33.     </script> 

    代码还是很简单的,这里我解释一下它的具体过程。

    首先,我们设置了目标位置(targetX), 和弹性系数(spring),小球的初始位置位于canvas的左边缘,在动画循环中,每一帧都让目标的位置剪去小球的位置,然后将加速度(ax)赋值为距离(dx)与弹性系数(spring)的乘积,随着小球逐渐的向右运动(ball.x的增大),这样我们就得到一个逐渐衰减的加速度值。最终得到的效果就如图片中显示的一样,我们的目标位置是canvas画布的中心,小球以一个非常快的速度开始运动,因为此时的加速度很大,相应的速度值也很大,所以在一开始小球运动的很快。当小球快要到达目标位置时,小球不会立刻停止,为什么呢?因为虽然当小球靠近目标位置的时候,此时的加速度因为距离已经变得很小而逐渐趋近于零,但此时的速度却并不为零。所以,小球会超过目标位置继续运动。

    当小球超过目标位置继续运动的时候,此时targetX - ball.x为负值,那么导致加速的值也为赋值,所以速度会在每一帧都加上一个负值的加速度,这样速度就开始慢慢减小,随着负值加速度的不断增大,速度逐渐减小至零,这时候小球就运动到了它能够到达的最远端。

    当到达最远端,小球的速度变为零,但此时的加速度并不为零,此时的加速度值为一个负值。所以,速度值在随后开始从零变为负值,小球据开始从最远端往回走,当经过目标位置时,加速度又变为零,此时速度不为零继续向左运动,当超过零点加速度变为正值,速度开始减少,直至为零,让后就这样一直往复下去,最终停留在目标位置,这就是我们的弹性动画,简直和弹簧一样,有木有。

    如果,你还能记得中学时关于速度与加速度的关系,你应该很容易就理解我所说的,加速度为零,速度不为零,速度为零,而加速度不为零

    此后介绍的其他弹性动画,都是基于这个概念,至于形式的不同,只是增加或减少不同的控制元素。比如对于任意位置的弹性动画,就可以说是是上面简单动画的加强版。这里我们设置了一个任意的目标位置
     

    1. var targetX = somewhere; 
    2. var targetY = somewhere; 

    然后,在动画循环中
     

    1. var dx = targetX - ball.x, 
    2.     ax = dx * spring; 
    3. var dy = targetY - ball.y, 
    4.     ay = dy * spring; 
    5.      
    6.     vx += ax; 
    7.     vy += ay; 

     

    2.鼠标跟随弹性动画

    鼠标跟随是个老梗了,无非就是把目标位置设置为我们的鼠标。在这里我们把它作为我们渐进式增强学习的第二个动画。废话不多说我们上效果图:

    《html5 canvas动画》 —— 弹性动画

    具体代码图下:
     

    1. window.onload = function(){ 
    2.           var canvas = document.getElementById('canvas'), 
    3.           context = canvas.getContext('2d'), 
    4.           mouse = utils.captureMouse(canvas), 
    5.           ball = new Ball(20,"orange"), 
    6.           spring = 0.03, //弹性系数 
    7.           friction = 0.95, //摩擦力 
    8.           vx = 0, 
    9.           vy = 0; 
    10.  
    11.       (function drawFrame () { 
    12.         window.requestAnimationFrame(drawFrame, canvas); 
    13.         context.clearRect(0, 0, canvas.width, canvas.height); 
    14.  
    15.         var dx = mouse.x - ball.x,  //核心代码 
    16.             dy = mouse.y - ball.y, 
    17.             ax = dx * spring, 
    18.             ay = dy * spring; 
    19.  
    20.             vx += ax; 
    21.             vy += ay; 
    22.             vx *= friction; 
    23.             vy *= friction; 
    24.             ball.x += vx; 
    25.             ball.y += vy; 
    26.             ball.draw(context); 
    27.       }()); 
    28.       } 

    这里我们定义了一个摩擦力,让运动更加逼真。具体的原理解释我就不在这多说了,前面已经说的很详细了。

    2.1绳球运动

    我一直在考虑这个运动到底应该取个什么样的名字。最后好像这个名字最能表现出该运动的运动元素,和运动形态。先看效果图,原理我们后面解释:
    《html5 canvas动画》 —— 弹性动画

    具体代码如下:

    1. 。。。 
    2. ontext.save(); 
    3.               context.beginPath(); 
    4.               context.strokeStyle = "#fff"
    5.               context.moveTo(ball.x, ball.y); 
    6.               context.lineTo(mouse.x, mouse.y); 
    7.               context.stroke(); 
    8.               context.closePath(); 
    9.               context.restore(); 
    10. 。。。 

    在前面的鼠标跟随动画中,我们的目标位置鼠标,那么绳球运动的概念很简单,在鼠标与目标位置之间画个绳子,额,就是这么简单,说的我都不好意思了。你可以在后面再多追加几个小球看看会有什么样的效果。

    3. Offset spring

    在上面的动画中我们,小球的运动位置为我们设定的目标位置。offset 顾名思义为偏移量,它的作用是让物体最终停止在距离控制点一定距离的位置。比如:距离鼠标100像素的位置。这里我们给一个简单的例子:
    《html5 canvas动画》 —— 弹性动画

    具体代码在这我就不列出了,在文章的开头,有我们的源代码文件。如果感兴趣可以去看看。

    4.缓动动画与弹性动画总结

    1、缓动动画
    1. var dx = targetX - object.x, 
    2.     dy = targetY - object.y; 
    3.      
    4. var vx = dx * easing, 
    5.     vy = dy * easing; 
    6.      
    7.     object.x += vx; 
    8.     object.y += vy; 
    2、缓动动画,精简形式
    1. object.x += (targetX - object.x) * easing; 
    2. object.y += (targetY - object.y) * easing; 
    3、弹性动画
    1. var ax = (targetX - object.x) * spring; 
    2. var ay = (targetY - object.y) * spring; 
    3.  
    4. var vx += ax; 
    5. var vy += ay; 
    6.  
    7. vx *= f; 
    8. vy *= f; 
    9.  
    10. object.x += vx; 
    11. object.y += vy; 
    4、弹性动画,精简形式
    1. vx += (targetX - object.x) * spring; 
    2. vy += (targetY - object.y) * spring; 
    3.  
    4. object.x += (vx*=f); 
    5. object.y += (vy*=f); 
    5、 Offset spring
    1. var dx = object.x - fixedX, 
    2.     dy = object.y - fixedY; 
    3.     angle = Math.atan2(dy, dx); 
    4.     targetX = fixed + Math.cos(angle)*springLength, 
    5.     targetY = fixed + Math.sin(angle)*springLength; 
    6.      
    7.     //spring to targetX, targetY as above 
    下一章,碰撞检测,应该是本系列最难的一章,做好准备。

    js代码下载:  《html5 canvas动画》.zip
    转载请注明(B5教程网)原文链接:https://b5.mxunkeji.com/content-142-5111-1.html
    相关热词搜索: