我们可以先看代码
图片显示代码的结构
<!DOCTYPE HTML> <html> <head> <title>timeline脚本</title> <script type="text/javascript" src="sea.js"></script> <script type="text/javascript"> seajs.use("main",function(main){ main.start(); }); </script> </head> <body> <canvas id="myview">您的浏览器不支持,请更换现代浏览器</canvas> </body> </html>
这里使用sea.js调用程序的入口,不是重点
define("main",function(require, exports, module){ var timeline = require("timeline"); exports.start = function(){ timeline.init(); //this.show(); this.hide(); }; exports.anims = []; exports.show = function( start ){ timeline.createTask({ start: start, duration: 1000, data: [ 1e-5, 1, "show" ], object: this, onTimeUpdate: this.onZooming, onTimeStart: this.onZoomStart, onTimeEnd: this.onZoomEnd, recycle: this.anims }); }; exports.hide = function( start ){ timeline.createTask({ start: start, duration: 500, data: [ 1, 1e-5, "hide" ], object: this, onTimeUpdate: this.onZooming, onTimeStart: this.onZoomStart, onTimeEnd: this.onZoomEnd, recycle: this.anims }); }; // 显示/隐藏 相关 exports.onZoomStart = function(){ console.info("开始缩放"); }; exports.onZooming = function(){ console.info("正在缩放"); }; exports.onZoomEnd = function(){ console.info("结束缩放"); }; });
这里面只是做了一个方法的调用
define("timeline",function(require, exports, module){ //初始化,使用timeline就必须进行初始化操作 exports.init = function(){ var me = this; me.startTime = now(); me.count = 0; var time = 1; //这里每隔1毫秒进行一次更新操作 setInterval(function(){ me.count++; //这里的更新方法是关键,就好比是汽车的发动机 update(now()); }, time); }; exports.createTask = function(conf){ /* e.g. createTask({ start: 500, duration: 2000, data: [a, b, c,..], object: module, onTimeUpdate: fn(time, a, b, c,..), onTimeStart: fn(a, b, c,..), onTimeEnd: fn(a, b, c,..), recycle: [] }); */ var task = createTask(conf); addingTasks.unshift(task); adding = 1; if(conf.recycle){ this.taskList(conf.recycle, task); } return task; }; //当前模块运行的任务,以及停止并清除所有正运行的任务 exports.taskList = function(queue, task){ if(!queue.clear){ queue.clear = function(){ for(var task, i = this.length - 1; i >= 0; i--){ task = this[i]; task.stop(); this.splice(i, 1); return this; } } } if(task){ queue.unshift(task); } return queue; }; exports.getFPS = function(){ var t = now(); var fps = this.count / ( t - this.startTime ) * 1e3; if(this.count > 1e3){ this.count = 0; this.startTime = t; } return fps; }; var tasks = []; var addingTasks = []; var adding = 0; var now = function(){ return new Date().getTime(); }; var createTask = function(conf){ var object = conf.object || {}; conf.start = conf.start || 0; return { start: conf.start + now(), duration: conf.duration == -1 ? 864000000 : conf.duration, data: conf.data ? [0].concat(conf.data) : [0], started: 0, object: object, onTimeStart: conf.onTimeStart || object.onTimeStart || function(){ return null; }, onTimeUpdate: conf.onTimeUpdate || object.onTimeUpdate || function(){ return null; }, onTimeEnd: conf.onTimeEnd || object.onTimeEnd || function(){ return null; }, stop: function(){ this.stopped = 1; } }; }; //进行任务的更新操作, var updateTask = function(task, time){ var data = task.data; data[0] = time; //运行更新方法,更新方法的作用域是task.object,参数是data task.onTimeUpdate.apply(task.object, data); }; var checkStartTask = function(task){ if(!task.started){ task.started = 1; //运行开始方法,开始方法的作用域是task.object,参数是task.data数组删除第一个元素,因为第一个元素是动态添加的 task.onTimeStart.apply(task.object, task.data.slice(1)); updateTask(task, 0); } }; var update = function(time){ var i = tasks.length, t, task, start, duration, data; while(i--){ task = tasks[i]; start = task.start; duration = task.duration; if(time >= start){ if(task.stopped){ tasks.splice(i, 1); continue; } checkStartTask(task); if((t = time - start ) < duration){ updateTask(task, t); }else{ updateTask(task, duration); task.onTimeEnd.apply(task.object, task.data.slice(1)); tasks.splice(i, 1); } } } //任务的添加 if(adding){ tasks.unshift.apply(tasks, addingTasks); addingTasks.length = adding = 0; } }; });