主页 > 前端 > javascript >
来源:未知 时间:2014-10-21 10:34 作者:xbdadmin 阅读:次
[导读] 用惯了jquery的同学,相信都很欣赏其动画引擎。确实相对比较完善!如果,如果想像力足够丰富的话,相信可以做出超出想像的效果。当然,跟2d库比起来,还是相差相当一段距离。jqu...
用惯了jquery的同学,相信都很欣赏其动画引擎。确实相对比较完善!如果,如果想像力足够丰富的话,相信可以做出超出想像的效果。当然,跟2d库比起来,还是相差相当一段距离。jquery压根也不是专门为动画而设计的。模拟真实世界方面,还是不足的。但在web世界里还是游刃有余的。动画其实一直是flash的专属领地(web区哉)。只是它常常沦为黑客攻击的漏洞所在,而且要装插件,有时候文件实在太大,而且性耗实在是高啊。html5出现后,其实adobe自己都转移阵地到html5了。当然,我觉得很长一段时间内,flash是不会被放弃的。 长话短说,步入正题。仿照flash的动画原理,自己写了一个非常简单的js动画引擎。 首先,用过flash的同学都知道。flash有个时间线,上面布满了“帧”。其实每个帧都是一个镜头,镜头连贯起来就是一副动画效果。其实,这跟电影的原理也一样的,小时候玩过胶片的都知道,对着光可以看到一副副的镜头。人眼分辨两个画面的连贯是有时间限度的。如果想看不到两个画面变换时的闪烁大概30帧/秒左右,电影是24帧的。所以,如果能保证,动画切换能保证每秒30次,基本上,就做到了动画的流畅效果,但是这取决环境。所以具体情况,具体而定,其实关于这方面的知识我也是一知半解。就这个动画引擎而言,了解这么多也差不多足够了,有兴趣可以查找相关知识! 下面开始说说设计原理。
首先需要一个帧频,也就是多少帧每秒。如果有了总用时,通过开始和结束的状态差,就可以计算出整个动画下来有多少个“画面”(总帧数)。 总帧数 = 总用时/1000*帧频 每走一帧,都计算出一个画面! 当前画面=初始状态 + (当前帧/总帧数)(结束状态-初始状态)
这就意味着,如果当前帧是最后一帧的话,当前画面===结束状态。整个过程播放完毕。 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(); } this.timmer = setInterval(function() { if (that.complete()) { that.stop(); that.running = false; if (callback) { callback.call(that); } return; } that.curframe++; that.enterFrame.call(that); }, 1000 / this.fps); return this; }, // 停止动画 stop: function() { //console.log('结束动画!'); if (this.timmer) { clearInterval(this.timmer); // 清除掉timmer id this.timmer = undefined; } }, go: function(props, duration, tween) { var that = this; //console.log(tween) this.ms.push(function() { that.init.call(that, props, duration, tween); that.play.call(that, that.start); }); return this; }, //向后一帧 next: function() { this.stop(); this.curframe++; this.curframe = this.curframe > this.frames ? this.frames: this.curframe; this.enterFrame.call(this); }, //向前一帧 prev: function() { this.stop(); this.curframe--; this.curframe = this.curframe < 0 ? 0 : this.curframe; this.enterFrame.call(this); }, //跳跃到指定帧并播放 gotoAndPlay: function(frame) { this.stop(); this.curframe = frame; this.play.call(this); }, //跳到指定帧停止播放 gotoAndStop: function(frame) { this.stop(); this.curframe = frame; this.enterFrame.call(this); }, //进入帧动作 enterFrame: function() { //console.log('进入帧:' + this.curframe) var ds; for (var prop in this.initstate) { //console.log('from: ' + this.initstate[prop]['from']) ds = this.tween(this.curframe, this.initstate[prop]['from'], this.initstate[prop]['to'] - this.initstate[prop]['from'], this.frames).toFixed(2); //console.log(prop + ':' + ds) $util.dom.setStyle(this.obj, prop, ds) } }, //动画结束 complete: function() { return this.curframe >= this.frames; }, hasNext: function() { return this.ms.length > 0; } } 下面是一个简单的工具,其中有所用到的缓动公式: util.js $util = { /** * 类型检测 */ type : function(obj){ var rep = /\[object\s+(\w+)\]/i; var str = Object.prototype.toString.call(obj).toLowerCase(); str.match(rep); return RegExp.$1; }, /** * 深拷贝 */ $unlink :function (object){ var unlinked; switch ($type(object)){ case 'object': unlinked = {}; for (var p 最新评论添加评论更多文章推荐
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习 京ICP备14009008号-1@版权所有www.zixuephp.com 网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com
添加评论 |