《每周一点canvas动画》 —— 弹性动画
本系列文章代码文件
在上一章我们介绍了缓动动画,并且对弹性动画的概念做了简单的介绍。弹性动画(spring)与缓动动画都是基于距离的百分比动画,两者的不同之处在于,一个作用于速度(ease), 一个作用于加速度(spring)。弹性动画是动画中相当有用的的一个物理概念,通过它你可以做很多酷炫的效果,本节的主要内容如下:
简单的弹性动画
鼠标跟随弹性动画
offset spring
总结
1.简单的弹性动画
之前我们已经说过弹性动画的作用元素是加速度。该加速度的变化基于距离的百分比。有了上一节对缓动动画的理解,想必大家对于我们要做什么应该都一清二楚了。这里我们先做一个基于坐标轴的弹性动画。先上效果图:
具体代码如下:
your browser not support canvas! window.onload = function () { var canvas = document.getElementById('canvas'), context = canvas.getContext('2d'), ball = new Ball(), spring = 0.03, //弹性系数 targetX = canvas.width / 2, //目标位置 vx = 0; ball.y = canvas.height / 2; (function drawFrame () { window.requestAnimationFrame(drawFrame, canvas); context.clearRect(0, 0, canvas.width, canvas.height); var dx = targetX - ball.x, //目标位置减去小球的位置 ax = dx * spring; //距离乘以弹性系数 vx += ax; ball.x += vx; ball.draw(context); }());};
代码还是很简单的,这里我解释一下它的具体过程。
首先,我们设置了目标位置(targetX), 和弹性系数(spring),小球的初始位置位于canvas的左边缘,在动画循环中,每一帧都让目标的位置剪去小球的位置,然后将加速度(ax)赋值为距离(dx)与弹性系数(spring)的乘积,随着小球逐渐的向右运动(ball.x的增大),这样我们就得到一个逐渐衰减的加速度值。最终得到的效果就如图片中显示的一样,我们的目标位置是canvas画布的中心,小球以一个非常快的速度开始运动,因为此时的加速度很大,相应的速度值也很大,所以在一开始小球运动的很快。当小球快要到达目标位置时,小球不会立刻停止,为什么呢?因为虽然当小球靠近目标位置的时候,此时的加速度因为距离已经变得很小而逐渐趋近于零,但此时的速度却并不为零。所以,小球会超过目标位置继续运动。
当小球超过目标位置继续运动的时候,此时targetX - ball.x为负值,那么导致加速的值也为赋值,所以速度会在每一帧都加上一个负值的加速度,这样速度就开始慢慢减小,随着负值加速度的不断增大,速度逐渐减小至零,这时候小球就运动到了它能够到达的最远端。
当到达最远端,小球的速度变为零,但此时的加速度并不为零,此时的加速度值为一个负值。所以,速度值在随后开始从零变为负值,小球据开始从最远端往回走,当经过目标位置时,加速度又变为零,此时速度不为零继续向左运动,当超过零点加速度变为正值,速度开始减少,直至为零,让后就这样一直往复下去,最终停留在目标位置,这就是我们的弹性动画,简直和弹簧一样,有木有。
如果,你还能记得中学时关于速度与加速度的关系,你应该很容易就理解我所说的,加速度为零,速度不为零,速度为零,而加速度不为零。
此后介绍的其他弹性动画,都是基于这个概念,至于形式的不同,只是增加或减少不同的控制元素。比如对于任意位置的弹性动画,就可以说是是上面简单动画的加强版。这里我们设置了一个任意的目标位置
var targetX = somewhere;
var targetY = somewhere;
然后,在动画循环中
var dx = targetX - ball.x,
ax = dx spring;
var dy = targetY - ball.y,
ay = dy spring;
vx += ax;vy += ay;
2.鼠标跟随弹性动画
鼠标跟随是个老梗了,无非就是把目标位置设置为我们的鼠标。在这里我们把它作为我们渐进式增强学习的第二个动画。废话不多说我们上效果图:
具体代码图下:
window.onload = function(){
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
mouse = utils.captureMouse(canvas),
ball = new Ball(20,"orange"),
spring = 0.03, //弹性系数
friction = 0.95, //摩擦力
vx = 0,
vy = 0;
(function drawFrame () { window.requestAnimationFrame(drawFrame, canvas); context.clearRect(0, 0, canvas.width, canvas.height); var dx = mouse.x - ball.x, //核心代码 dy = mouse.y - ball.y, ax = dx * spring, ay = dy * spring; vx += ax; vy += ay; vx *= friction; vy *= friction; ball.x += vx; ball.y += vy; ball.draw(context); }()); }
这里我们定义了一个摩擦力,让运动更加逼真。具体的原理解释我就不在这多说了,前面已经说的很详细了。
2.1绳球运动
我一直在考虑这个运动到底应该取个什么样的名字。最后好像这个名字最能表现出该运动的运动元素,和运动形态。先看效果图,原理我们后面解释:
具体代码如下:
。。。
context.save();
context.beginPath();
context.strokeStyle = "# fff";
context.moveTo(ball.x, ball.y);
context.lineTo(mouse.x, mouse.y);
context.stroke();
context.closePath();
context.restore();
。。。
在前面的鼠标跟随动画中,我们的目标位置鼠标,那么绳球运动的概念很简单,在鼠标与目标位置之间画个绳子,额,就是这么简单,说的我都不好意思了。你可以在后面再多追加几个小球看看会有什么样的效果。
3. Offset spring
在上面的动画中我们,小球的运动位置为我们设定的目标位置。offset 顾名思义为偏移量,它的作用是让物体最终停止在距离控制点一定距离的位置。比如:距离鼠标100像素的位置。这里我们给一个简单的例子:
具体代码在这我就不列出了,在文章的开头,有我们的源代码文件。如果感兴趣可以去看看。
4.缓动动画与弹性动画总结
1、缓动动画
var dx = targetX - object.x, dy = targetY - object.y;var vx = dx * easing, vy = dy * easing; object.x += vx; object.y += vy;
2、缓动动画,精简形式
object.x += (targetX - object.x) * easing;object.y += (targetY - object.y) * easing;
3、弹性动画
var ax = (targetX - object.x) * spring;var ay = (targetY - object.y) * spring;var vx += ax;var vy += ay;vx *= f;vy *= f;object.x += vx;object.y += vy;
4、弹性动画,精简形式
vx += (targetX - object.x) * spring;vy += (targetY - object.y) * spring;object.x += (vx*=f);object.y += (vy*=f);
5、 Offset spring
var dx = object.x - fixedX, dy = object.y - fixedY; angle = Math.atan2(dy, dx); targetX = fixed + Math.cos(angle)*springLength, targetY = fixed + Math.sin(angle)*springLength; //spring to targetX, targetY as above
下一章,碰撞检测,应该是本系列最难的一章,做好准备。
关键字:JavaScript, html5, canvas
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!