]>
git.wh0rd.org - tt-rss.git/blob - lib/dojo/_base/fx.js.uncompressed.js
1 define("dojo/_base/fx", ["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"], function(dojo
, lang
, Evented
, Color
, connect
, has
, dom
, style
){
5 // This module defines the base dojo.fx implementation.
7 // Animation loosely package based on Dan Pupius' work, contributed under CLA; see
8 // http://pupius.co.uk/js/Toolkit.Drawing.js
10 var _mixin
= lang
.mixin
;
12 dojo
._Line = function(/*int*/ start
, /*int*/ end
){
14 // dojo._Line is the object used to generate values from a start value
17 // Beginning value for range
19 // Ending value for range
24 dojo
._Line
.prototype.getValue = function(/*float*/ n
){
25 // summary: Returns the point on the line
26 // n: a floating point number greater than 0 and less than 1
27 return ((this.end
- this.start
) * n
) + this.start
; // Decimal
30 dojo
.Animation = function(args
){
32 // A generic animation class that fires callbacks into its handlers
33 // object at various states.
35 // A generic animation class that fires callbacks into its handlers
36 // object at various states. Nearly all dojo animation functions
37 // return an instance of this method, usually without calling the
38 // .play() method beforehand. Therefore, you will likely need to
39 // call .play() on instances of `dojo.Animation` when one is
42 // The 'magic argument', mixing all the properties into this
43 // animation instance.
46 if(lang
.isArray(this.curve
)){
47 this.curve
= new dojo
._Line(this.curve
[0], this.curve
[1]);
51 dojo
.Animation
.prototype = new Evented();
52 // Alias to drop come 2.0:
53 dojo
._Animation
= dojo
.Animation
;
55 lang
.extend(dojo
.Animation
, {
57 // The time in milliseonds the animation will take to run
61 // curve: dojo._Line|Array
62 // A two element array of start and end values, or a `dojo._Line` instance to be
63 // used in the Animation.
67 // A Function to adjust the acceleration (or deceleration) of the progress
68 // across a dojo._Line
73 // The number of times to loop the animation
77 // the time in milliseconds to wait before advancing to next frame
78 // (used as a fps timer: 1000/rate = fps)
79 rate
: 20 /* 50 fps */,
83 // The time in milliseconds to wait before starting animation after it
84 // has been .play()'ed
87 // beforeBegin: Event?
88 // Synthetic event fired before a dojo.Animation begins playing (synchronous)
92 // Synthetic event fired as a dojo.Animation begins playing (useful?)
96 // Synthetic event fired at each interval of a `dojo.Animation`
100 // Synthetic event fired after the final frame of a `dojo.Animation`
104 // Synthetic event fired any time a `dojo.Animation` is play()'ed
108 // Synthetic event fired when a `dojo.Animation` is paused
112 // Synthetic event fires when a `dojo.Animation` is stopped
118 _startRepeatCount
: 0,
120 _getStep: function(){
121 var _p
= this._percent
,
124 return _e
? _e(_p
) : _p
;
126 _fire: function(/*Event*/ evt
, /*Array?*/ args
){
128 // Convenience function. Fire event "evt" and pass it the
129 // arguments specified in "args".
131 // Convenience function. Fire event "evt" and pass it the
132 // arguments specified in "args".
133 // Fires the callback in the scope of the `dojo.Animation`
136 // The event to fire.
138 // The arguments to pass to the event.
141 if(dojo
.config
.debugAtAllCosts
){
142 this[evt
].apply(this, a
);
145 this[evt
].apply(this, a
);
147 // squelch and log because we shouldn't allow exceptions in
148 // synthetic event handlers to cause the internal timer to run
149 // amuck, potentially pegging the CPU. I'm not a fan of this
150 // squelch, but hopefully logging will make it clear what's
152 console
.error("exception in animation handler for:", evt
);
157 return this; // dojo.Animation
160 play: function(/*int?*/ delay
, /*Boolean?*/ gotoStart
){
162 // Start the animation.
164 // How many milliseconds to delay before starting.
166 // If true, starts the animation from the beginning; otherwise,
167 // starts it from its current position.
168 // returns: dojo.Animation
169 // The instance to allow chaining.
172 if(_t
._delayTimer
){ _t
._clearTimer(); }
175 _t
._active
= _t
._paused
= false;
177 }else if(_t
._active
&& !_t
._paused
){
181 _t
._fire("beforeBegin", [_t
.node
]);
183 var de
= delay
|| _t
.delay
,
184 _p
= lang
.hitch(_t
, "_play", gotoStart
);
187 _t
._delayTimer
= setTimeout(_p
, de
);
191 return _t
; // dojo.Animation
194 _play: function(gotoStart
){
196 if(_t
._delayTimer
){ _t
._clearTimer(); }
197 _t
._startTime
= new Date().valueOf();
199 _t
._startTime
-= _t
.duration
* _t
._percent
;
204 var value
= _t
.curve
.getValue(_t
._getStep());
206 if(!_t
._startRepeatCount
){
207 _t
._startRepeatCount
= _t
.repeat
;
209 _t
._fire("onBegin", [value
]);
212 _t
._fire("onPlay", [value
]);
215 return _t
; // dojo.Animation
219 // summary: Pauses a running animation.
221 if(_t
._delayTimer
){ _t
._clearTimer(); }
223 if(!_t
._active
){ return _t
; /*dojo.Animation*/ }
225 _t
._fire("onPause", [_t
.curve
.getValue(_t
._getStep())]);
226 return _t
; // dojo.Animation
229 gotoPercent: function(/*Decimal*/ percent
, /*Boolean?*/ andPlay
){
231 // Sets the progress of the animation.
233 // A percentage in decimal notation (between and including 0.0 and 1.0).
235 // If true, play the animation after setting the progress.
238 _t
._active
= _t
._paused
= true;
239 _t
._percent
= percent
;
240 if(andPlay
){ _t
.play(); }
241 return _t
; // dojo.Animation
244 stop: function(/*boolean?*/ gotoEnd
){
245 // summary: Stops a running animation.
246 // gotoEnd: If true, the animation will end.
248 if(_t
._delayTimer
){ _t
._clearTimer(); }
249 if(!_t
._timer
){ return _t
; /* dojo.Animation */ }
254 _t
._fire("onStop", [_t
.curve
.getValue(_t
._getStep())]);
255 _t
._active
= _t
._paused
= false;
256 return _t
; // dojo.Animation
261 // Returns a string token representation of the status of
262 // the animation, one of: "paused", "playing", "stopped"
264 return this._paused
? "paused" : "playing"; // String
266 return "stopped"; // String
272 var curr
= new Date().valueOf();
273 var step
= (curr
- _t
._startTime
) / (_t
.duration
);
282 step
= _t
.easing(step
);
285 _t
._fire("onAnimate", [_t
.curve
.getValue(step
)]);
295 }else if(_t
.repeat
== -1){
298 if(_t
._startRepeatCount
){
299 _t
.repeat
= _t
._startRepeatCount
;
300 _t
._startRepeatCount
= 0;
304 _t
._fire("onEnd", [_t
.node
]);
305 !_t
.repeat
&& _t
._stopTimer();
308 return _t
; // dojo.Animation
311 _clearTimer: function(){
312 // summary: Clear the play delay timer
313 clearTimeout(this._delayTimer
);
314 delete this._delayTimer
;
319 // the local timer, stubbed into all Animation instances
326 lang
.extend(dojo
.Animation
, {
328 _startTimer: function(){
330 this._timer
= connect
.connect(runner
, "run", this, "_cycle");
334 timer
= setInterval(lang
.hitch(runner
, "run"), this.rate
);
338 _stopTimer: function(){
340 connect
.disconnect(this._timer
);
345 clearInterval(timer
);
354 has("ie") ? function(node
){
355 // only set the zoom if the "tickle" value would be the same as the
358 // don't set the width to auto if it didn't already cascade that way.
359 // We don't want to f anyones designs
360 if(!ns
.width
.length
&& style
.get(node
, "width") == "auto"){
366 dojo
._fade = function(/*Object*/ args
){
368 // Returns an animation that will fade the node defined by
369 // args.node from the start to end values passed (args.start
370 // args.end) (end is mandatory, start is optional)
372 args
.node
= dom
.byId(args
.node
);
373 var fArgs
= _mixin({ properties
: {} }, args
),
374 props
= (fArgs
.properties
.opacity
= {});
376 props
.start
= !("start" in fArgs
) ?
378 return +style
.get(fArgs
.node
, "opacity")||0;
380 props
.end
= fArgs
.end
;
382 var anim
= dojo
.animateProperty(fArgs
);
383 connect
.connect(anim
, "beforeBegin", lang
.partial(_makeFadeable
, fArgs
.node
));
385 return anim
; // dojo.Animation
389 dojo.__FadeArgs = function(node, duration, easing){
390 // node: DOMNode|String
391 // The node referenced in the animation
392 // duration: Integer?
393 // Duration of the animation in milliseconds.
395 // An easing function.
397 this.duration = duration;
398 this.easing = easing;
402 dojo
.fadeIn = function(/*dojo.__FadeArgs*/ args
){
404 // Returns an animation that will fade node defined in 'args' from
405 // its current opacity to fully opaque.
406 return dojo
._fade(_mixin({ end
: 1 }, args
)); // dojo.Animation
409 dojo
.fadeOut = function(/*dojo.__FadeArgs*/ args
){
411 // Returns an animation that will fade node defined in 'args'
412 // from its current opacity to fully transparent.
413 return dojo
._fade(_mixin({ end
: 0 }, args
)); // dojo.Animation
416 dojo
._defaultEasing = function(/*Decimal?*/ n
){
417 // summary: The default easing function for dojo.Animation(s)
418 return 0.5 + ((Math
.sin((n
+ 1.5) * Math
.PI
)) / 2); // Decimal
421 var PropLine = function(properties
){
422 // PropLine is an internal class which is used to model the values of
423 // an a group of CSS properties across an animation lifecycle. In
424 // particular, the "getValue" function handles getting interpolated
425 // values between start and end for a particular CSS value.
426 this._properties
= properties
;
427 for(var p
in properties
){
428 var prop
= properties
[p
];
429 if(prop
.start
instanceof Color
){
430 // create a reusable temp color object to keep intermediate results
431 prop
.tempColor
= new Color();
436 PropLine
.prototype.getValue = function(r
){
438 for(var p
in this._properties
){
439 var prop
= this._properties
[p
],
441 if(start
instanceof Color
){
442 ret
[p
] = Color
.blendColors(start
, prop
.end
, r
, prop
.tempColor
).toCss();
443 }else if(!lang
.isArray(start
)){
444 ret
[p
] = ((prop
.end
- start
) * r
) + start
+ (p
!= "opacity" ? prop
.units
|| "px" : 0);
451 dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
452 // Properties: Object?
453 // A hash map of style properties to Objects describing the transition,
454 // such as the properties of dojo._Line with an additional 'units' property
457 //TODOC: add event callbacks
461 dojo
.animateProperty = function(/*dojo.__AnimArgs*/ args
){
463 // Returns an animation that will transition the properties of
464 // node defined in `args` depending how they are defined in
468 // `dojo.animateProperty` is the foundation of most `dojo.fx`
469 // animations. It takes an object of "properties" corresponding to
470 // style properties, and animates them in parallel over a set
474 // A simple animation that changes the width of the specified node.
475 // | dojo.animateProperty({
477 // | properties: { width: 400 },
479 // Dojo figures out the start value for the width and converts the
480 // integer specified for the width to the more expressive but
481 // verbose form `{ width: { end: '400', units: 'px' } }` which you
482 // can also specify directly. Defaults to 'px' if ommitted.
485 // Animate width, height, and padding over 2 seconds... the
487 // | dojo.animateProperty({ node: node, duration:2000,
489 // | width: { start: '200', end: '400', units:"px" },
490 // | height: { start:'200', end: '400', units:"px" },
491 // | paddingTop: { start:'5', end:'50', units:"px" }
494 // Note 'paddingTop' is used over 'padding-top'. Multi-name CSS properties
495 // are written using "mixed case", as the hyphen is illegal as an object key.
498 // Plug in a different easing function and register a callback for
499 // when the animation ends. Easing functions accept values between
500 // zero and one and return a value on that basis. In this case, an
501 // exponential-in curve.
502 // | dojo.animateProperty({
504 // | // dojo figures out the start value
505 // | properties: { width: { end: 400 } },
506 // | easing: function(n){
507 // | return (n==0) ? 0 : Math.pow(2, 10 * (n - 1));
509 // | onEnd: function(node){
510 // | // called when the animation finishes. The animation
511 // | // target is passed to this function
513 // | }).play(500); // delay playing half a second
516 // Like all `dojo.Animation`s, animateProperty returns a handle to the
517 // Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
518 // to access these events outside of the Animation definiton:
519 // | var anim = dojo.animateProperty({
522 // | width:400, height:500
525 // | dojo.connect(anim,"onEnd", function(){
526 // | console.log("animation ended");
528 // | // play the animation now:
532 // Each property can be a function whose return value is substituted along.
533 // Additionally, each measurement (eg: start, end) can be a function. The node
534 // reference is passed direcly to callbacks.
535 // | dojo.animateProperty({
538 // | height:function(node){
539 // | // shrink this node by 50%
540 // | return dojo.position(node).h / 2
543 // | start:function(node){ return 100; },
544 // | end:function(node){ return 200; }
550 var n
= args
.node
= dom
.byId(args
.node
);
551 if(!args
.easing
){ args
.easing
= dojo
._defaultEasing
; }
553 var anim
= new dojo
.Animation(args
);
554 connect
.connect(anim
, "beforeBegin", anim
, function(){
556 for(var p
in this.properties
){
557 // Make shallow copy of properties into pm because we overwrite
558 // some values below. In particular if start/end are functions
559 // we don't want to overwrite them or the functions won't be
560 // called if the animation is reused.
561 if(p
== "width" || p
== "height"){
562 this.node
.display
= "block";
564 var prop
= this.properties
[p
];
565 if(lang
.isFunction(prop
)){
568 prop
= pm
[p
] = _mixin({}, (lang
.isObject(prop
) ? prop
: { end
: prop
}));
570 if(lang
.isFunction(prop
.start
)){
571 prop
.start
= prop
.start(n
);
573 if(lang
.isFunction(prop
.end
)){
574 prop
.end
= prop
.end(n
);
576 var isColor
= (p
.toLowerCase().indexOf("color") >= 0);
577 function getStyle(node
, p
){
578 // dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
579 var v
= { height
: node
.offsetHeight
, width
: node
.offsetWidth
}[p
];
580 if(v
!== undefined){ return v
; }
581 v
= style
.get(node
, p
);
582 return (p
== "opacity") ? +v
: (isColor
? v
: parseFloat(v
));
584 if(!("end" in prop
)){
585 prop
.end
= getStyle(n
, p
);
586 }else if(!("start" in prop
)){
587 prop
.start
= getStyle(n
, p
);
591 prop
.start
= new Color(prop
.start
);
592 prop
.end
= new Color(prop
.end
);
594 prop
.start
= (p
== "opacity") ? +prop
.start
: parseFloat(prop
.start
);
597 this.curve
= new PropLine(pm
);
599 connect
.connect(anim
, "onAnimate", lang
.hitch(style
, "set", anim
.node
));
600 return anim
; // dojo.Animation
603 dojo
.anim = function( /*DOMNode|String*/ node
,
604 /*Object*/ properties
,
605 /*Integer?*/ duration
,
606 /*Function?*/ easing
,
610 // A simpler interface to `dojo.animateProperty()`, also returns
611 // an instance of `dojo.Animation` but begins the animation
612 // immediately, unlike nearly every other Dojo animation API.
614 // `dojo.anim` is a simpler (but somewhat less powerful) version
615 // of `dojo.animateProperty`. It uses defaults for many basic properties
616 // and allows for positional parameters to be used in place of the
617 // packed "property bag" which is used for other Dojo animation
620 // The `dojo.Animation` object returned from `dojo.anim` will be
621 // already playing when it is returned from this function, so
622 // calling play() on it again is (usually) a no-op.
624 // a DOM node or the id of a node to animate CSS properties on
626 // The number of milliseconds over which the animation
627 // should run. Defaults to the global animation default duration
630 // An easing function over which to calculate acceleration
631 // and deceleration of the animation through its duration.
632 // A default easing algorithm is provided, but you may
633 // plug in any you wish. A large selection of easing algorithms
634 // are available in `dojo.fx.easing`.
636 // A function to be called when the animation finishes
639 // The number of milliseconds to delay beginning the
640 // animation by. The default is 0.
643 // | dojo.anim("id", { opacity: 0 });
645 // Fade out a node over a full second
646 // | dojo.anim("id", { opacity: 0 }, 1000);
647 return dojo
.animateProperty({ // dojo.Animation
649 duration
: duration
|| dojo
.Animation
.prototype.duration
,
650 properties
: properties
,
658 Animation
: dojo
.Animation
,
661 fadeOut
: dojo
.fadeOut
,
662 _defaultEasing
: dojo
._defaultEasing
,
663 animateProperty
: dojo
.animateProperty
,