用惯了jquery的同学,相信都很欣赏其动画引擎。确实相对比较完善!如果,如果想像力足够丰富的话,相信可以做出超出想像的效果。当然,跟2d库比起来,还是相差相当一段距离。jquery压根也不是专门为动画而设计的。模拟真实世界方面,还是不足的。但在web世界里还是游刃有余的。动画其实一直是flash的专属领地(web区哉)。只是它常常沦为黑客攻击的漏洞所在,而且要装插件,有时候文件实在太大,而且性耗实在是高啊。html5出现后,其实adobe自己都转移阵地到html5了。当然,我觉得很长一段时间内,flash是不会被放弃的。
长话短说,步入正题。仿照flash的动画原理,自己写了一个非常简单的js动画引擎。
首先,用过flash的同学都知道。flash有个时间线,上面布满了“帧”。其实每个帧都是一个镜头,镜头连贯起来就是一副动画效果。其实,这跟电影的原理也一样的,小时候玩过胶片的都知道,对着光可以看到一副副的镜头。人眼分辨两个画面的连贯是有时间限度的。如果想看不到两个画面变换时的闪烁大概30帧/秒左右,电影是24帧的。所以,如果能保证,动画切换能保证每秒30次,基本上,就做到了动画的流畅效果,但是这取决环境。所以具体情况,具体而定,其实关于这方面的知识我也是一知半解。就这个动画引擎而言,了解这么多也差不多足够了,有兴趣可以查找相关知识!
下面开始说说设计原理。
首先需要一个帧频,也就是多少帧每秒。如果有了总用时,就可以计算出整个动画下来有多少个“画面”(总帧数)。这种设计,显然有个不足的地方,不能保证时间正好是个整数帧。除非1ms一帧。这是一个网友提出来的,我感觉不好就没有采用。所以这个引擎是有时间误差的。有了总帧数,当动画运行到最后一帧的时候,整个动画也就播放完。如果需要重复播放,重新把当前帧归0。这种动画有一个好处,就可以直接运行到指定帧。也就是flash里的gotoAndStop和gotoAndPlay。其实整个动画设计原理都是照着flash实现的。包括一个很重要的方法:enterFrame。位置就是根据进入当前帧来计算的。还有其它一些方法:stop、play、next......等等因为目前来说,这个引擎是写非常简单和粗糙的,先不说这么详细了。下面先上代码和示例吧!
animate.js 动画核心
var animation = function(obj) {
this.obj = obj;
this.frames = 0;
this.timmer = undefined;
this.running = false;
this.ms = [];
}
animation.prototype = {
fps: 36,
init: function(props, duration, tween) {
//console.log('初始化');
this.curframe = 0;
this.initstate = {};
this.props = props;
this.duration = duration || 1000;
this.tween = tween || function(t, b, c, d) {
return t * c / d + b;
};
this.frames = Math.ceil(this.duration * this.fps/1000);
for (var prop in this.props) {
this.initstate[prop] = {
from: parseFloat($util.dom.getStyle(this.obj, prop)),
to: parseFloat(this.props[prop])
};
}
},
start: function() {
if (!this.running && this.hasNext()) {
//console.log('可以执行...');
this.ms.shift().call(this)
}
return this;
},
//开始播放
play: function(callback) {
//console.log('开始动画!');
var that = this;
this.running = true;
if (this.timmer) {
this.stop();
}