From 1354d17270961fff662d40f90521223f8fd0d73b Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Tue, 14 Aug 2012 18:59:10 +0400 Subject: update dojo to 1.7.3 --- lib/dojo/_base/fx.js.uncompressed.js | 666 +++++++++++++++++++++++++++++++++++ 1 file changed, 666 insertions(+) create mode 100644 lib/dojo/_base/fx.js.uncompressed.js (limited to 'lib/dojo/_base/fx.js.uncompressed.js') diff --git a/lib/dojo/_base/fx.js.uncompressed.js b/lib/dojo/_base/fx.js.uncompressed.js new file mode 100644 index 000000000..cf52b0de1 --- /dev/null +++ b/lib/dojo/_base/fx.js.uncompressed.js @@ -0,0 +1,666 @@ +define("dojo/_base/fx", ["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"], function(dojo, lang, Evented, Color, connect, has, dom, style){ + // module: + // dojo/_base/fx + // summary: + // This module defines the base dojo.fx implementation. + // notes: + // Animation loosely package based on Dan Pupius' work, contributed under CLA; see + // http://pupius.co.uk/js/Toolkit.Drawing.js + + var _mixin = lang.mixin; + + dojo._Line = function(/*int*/ start, /*int*/ end){ + // summary: + // dojo._Line is the object used to generate values from a start value + // to an end value + // start: int + // Beginning value for range + // end: int + // Ending value for range + this.start = start; + this.end = end; + }; + + dojo._Line.prototype.getValue = function(/*float*/ n){ + // summary: Returns the point on the line + // n: a floating point number greater than 0 and less than 1 + return ((this.end - this.start) * n) + this.start; // Decimal + }; + + dojo.Animation = function(args){ + // summary: + // A generic animation class that fires callbacks into its handlers + // object at various states. + // description: + // A generic animation class that fires callbacks into its handlers + // object at various states. Nearly all dojo animation functions + // return an instance of this method, usually without calling the + // .play() method beforehand. Therefore, you will likely need to + // call .play() on instances of `dojo.Animation` when one is + // returned. + // args: Object + // The 'magic argument', mixing all the properties into this + // animation instance. + + _mixin(this, args); + if(lang.isArray(this.curve)){ + this.curve = new dojo._Line(this.curve[0], this.curve[1]); + } + + }; + dojo.Animation.prototype = new Evented(); + // Alias to drop come 2.0: + dojo._Animation = dojo.Animation; + + lang.extend(dojo.Animation, { + // duration: Integer + // The time in milliseonds the animation will take to run + duration: 350, + + /*===== + // curve: dojo._Line|Array + // A two element array of start and end values, or a `dojo._Line` instance to be + // used in the Animation. + curve: null, + + // easing: Function? + // A Function to adjust the acceleration (or deceleration) of the progress + // across a dojo._Line + easing: null, + =====*/ + + // repeat: Integer? + // The number of times to loop the animation + repeat: 0, + + // rate: Integer? + // the time in milliseconds to wait before advancing to next frame + // (used as a fps timer: 1000/rate = fps) + rate: 20 /* 50 fps */, + + /*===== + // delay: Integer? + // The time in milliseconds to wait before starting animation after it + // has been .play()'ed + delay: null, + + // beforeBegin: Event? + // Synthetic event fired before a dojo.Animation begins playing (synchronous) + beforeBegin: null, + + // onBegin: Event? + // Synthetic event fired as a dojo.Animation begins playing (useful?) + onBegin: null, + + // onAnimate: Event? + // Synthetic event fired at each interval of a `dojo.Animation` + onAnimate: null, + + // onEnd: Event? + // Synthetic event fired after the final frame of a `dojo.Animation` + onEnd: null, + + // onPlay: Event? + // Synthetic event fired any time a `dojo.Animation` is play()'ed + onPlay: null, + + // onPause: Event? + // Synthetic event fired when a `dojo.Animation` is paused + onPause: null, + + // onStop: Event + // Synthetic event fires when a `dojo.Animation` is stopped + onStop: null, + + =====*/ + + _percent: 0, + _startRepeatCount: 0, + + _getStep: function(){ + var _p = this._percent, + _e = this.easing + ; + return _e ? _e(_p) : _p; + }, + _fire: function(/*Event*/ evt, /*Array?*/ args){ + // summary: + // Convenience function. Fire event "evt" and pass it the + // arguments specified in "args". + // description: + // Convenience function. Fire event "evt" and pass it the + // arguments specified in "args". + // Fires the callback in the scope of the `dojo.Animation` + // instance. + // evt: + // The event to fire. + // args: + // The arguments to pass to the event. + var a = args||[]; + if(this[evt]){ + if(dojo.config.debugAtAllCosts){ + this[evt].apply(this, a); + }else{ + try{ + this[evt].apply(this, a); + }catch(e){ + // squelch and log because we shouldn't allow exceptions in + // synthetic event handlers to cause the internal timer to run + // amuck, potentially pegging the CPU. I'm not a fan of this + // squelch, but hopefully logging will make it clear what's + // going on + console.error("exception in animation handler for:", evt); + console.error(e); + } + } + } + return this; // dojo.Animation + }, + + play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){ + // summary: + // Start the animation. + // delay: + // How many milliseconds to delay before starting. + // gotoStart: + // If true, starts the animation from the beginning; otherwise, + // starts it from its current position. + // returns: dojo.Animation + // The instance to allow chaining. + + var _t = this; + if(_t._delayTimer){ _t._clearTimer(); } + if(gotoStart){ + _t._stopTimer(); + _t._active = _t._paused = false; + _t._percent = 0; + }else if(_t._active && !_t._paused){ + return _t; + } + + _t._fire("beforeBegin", [_t.node]); + + var de = delay || _t.delay, + _p = lang.hitch(_t, "_play", gotoStart); + + if(de > 0){ + _t._delayTimer = setTimeout(_p, de); + return _t; + } + _p(); + return _t; // dojo.Animation + }, + + _play: function(gotoStart){ + var _t = this; + if(_t._delayTimer){ _t._clearTimer(); } + _t._startTime = new Date().valueOf(); + if(_t._paused){ + _t._startTime -= _t.duration * _t._percent; + } + + _t._active = true; + _t._paused = false; + var value = _t.curve.getValue(_t._getStep()); + if(!_t._percent){ + if(!_t._startRepeatCount){ + _t._startRepeatCount = _t.repeat; + } + _t._fire("onBegin", [value]); + } + + _t._fire("onPlay", [value]); + + _t._cycle(); + return _t; // dojo.Animation + }, + + pause: function(){ + // summary: Pauses a running animation. + var _t = this; + if(_t._delayTimer){ _t._clearTimer(); } + _t._stopTimer(); + if(!_t._active){ return _t; /*dojo.Animation*/ } + _t._paused = true; + _t._fire("onPause", [_t.curve.getValue(_t._getStep())]); + return _t; // dojo.Animation + }, + + gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){ + // summary: + // Sets the progress of the animation. + // percent: + // A percentage in decimal notation (between and including 0.0 and 1.0). + // andPlay: + // If true, play the animation after setting the progress. + var _t = this; + _t._stopTimer(); + _t._active = _t._paused = true; + _t._percent = percent; + if(andPlay){ _t.play(); } + return _t; // dojo.Animation + }, + + stop: function(/*boolean?*/ gotoEnd){ + // summary: Stops a running animation. + // gotoEnd: If true, the animation will end. + var _t = this; + if(_t._delayTimer){ _t._clearTimer(); } + if(!_t._timer){ return _t; /* dojo.Animation */ } + _t._stopTimer(); + if(gotoEnd){ + _t._percent = 1; + } + _t._fire("onStop", [_t.curve.getValue(_t._getStep())]); + _t._active = _t._paused = false; + return _t; // dojo.Animation + }, + + status: function(){ + // summary: + // Returns a string token representation of the status of + // the animation, one of: "paused", "playing", "stopped" + if(this._active){ + return this._paused ? "paused" : "playing"; // String + } + return "stopped"; // String + }, + + _cycle: function(){ + var _t = this; + if(_t._active){ + var curr = new Date().valueOf(); + var step = (curr - _t._startTime) / (_t.duration); + + if(step >= 1){ + step = 1; + } + _t._percent = step; + + // Perform easing + if(_t.easing){ + step = _t.easing(step); + } + + _t._fire("onAnimate", [_t.curve.getValue(step)]); + + if(_t._percent < 1){ + _t._startTimer(); + }else{ + _t._active = false; + + if(_t.repeat > 0){ + _t.repeat--; + _t.play(null, true); + }else if(_t.repeat == -1){ + _t.play(null, true); + }else{ + if(_t._startRepeatCount){ + _t.repeat = _t._startRepeatCount; + _t._startRepeatCount = 0; + } + } + _t._percent = 0; + _t._fire("onEnd", [_t.node]); + !_t.repeat && _t._stopTimer(); + } + } + return _t; // dojo.Animation + }, + + _clearTimer: function(){ + // summary: Clear the play delay timer + clearTimeout(this._delayTimer); + delete this._delayTimer; + } + + }); + + // the local timer, stubbed into all Animation instances + var ctr = 0, + timer = null, + runner = { + run: function(){} + }; + + lang.extend(dojo.Animation, { + + _startTimer: function(){ + if(!this._timer){ + this._timer = connect.connect(runner, "run", this, "_cycle"); + ctr++; + } + if(!timer){ + timer = setInterval(lang.hitch(runner, "run"), this.rate); + } + }, + + _stopTimer: function(){ + if(this._timer){ + connect.disconnect(this._timer); + this._timer = null; + ctr--; + } + if(ctr <= 0){ + clearInterval(timer); + timer = null; + ctr = 0; + } + } + + }); + + var _makeFadeable = + has("ie") ? function(node){ + // only set the zoom if the "tickle" value would be the same as the + // default + var ns = node.style; + // don't set the width to auto if it didn't already cascade that way. + // We don't want to f anyones designs + if(!ns.width.length && style.get(node, "width") == "auto"){ + ns.width = "auto"; + } + } : + function(){}; + + dojo._fade = function(/*Object*/ args){ + // summary: + // Returns an animation that will fade the node defined by + // args.node from the start to end values passed (args.start + // args.end) (end is mandatory, start is optional) + + args.node = dom.byId(args.node); + var fArgs = _mixin({ properties: {} }, args), + props = (fArgs.properties.opacity = {}); + + props.start = !("start" in fArgs) ? + function(){ + return +style.get(fArgs.node, "opacity")||0; + } : fArgs.start; + props.end = fArgs.end; + + var anim = dojo.animateProperty(fArgs); + connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node)); + + return anim; // dojo.Animation + }; + + /*===== + dojo.__FadeArgs = function(node, duration, easing){ + // node: DOMNode|String + // The node referenced in the animation + // duration: Integer? + // Duration of the animation in milliseconds. + // easing: Function? + // An easing function. + this.node = node; + this.duration = duration; + this.easing = easing; + } + =====*/ + + dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){ + // summary: + // Returns an animation that will fade node defined in 'args' from + // its current opacity to fully opaque. + return dojo._fade(_mixin({ end: 1 }, args)); // dojo.Animation + }; + + dojo.fadeOut = function(/*dojo.__FadeArgs*/ args){ + // summary: + // Returns an animation that will fade node defined in 'args' + // from its current opacity to fully transparent. + return dojo._fade(_mixin({ end: 0 }, args)); // dojo.Animation + }; + + dojo._defaultEasing = function(/*Decimal?*/ n){ + // summary: The default easing function for dojo.Animation(s) + return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2); // Decimal + }; + + var PropLine = function(properties){ + // PropLine is an internal class which is used to model the values of + // an a group of CSS properties across an animation lifecycle. In + // particular, the "getValue" function handles getting interpolated + // values between start and end for a particular CSS value. + this._properties = properties; + for(var p in properties){ + var prop = properties[p]; + if(prop.start instanceof Color){ + // create a reusable temp color object to keep intermediate results + prop.tempColor = new Color(); + } + } + }; + + PropLine.prototype.getValue = function(r){ + var ret = {}; + for(var p in this._properties){ + var prop = this._properties[p], + start = prop.start; + if(start instanceof Color){ + ret[p] = Color.blendColors(start, prop.end, r, prop.tempColor).toCss(); + }else if(!lang.isArray(start)){ + ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0); + } + } + return ret; + }; + + /*===== + dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], { + // Properties: Object? + // A hash map of style properties to Objects describing the transition, + // such as the properties of dojo._Line with an additional 'units' property + properties: {} + + //TODOC: add event callbacks + }); + =====*/ + + dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){ + // summary: + // Returns an animation that will transition the properties of + // node defined in `args` depending how they are defined in + // `args.properties` + // + // description: + // `dojo.animateProperty` is the foundation of most `dojo.fx` + // animations. It takes an object of "properties" corresponding to + // style properties, and animates them in parallel over a set + // duration. + // + // example: + // A simple animation that changes the width of the specified node. + // | dojo.animateProperty({ + // | node: "nodeId", + // | properties: { width: 400 }, + // | }).play(); + // Dojo figures out the start value for the width and converts the + // integer specified for the width to the more expressive but + // verbose form `{ width: { end: '400', units: 'px' } }` which you + // can also specify directly. Defaults to 'px' if ommitted. + // + // example: + // Animate width, height, and padding over 2 seconds... the + // pedantic way: + // | dojo.animateProperty({ node: node, duration:2000, + // | properties: { + // | width: { start: '200', end: '400', units:"px" }, + // | height: { start:'200', end: '400', units:"px" }, + // | paddingTop: { start:'5', end:'50', units:"px" } + // | } + // | }).play(); + // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties + // are written using "mixed case", as the hyphen is illegal as an object key. + // + // example: + // Plug in a different easing function and register a callback for + // when the animation ends. Easing functions accept values between + // zero and one and return a value on that basis. In this case, an + // exponential-in curve. + // | dojo.animateProperty({ + // | node: "nodeId", + // | // dojo figures out the start value + // | properties: { width: { end: 400 } }, + // | easing: function(n){ + // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1)); + // | }, + // | onEnd: function(node){ + // | // called when the animation finishes. The animation + // | // target is passed to this function + // | } + // | }).play(500); // delay playing half a second + // + // example: + // Like all `dojo.Animation`s, animateProperty returns a handle to the + // Animation instance, which fires the events common to Dojo FX. Use `dojo.connect` + // to access these events outside of the Animation definiton: + // | var anim = dojo.animateProperty({ + // | node:"someId", + // | properties:{ + // | width:400, height:500 + // | } + // | }); + // | dojo.connect(anim,"onEnd", function(){ + // | console.log("animation ended"); + // | }); + // | // play the animation now: + // | anim.play(); + // + // example: + // Each property can be a function whose return value is substituted along. + // Additionally, each measurement (eg: start, end) can be a function. The node + // reference is passed direcly to callbacks. + // | dojo.animateProperty({ + // | node:"mine", + // | properties:{ + // | height:function(node){ + // | // shrink this node by 50% + // | return dojo.position(node).h / 2 + // | }, + // | width:{ + // | start:function(node){ return 100; }, + // | end:function(node){ return 200; } + // | } + // | } + // | }).play(); + // + + var n = args.node = dom.byId(args.node); + if(!args.easing){ args.easing = dojo._defaultEasing; } + + var anim = new dojo.Animation(args); + connect.connect(anim, "beforeBegin", anim, function(){ + var pm = {}; + for(var p in this.properties){ + // Make shallow copy of properties into pm because we overwrite + // some values below. In particular if start/end are functions + // we don't want to overwrite them or the functions won't be + // called if the animation is reused. + if(p == "width" || p == "height"){ + this.node.display = "block"; + } + var prop = this.properties[p]; + if(lang.isFunction(prop)){ + prop = prop(n); + } + prop = pm[p] = _mixin({}, (lang.isObject(prop) ? prop: { end: prop })); + + if(lang.isFunction(prop.start)){ + prop.start = prop.start(n); + } + if(lang.isFunction(prop.end)){ + prop.end = prop.end(n); + } + var isColor = (p.toLowerCase().indexOf("color") >= 0); + function getStyle(node, p){ + // dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable: + var v = { height: node.offsetHeight, width: node.offsetWidth }[p]; + if(v !== undefined){ return v; } + v = style.get(node, p); + return (p == "opacity") ? +v : (isColor ? v : parseFloat(v)); + } + if(!("end" in prop)){ + prop.end = getStyle(n, p); + }else if(!("start" in prop)){ + prop.start = getStyle(n, p); + } + + if(isColor){ + prop.start = new Color(prop.start); + prop.end = new Color(prop.end); + }else{ + prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start); + } + } + this.curve = new PropLine(pm); + }); + connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node)); + return anim; // dojo.Animation + }; + + dojo.anim = function( /*DOMNode|String*/ node, + /*Object*/ properties, + /*Integer?*/ duration, + /*Function?*/ easing, + /*Function?*/ onEnd, + /*Integer?*/ delay){ + // summary: + // A simpler interface to `dojo.animateProperty()`, also returns + // an instance of `dojo.Animation` but begins the animation + // immediately, unlike nearly every other Dojo animation API. + // description: + // `dojo.anim` is a simpler (but somewhat less powerful) version + // of `dojo.animateProperty`. It uses defaults for many basic properties + // and allows for positional parameters to be used in place of the + // packed "property bag" which is used for other Dojo animation + // methods. + // + // The `dojo.Animation` object returned from `dojo.anim` will be + // already playing when it is returned from this function, so + // calling play() on it again is (usually) a no-op. + // node: + // a DOM node or the id of a node to animate CSS properties on + // duration: + // The number of milliseconds over which the animation + // should run. Defaults to the global animation default duration + // (350ms). + // easing: + // An easing function over which to calculate acceleration + // and deceleration of the animation through its duration. + // A default easing algorithm is provided, but you may + // plug in any you wish. A large selection of easing algorithms + // are available in `dojo.fx.easing`. + // onEnd: + // A function to be called when the animation finishes + // running. + // delay: + // The number of milliseconds to delay beginning the + // animation by. The default is 0. + // example: + // Fade out a node + // | dojo.anim("id", { opacity: 0 }); + // example: + // Fade out a node over a full second + // | dojo.anim("id", { opacity: 0 }, 1000); + return dojo.animateProperty({ // dojo.Animation + node: node, + duration: duration || dojo.Animation.prototype.duration, + properties: properties, + easing: easing, + onEnd: onEnd + }).play(delay || 0); + }; + + return { + _Line: dojo._Line, + Animation: dojo.Animation, + _fade: dojo._fade, + fadeIn: dojo.fadeIn, + fadeOut: dojo.fadeOut, + _defaultEasing: dojo._defaultEasing, + animateProperty: dojo.animateProperty, + anim: dojo.anim + }; +}); -- cgit v1.2.3