javascript动画
javascript动画是js中比较重要的一环。本文是一个合集。既有对javascript动画的简介,入门等,又有对某个技术点的分析。
简单的javascript动画
不用任何javascript库,我们自己去实现一个类似jQuery的动画: 2s内容让元素宽高都从50px变成200px
来看效果:2s内宽高从50px到200px
function Animation(elem, properties, options){ var timer = null; var core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; var rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ); var startTime = Date.now(); var tweens = []; // 拼凑出动画需要改变的start, end, prop, unit属性 for(var index in properties){ var partsEnd = rfxnum.exec( properties[index] ); var partsStart = rfxnum.exec( elem.style[index] ); tweens.push({start: +partsStart[2], end: +partsEnd[2], prop:index, unit: partsStart[3]}) } // 改变值 function run(percent){ var pos = easing[options.type](percent, percent*(options.duration), 0, 1, options.duration); for(var i=0; i<tweens.length; i++){ elem.style[tweens[i].prop] = (tweens[i].start+(tweens[i].end-tweens[i].start)*pos)+ tweens[i].unit; } } // 定时器回掉 function tick(){ var currentTime = Date.now(); var remaining = Math.max(0, options.duration + startTime - currentTime); var percent = 1-remaining/options.duration; if(percent === 1) clearInterval(timer) run(percent); } // 开启定时器 function start(){ timer = setInterval(tick, 13); } start(); } document.getElementsByTagName("input")[0].onclick = function(){ Animation(document.getElementsByTagName("div")[0], { width: "200px", height: "200px" }, { type: "easeOutStrong", duration: 1000 }); }
这里我们用到了jquery Easing缓冲公式。
var easing = { // t: current time, 当前时间 // b: begInnIng value, 开始值 // c: change In value, 结束值 // d: duration, 动画时间 easeIn: function(x,t, b, c, d){ //加速曲线 return c*(t/=d)*t + b; } }
我们把总的时间设置成1(100%),开始自然是0,总时间duration已知,current time就是:duration * (1-(duration+startTime-nowTime)/duration)
这样,开个定时器,元素的运动轨迹轻而易举的搞定。
jQuery中的动画解读
我们使用的jQuery版本是jQuery.2.0.3。
想要分析它的实现,我们必然要对它的API非常熟悉。
// Generate shortcuts for custom animations
jQuery.each({
slideDown: genFx("show"),
slideUp: genFx("hide"),
slideToggle: genFx("toggle"),
fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" },
fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
jQuery.fn[ name ] = function( speed, easing, callback ) {
return this.animate( props, speed, easing, callback );
};
});
jQuery.fn.extend({
fadeTo: function( speed, to, easing, callback ) {},
animate: function( prop, speed, easing, callback ) {},
stop: function( type, clearQueue, gotoEnd ) {},
finish: function( type ) {}
})
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = jQuery.fn[ name ];
jQuery.fn[ name ] = function( speed, easing, callback ) {
return speed == null || typeof speed === "boolean" ?
cssFn.apply( this, arguments ) :
this.animate( genFx( name, true ), speed, easing, callback );
};
});
全部是拓展在jQuery的示例方法下。
搞这么多接口实在是增加学习成本。我们只关注animate接口即可。
调用animate()的流程图
jQuery动画拓展:贝塞尔曲线
jQuery可以帮助我们实现基于时间的动画,路径规则我们可以自己定义。
首先来看贝塞尔曲线的实现。
天猫加入购物车的例子都很熟悉,我们来模拟一个。
https://jsfiddle.net/sinbad/fkqjka2d/