diff options
Diffstat (limited to 'js/dojo/dojox/fx/Timeline.js')
| -rw-r--r-- | js/dojo/dojox/fx/Timeline.js | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/js/dojo/dojox/fx/Timeline.js b/js/dojo/dojox/fx/Timeline.js new file mode 100644 index 0000000..f61e330 --- /dev/null +++ b/js/dojo/dojox/fx/Timeline.js @@ -0,0 +1,213 @@ +//>>built +define("dojox/fx/Timeline", ["dojo/_base/lang","dojo/fx/easing","dojo/_base/fx","dojo/dom","./_base","dojo/_base/connect", + "dojo/_base/html", "dojo/_base/array","dojo/_base/Color"], + function(lang, easingUtil, baseFx, dom, dojoxFx, connectUtil, htmlUtil, arrayUtil, Color){ + +dojoxFx.animateTimeline = function(/* Object */options, /* DomNode|String */node){ + // options: Object + // The paramters passed to the timeline animation. Includes: + // keys: Array + // An array of objects, with style properties and values. + // duration: + // Duration of the animation in milliseconds. + // Defaults to 1000. + // node: DomNode + // The DomNode or id to be animated. + // + // summary: + // An add-on to dojo.fx that provides the ability to create + // a complex property animation based on an array of "keyframes". + // description: + // The Timeline is a replacement for the default dojo._Line. + // Instead of _Line.getValue returning a float between 0-1, + // _Timeline.getValue returns an object with all properties and + // their current values. + // A property does not have to appear in every keyframe. + // As in the example below, "height" is transitioned from the first + // keyframe to the third. "width" is transitioned from the first + // to the second to the third. + // Each keyframe can accept the following custom properties: + // step: String + // The start, finish or percentage that this keyframe represents. + // Allowed parameters are: + // 0%-100% + // from (same as 0%, used to conform with the Webkit animation spec) + // to (same as 100%, used to conform with the Webkit animation spec) + // ease: String + // The string name of a dojo.fx.easing ease. Defaults to "linear". Use + // the suffix name of the ease, like: "quadIn", not: "dojo.fx.quadIn". + // + // example: + // | var keys = [ + // | { + // | step:"0px", + // | ease:"quadInOut", + // | width:"50px", + // | height:"50px", + // | },{ + // | step:"25%", + // | width:"190px" + // | },{ + // | step:"100%", + // | width:"10px", + // | height:"200px", + // | } + // | ]; + // | ani = dojox.fx.animateTimeline({keys:keys, duration:2000}, "myDiv").play(); + // + var _curve = new Timeline(options.keys); + var ani = baseFx.animateProperty({ + node:dom.byId(node || options.node), + duration:options.duration || 1000, + properties:_curve._properties, + // don't change! This easing is for the timeline, + // not individual properties + easing:easingUtil.linear, + onAnimate: function(v){ + //console.log(" ani:", v); + } + }); + connectUtil.connect(ani, "onEnd", function(node){ + // Setting the final style. Hiccups in the browser + // can cause the animation to lose track. This ensures + // that it finishes in the proper location. + var sty = ani.curve.getValue(ani.reversed ? 0 : 1); + htmlUtil.style(node, sty); + }); + connectUtil.connect(ani, "beforeBegin", function(){ + // remove default curve and replace it with Timeline + if(ani.curve){ delete ani.curve; } + ani.curve = _curve; + _curve.ani = ani; + }) + return ani; // dojo.Animation +} + +var Timeline = function(/* Array */keys){ + // summary: + // The dojox.fx._Timeline object from which an instance + // is created + // tags: + // private + this.keys = lang.isArray(keys) ? this.flatten(keys) : keys; +} + +Timeline.prototype.flatten = function(keys){ + // summary: + // An internally used function that converts the keyframes + // as used in the example above into a series of key values + // which is what is used in the animation parsing. + var getPercent = function(str, idx){ + if(str == "from"){ return 0; } + if(str == "to"){ return 1; } + if(str === undefined){ + return idx==0 ? 0 : idx / (keys.length - 1) + } + return parseInt(str, 10) * .01 + } + var p = {}, o = {}; + arrayUtil.forEach(keys, function(k, i){ + var step = getPercent(k.step, i); + var ease = easingUtil[k.ease] || easingUtil.linear; + + for(var nm in k){ + if(nm == "step" || nm == "ease" || nm == "from" || nm == "to"){ continue; } + if(!o[nm]){ + o[nm] = { + steps:[], + values:[], + eases:[], + ease:ease + }; + p[nm] = {}; + if(!/#/.test(k[nm])){ + p[nm].units = o[nm].units = /\D{1,}/.exec(k[nm]).join(""); + }else{ + p[nm].units = o[nm].units = "isColor"; + } + } + + o[nm].eases.push(easingUtil[k.ease || "linear"]); + + o[nm].steps.push(step); + if(p[nm].units == "isColor"){ + o[nm].values.push(new Color(k[nm])); + }else{ + o[nm].values.push(parseInt(/\d{1,}/.exec(k[nm]).join(""))); + } + + if(p[nm].start === undefined){ + p[nm].start = o[nm].values[o[nm].values.length-1]; + }else{ + p[nm].end = o[nm].values[o[nm].values.length-1] + } + } + }); + + + this._properties = p; + return o; // Object + +} + +Timeline.prototype.getValue = function(/*float*/ p){ + // summary: + // Replaces the native getValue in dojo.fx.Animation. + // Returns an object with all propeties used in the animation + // and the property's current value + p = this.ani._reversed ? 1-p : p; + var o = {}, self = this; + + var getProp = function(nm, i){ + return self._properties[nm].units!="isColor" ? + self.keys[nm].values[i] + self._properties[nm].units : + self.keys[nm].values[i].toCss(); + } + + for(var nm in this.keys){ + var k = this.keys[nm]; + for(var i=0; i<k.steps.length; i++){ + + var step = k.steps[i]; + var ns = k.steps[i+1]; + var next = i < k.steps.length ? true : false; + var ease = k.eases[i] || function(n){return n;}; + + if(p == step){ + // first or last + o[nm] = getProp(nm, i); + if(!next || (next && this.ani._reversed)) break; + + }else if(p > step){ + + if(next && p < k.steps[i+1]){ + // inbetween steps + var end = k.values[i+1]; + var beg = k.values[i]; + + var seg = (1 / (ns - step)) * (p - step); + seg = ease(seg); + + if(beg instanceof Color){ + o[nm] = Color.blendColors(beg, end, seg).toCss(false); + }else{ + var df = end - beg; + o[nm] = beg + seg * df + this._properties[nm].units; + } + break; + + }else{ + // completed keys before 100% + o[nm] = getProp(nm, i); + } + + }else if((next && !this.ani._reversed) || (!next && this.ani._reversed)){ + o[nm] = getProp(nm, i); + } + } + } + return o; // Object +}; +dojoxFx._Timeline = Timeline; +return dojoxFx; +}); |
