根据这个解释,我们很快可以编写出一个线性的动画。
(function() {var begin, // 开始动画的时间el, start, end, duration;var INTERVAL = 13;function now() {return (new Date).getTime();}/*** 执行一步动画(更新属性) */ function _animLeft() { var pos = (now() - begin) / duration; if (pos >= 1.0) { return false; } return !!(el.style.left = start + (end - start) * pos); } /** * 对一个DOM执行动画,left从_start到_end,执行时间为 * _duration毫秒。 * * @param {object} _el 要执行动画的DOM节点 * @param {integer} _start left的起始值 * @param {integer} _end left的最终值 * @param {integer} _duration 动画执行时间 */ function animLeft(_el, _start, _end, _duration) { stopped = false; begin = now(); el = _el; start = _start; end = _end; duration = _duration || 1000; var step = function() { if (_animLeft()) { setTimeout(step, INTERVAL); } }; setTimeout(step, 0); } window.animLeft = animLeft; })(); animLeft( document.getElementById('el'), 100, 200 )JSBin
在真实世界的时间进行到x0的时候,动画进程原本应该进行到y0,在进行变换之后,只进行到y1。到最后,百川归海,两条线交汇于点(1, 1)。这里,y = x * x是变换函数(easing function)。
function ease(time) { return time * time; } /** * 执行一步动画(更新属性) */ function _animLeft() { var pos = (now() - begin) / duration; if (pos >= 1.0) { return false; } pos = ease(pos); return !!(el.style.left = (start + (end - start) * pos) + "px"); }JSBin
jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; } };因此,你可以往jQuery.easing里面添加easing function,使得jQuery支持新的动画速率控制方法。注意,easing function的定义域和值域必须都为[0, 1]。
jQuery.easing.myEasing = function( p ) { return ... }