diff options
Diffstat (limited to 'lib/dojo/fx.js')
-rw-r--r-- | lib/dojo/fx.js | 634 |
1 files changed, 393 insertions, 241 deletions
diff --git a/lib/dojo/fx.js b/lib/dojo/fx.js index 39ae253fd..5c70d5b9e 100644 --- a/lib/dojo/fx.js +++ b/lib/dojo/fx.js @@ -5,248 +5,400 @@ */ -if(!dojo._hasResource["dojo.fx"]){ -dojo._hasResource["dojo.fx"]=true; +if(!dojo._hasResource["dojo.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojo.fx"] = true; dojo.provide("dojo.fx"); -dojo.require("dojo.fx.Toggler"); -(function(){ -var d=dojo,_1={_fire:function(_2,_3){ -if(this[_2]){ -this[_2].apply(this,_3||[]); -} -return this; -}}; -var _4=function(_5){ -this._index=-1; -this._animations=_5||[]; -this._current=this._onAnimateCtx=this._onEndCtx=null; -this.duration=0; -d.forEach(this._animations,function(a){ -this.duration+=a.duration; -if(a.delay){ -this.duration+=a.delay; -} -},this); -}; -d.extend(_4,{_onAnimate:function(){ -this._fire("onAnimate",arguments); -},_onEnd:function(){ -d.disconnect(this._onAnimateCtx); -d.disconnect(this._onEndCtx); -this._onAnimateCtx=this._onEndCtx=null; -if(this._index+1==this._animations.length){ -this._fire("onEnd"); -}else{ -this._current=this._animations[++this._index]; -this._onAnimateCtx=d.connect(this._current,"onAnimate",this,"_onAnimate"); -this._onEndCtx=d.connect(this._current,"onEnd",this,"_onEnd"); -this._current.play(0,true); -} -},play:function(_6,_7){ -if(!this._current){ -this._current=this._animations[this._index=0]; -} -if(!_7&&this._current.status()=="playing"){ -return this; -} -var _8=d.connect(this._current,"beforeBegin",this,function(){ -this._fire("beforeBegin"); -}),_9=d.connect(this._current,"onBegin",this,function(_a){ -this._fire("onBegin",arguments); -}),_b=d.connect(this._current,"onPlay",this,function(_c){ -this._fire("onPlay",arguments); -d.disconnect(_8); -d.disconnect(_9); -d.disconnect(_b); -}); -if(this._onAnimateCtx){ -d.disconnect(this._onAnimateCtx); -} -this._onAnimateCtx=d.connect(this._current,"onAnimate",this,"_onAnimate"); -if(this._onEndCtx){ -d.disconnect(this._onEndCtx); -} -this._onEndCtx=d.connect(this._current,"onEnd",this,"_onEnd"); -this._current.play.apply(this._current,arguments); -return this; -},pause:function(){ -if(this._current){ -var e=d.connect(this._current,"onPause",this,function(_d){ -this._fire("onPause",arguments); -d.disconnect(e); -}); -this._current.pause(); -} -return this; -},gotoPercent:function(_e,_f){ -this.pause(); -var _10=this.duration*_e; -this._current=null; -d.some(this._animations,function(a){ -if(a.duration<=_10){ -this._current=a; -return true; -} -_10-=a.duration; -return false; -}); -if(this._current){ -this._current.gotoPercent(_10/this._current.duration,_f); -} -return this; -},stop:function(_11){ -if(this._current){ -if(_11){ -for(;this._index+1<this._animations.length;++this._index){ -this._animations[this._index].stop(true); -} -this._current=this._animations[this._index]; -} -var e=d.connect(this._current,"onStop",this,function(arg){ -this._fire("onStop",arguments); -d.disconnect(e); -}); -this._current.stop(); -} -return this; -},status:function(){ -return this._current?this._current.status():"stopped"; -},destroy:function(){ -if(this._onAnimateCtx){ -d.disconnect(this._onAnimateCtx); -} -if(this._onEndCtx){ -d.disconnect(this._onEndCtx); -} -}}); -d.extend(_4,_1); -dojo.fx.chain=function(_12){ -return new _4(_12); -}; -var _13=function(_14){ -this._animations=_14||[]; -this._connects=[]; -this._finished=0; -this.duration=0; -d.forEach(_14,function(a){ -var _15=a.duration; -if(a.delay){ -_15+=a.delay; -} -if(this.duration<_15){ -this.duration=_15; -} -this._connects.push(d.connect(a,"onEnd",this,"_onEnd")); -},this); -this._pseudoAnimation=new d.Animation({curve:[0,1],duration:this.duration}); -var _16=this; -d.forEach(["beforeBegin","onBegin","onPlay","onAnimate","onPause","onStop","onEnd"],function(evt){ -_16._connects.push(d.connect(_16._pseudoAnimation,evt,function(){ -_16._fire(evt,arguments); -})); -}); -}; -d.extend(_13,{_doAction:function(_17,_18){ -d.forEach(this._animations,function(a){ -a[_17].apply(a,_18); -}); -return this; -},_onEnd:function(){ -if(++this._finished>this._animations.length){ -this._fire("onEnd"); -} -},_call:function(_19,_1a){ -var t=this._pseudoAnimation; -t[_19].apply(t,_1a); -},play:function(_1b,_1c){ -this._finished=0; -this._doAction("play",arguments); -this._call("play",arguments); -return this; -},pause:function(){ -this._doAction("pause",arguments); -this._call("pause",arguments); -return this; -},gotoPercent:function(_1d,_1e){ -var ms=this.duration*_1d; -d.forEach(this._animations,function(a){ -a.gotoPercent(a.duration<ms?1:(ms/a.duration),_1e); -}); -this._call("gotoPercent",arguments); -return this; -},stop:function(_1f){ -this._doAction("stop",arguments); -this._call("stop",arguments); -return this; -},status:function(){ -return this._pseudoAnimation.status(); -},destroy:function(){ -d.forEach(this._connects,dojo.disconnect); -}}); -d.extend(_13,_1); -dojo.fx.combine=function(_20){ -return new _13(_20); -}; -dojo.fx.wipeIn=function(_21){ -var _22=_21.node=d.byId(_21.node),s=_22.style,o; -var _23=d.animateProperty(d.mixin({properties:{height:{start:function(){ -o=s.overflow; -s.overflow="hidden"; -if(s.visibility=="hidden"||s.display=="none"){ -s.height="1px"; -s.display=""; -s.visibility=""; -return 1; -}else{ -var _24=d.style(_22,"height"); -return Math.max(_24,1); -} -},end:function(){ -return _22.scrollHeight; -}}}},_21)); -d.connect(_23,"onEnd",function(){ -s.height="auto"; -s.overflow=o; -}); -return _23; -}; -dojo.fx.wipeOut=function(_25){ -var _26=_25.node=d.byId(_25.node),s=_26.style,o; -var _27=d.animateProperty(d.mixin({properties:{height:{end:1}}},_25)); -d.connect(_27,"beforeBegin",function(){ -o=s.overflow; -s.overflow="hidden"; -s.display=""; -}); -d.connect(_27,"onEnd",function(){ -s.overflow=o; -s.height="auto"; -s.display="none"; -}); -return _27; -}; -dojo.fx.slideTo=function(_28){ -var _29=_28.node=d.byId(_28.node),top=null,_2a=null; -var _2b=(function(n){ -return function(){ -var cs=d.getComputedStyle(n); -var pos=cs.position; -top=(pos=="absolute"?n.offsetTop:parseInt(cs.top)||0); -_2a=(pos=="absolute"?n.offsetLeft:parseInt(cs.left)||0); -if(pos!="absolute"&&pos!="relative"){ -var ret=d.position(n,true); -top=ret.y; -_2a=ret.x; -n.style.position="absolute"; -n.style.top=top+"px"; -n.style.left=_2a+"px"; -} -}; -})(_29); -_2b(); -var _2c=d.animateProperty(d.mixin({properties:{top:_28.top||0,left:_28.left||0}},_28)); -d.connect(_2c,"beforeBegin",_2c,_2b); -return _2c; +dojo.require("dojo.fx.Toggler"); // FIXME: remove this back-compat require in 2.0 +/*===== +dojo.fx = { + // summary: Effects library on top of Base animations }; +=====*/ +(function(){ + + var d = dojo, + _baseObj = { + _fire: function(evt, args){ + if(this[evt]){ + this[evt].apply(this, args||[]); + } + return this; + } + }; + + var _chain = function(animations){ + this._index = -1; + this._animations = animations||[]; + this._current = this._onAnimateCtx = this._onEndCtx = null; + + this.duration = 0; + d.forEach(this._animations, function(a){ + this.duration += a.duration; + if(a.delay){ this.duration += a.delay; } + }, this); + }; + d.extend(_chain, { + _onAnimate: function(){ + this._fire("onAnimate", arguments); + }, + _onEnd: function(){ + d.disconnect(this._onAnimateCtx); + d.disconnect(this._onEndCtx); + this._onAnimateCtx = this._onEndCtx = null; + if(this._index + 1 == this._animations.length){ + this._fire("onEnd"); + }else{ + // switch animations + this._current = this._animations[++this._index]; + this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate"); + this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd"); + this._current.play(0, true); + } + }, + play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){ + if(!this._current){ this._current = this._animations[this._index = 0]; } + if(!gotoStart && this._current.status() == "playing"){ return this; } + var beforeBegin = d.connect(this._current, "beforeBegin", this, function(){ + this._fire("beforeBegin"); + }), + onBegin = d.connect(this._current, "onBegin", this, function(arg){ + this._fire("onBegin", arguments); + }), + onPlay = d.connect(this._current, "onPlay", this, function(arg){ + this._fire("onPlay", arguments); + d.disconnect(beforeBegin); + d.disconnect(onBegin); + d.disconnect(onPlay); + }); + if(this._onAnimateCtx){ + d.disconnect(this._onAnimateCtx); + } + this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate"); + if(this._onEndCtx){ + d.disconnect(this._onEndCtx); + } + this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd"); + this._current.play.apply(this._current, arguments); + return this; + }, + pause: function(){ + if(this._current){ + var e = d.connect(this._current, "onPause", this, function(arg){ + this._fire("onPause", arguments); + d.disconnect(e); + }); + this._current.pause(); + } + return this; + }, + gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){ + this.pause(); + var offset = this.duration * percent; + this._current = null; + d.some(this._animations, function(a){ + if(a.duration <= offset){ + this._current = a; + return true; + } + offset -= a.duration; + return false; + }); + if(this._current){ + this._current.gotoPercent(offset / this._current.duration, andPlay); + } + return this; + }, + stop: function(/*boolean?*/ gotoEnd){ + if(this._current){ + if(gotoEnd){ + for(; this._index + 1 < this._animations.length; ++this._index){ + this._animations[this._index].stop(true); + } + this._current = this._animations[this._index]; + } + var e = d.connect(this._current, "onStop", this, function(arg){ + this._fire("onStop", arguments); + d.disconnect(e); + }); + this._current.stop(); + } + return this; + }, + status: function(){ + return this._current ? this._current.status() : "stopped"; + }, + destroy: function(){ + if(this._onAnimateCtx){ d.disconnect(this._onAnimateCtx); } + if(this._onEndCtx){ d.disconnect(this._onEndCtx); } + } + }); + d.extend(_chain, _baseObj); + + dojo.fx.chain = function(/*dojo.Animation[]*/ animations){ + // summary: + // Chain a list of `dojo.Animation`s to run in sequence + // + // description: + // Return a `dojo.Animation` which will play all passed + // `dojo.Animation` instances in sequence, firing its own + // synthesized events simulating a single animation. (eg: + // onEnd of this animation means the end of the chain, + // not the individual animations within) + // + // example: + // Once `node` is faded out, fade in `otherNode` + // | dojo.fx.chain([ + // | dojo.fadeIn({ node:node }), + // | dojo.fadeOut({ node:otherNode }) + // | ]).play(); + // + return new _chain(animations) // dojo.Animation + }; + + var _combine = function(animations){ + this._animations = animations||[]; + this._connects = []; + this._finished = 0; + + this.duration = 0; + d.forEach(animations, function(a){ + var duration = a.duration; + if(a.delay){ duration += a.delay; } + if(this.duration < duration){ this.duration = duration; } + this._connects.push(d.connect(a, "onEnd", this, "_onEnd")); + }, this); + + this._pseudoAnimation = new d.Animation({curve: [0, 1], duration: this.duration}); + var self = this; + d.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"], + function(evt){ + self._connects.push(d.connect(self._pseudoAnimation, evt, + function(){ self._fire(evt, arguments); } + )); + } + ); + }; + d.extend(_combine, { + _doAction: function(action, args){ + d.forEach(this._animations, function(a){ + a[action].apply(a, args); + }); + return this; + }, + _onEnd: function(){ + if(++this._finished > this._animations.length){ + this._fire("onEnd"); + } + }, + _call: function(action, args){ + var t = this._pseudoAnimation; + t[action].apply(t, args); + }, + play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){ + this._finished = 0; + this._doAction("play", arguments); + this._call("play", arguments); + return this; + }, + pause: function(){ + this._doAction("pause", arguments); + this._call("pause", arguments); + return this; + }, + gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){ + var ms = this.duration * percent; + d.forEach(this._animations, function(a){ + a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay); + }); + this._call("gotoPercent", arguments); + return this; + }, + stop: function(/*boolean?*/ gotoEnd){ + this._doAction("stop", arguments); + this._call("stop", arguments); + return this; + }, + status: function(){ + return this._pseudoAnimation.status(); + }, + destroy: function(){ + d.forEach(this._connects, dojo.disconnect); + } + }); + d.extend(_combine, _baseObj); + + dojo.fx.combine = function(/*dojo.Animation[]*/ animations){ + // summary: + // Combine a list of `dojo.Animation`s to run in parallel + // + // description: + // Combine an array of `dojo.Animation`s to run in parallel, + // providing a new `dojo.Animation` instance encompasing each + // animation, firing standard animation events. + // + // example: + // Fade out `node` while fading in `otherNode` simultaneously + // | dojo.fx.combine([ + // | dojo.fadeIn({ node:node }), + // | dojo.fadeOut({ node:otherNode }) + // | ]).play(); + // + // example: + // When the longest animation ends, execute a function: + // | var anim = dojo.fx.combine([ + // | dojo.fadeIn({ node: n, duration:700 }), + // | dojo.fadeOut({ node: otherNode, duration: 300 }) + // | ]); + // | dojo.connect(anim, "onEnd", function(){ + // | // overall animation is done. + // | }); + // | anim.play(); // play the animation + // + return new _combine(animations); // dojo.Animation + }; + + dojo.fx.wipeIn = function(/*Object*/ args){ + // summary: + // Expand a node to it's natural height. + // + // description: + // Returns an animation that will expand the + // node defined in 'args' object from it's current height to + // it's natural height (with no scrollbar). + // Node must have no margin/border/padding. + // + // args: Object + // A hash-map of standard `dojo.Animation` constructor properties + // (such as easing: node: duration: and so on) + // + // example: + // | dojo.fx.wipeIn({ + // | node:"someId" + // | }).play() + var node = args.node = d.byId(args.node), s = node.style, o; + + var anim = d.animateProperty(d.mixin({ + properties: { + height: { + // wrapped in functions so we wait till the last second to query (in case value has changed) + start: function(){ + // start at current [computed] height, but use 1px rather than 0 + // because 0 causes IE to display the whole panel + o = s.overflow; + s.overflow = "hidden"; + if(s.visibility == "hidden" || s.display == "none"){ + s.height = "1px"; + s.display = ""; + s.visibility = ""; + return 1; + }else{ + var height = d.style(node, "height"); + return Math.max(height, 1); + } + }, + end: function(){ + return node.scrollHeight; + } + } + } + }, args)); + + d.connect(anim, "onEnd", function(){ + s.height = "auto"; + s.overflow = o; + }); + + return anim; // dojo.Animation + } + + dojo.fx.wipeOut = function(/*Object*/ args){ + // summary: + // Shrink a node to nothing and hide it. + // + // description: + // Returns an animation that will shrink node defined in "args" + // from it's current height to 1px, and then hide it. + // + // args: Object + // A hash-map of standard `dojo.Animation` constructor properties + // (such as easing: node: duration: and so on) + // + // example: + // | dojo.fx.wipeOut({ node:"someId" }).play() + + var node = args.node = d.byId(args.node), s = node.style, o; + + var anim = d.animateProperty(d.mixin({ + properties: { + height: { + end: 1 // 0 causes IE to display the whole panel + } + } + }, args)); + + d.connect(anim, "beforeBegin", function(){ + o = s.overflow; + s.overflow = "hidden"; + s.display = ""; + }); + d.connect(anim, "onEnd", function(){ + s.overflow = o; + s.height = "auto"; + s.display = "none"; + }); + + return anim; // dojo.Animation + } + + dojo.fx.slideTo = function(/*Object*/ args){ + // summary: + // Slide a node to a new top/left position + // + // description: + // Returns an animation that will slide "node" + // defined in args Object from its current position to + // the position defined by (args.left, args.top). + // + // args: Object + // A hash-map of standard `dojo.Animation` constructor properties + // (such as easing: node: duration: and so on). Special args members + // are `top` and `left`, which indicate the new position to slide to. + // + // example: + // | dojo.fx.slideTo({ node: node, left:"40", top:"50", units:"px" }).play() + + var node = args.node = d.byId(args.node), + top = null, left = null; + + var init = (function(n){ + return function(){ + var cs = d.getComputedStyle(n); + var pos = cs.position; + top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0); + left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0); + if(pos != 'absolute' && pos != 'relative'){ + var ret = d.position(n, true); + top = ret.y; + left = ret.x; + n.style.position="absolute"; + n.style.top=top+"px"; + n.style.left=left+"px"; + } + }; + })(node); + init(); + + var anim = d.animateProperty(d.mixin({ + properties: { + top: args.top || 0, + left: args.left || 0 + } + }, args)); + d.connect(anim, "beforeBegin", anim, init); + + return anim; // dojo.Animation + } + })(); + } |