summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI/animation.js
Unidiff
Diffstat (limited to 'frontend/beta/js/YUI/animation.js') (more/less context) (show whitespace changes)
-rw-r--r--frontend/beta/js/YUI/animation.js1272
1 files changed, 1272 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI/animation.js b/frontend/beta/js/YUI/animation.js
new file mode 100644
index 0000000..333f946
--- a/dev/null
+++ b/frontend/beta/js/YUI/animation.js
@@ -0,0 +1,1272 @@
1/*
2Copyright (c) 2006, Yahoo! Inc. All rights reserved.
3Code licensed under the BSD License:
4http://developer.yahoo.net/yui/license.txt
5version: 0.12.0
6*/
7
8/**
9 * The animation module provides allows effects to be added to HTMLElements.
10 * @module animation
11 */
12
13/**
14 *
15 * Base animation class that provides the interface for building animated effects.
16 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
17 * @class Anim
18 * @namespace YAHOO.util
19 * @requires YAHOO.util.AnimMgr
20 * @requires YAHOO.util.Easing
21 * @requires YAHOO.util.Dom
22 * @requires YAHOO.util.Event
23 * @requires YAHOO.util.CustomEvent
24 * @constructor
25 * @param {String | HTMLElement} el Reference to the element that will be animated
26 * @param {Object} attributes The attribute(s) to be animated.
27 * Each attribute is an object with at minimum a "to" or "by" member defined.
28 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
29 * All attribute names use camelCase.
30 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
31 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
32 */
33
34YAHOO.util.Anim = function(el, attributes, duration, method) {
35 if (el) {
36 this.init(el, attributes, duration, method);
37 }
38};
39
40YAHOO.util.Anim.prototype = {
41 /**
42 * Provides a readable name for the Anim instance.
43 * @method toString
44 * @return {String}
45 */
46 toString: function() {
47 var el = this.getEl();
48 var id = el.id || el.tagName;
49 return ("Anim " + id);
50 },
51
52 patterns: { // cached for performance
53 noNegatives: /width|height|opacity|padding/i, // keep at zero or above
54 offsetAttribute: /^((width|height)|(top|left))$/, // use offsetValue as default
55 defaultUnit: /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
56 offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
57 },
58
59 /**
60 * Returns the value computed by the animation's "method".
61 * @method doMethod
62 * @param {String} attr The name of the attribute.
63 * @param {Number} start The value this attribute should start from for this animation.
64 * @param {Number} end The value this attribute should end at for this animation.
65 * @return {Number} The Value to be applied to the attribute.
66 */
67 doMethod: function(attr, start, end) {
68 return this.method(this.currentFrame, start, end - start, this.totalFrames);
69 },
70
71 /**
72 * Applies a value to an attribute.
73 * @method setAttribute
74 * @param {String} attr The name of the attribute.
75 * @param {Number} val The value to be applied to the attribute.
76 * @param {String} unit The unit ('px', '%', etc.) of the value.
77 */
78 setAttribute: function(attr, val, unit) {
79 if ( this.patterns.noNegatives.test(attr) ) {
80 val = (val > 0) ? val : 0;
81 }
82
83 YAHOO.util.Dom.setStyle(this.getEl(), attr, val + unit);
84 },
85
86 /**
87 * Returns current value of the attribute.
88 * @method getAttribute
89 * @param {String} attr The name of the attribute.
90 * @return {Number} val The current value of the attribute.
91 */
92 getAttribute: function(attr) {
93 var el = this.getEl();
94 var val = YAHOO.util.Dom.getStyle(el, attr);
95
96 if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
97 return parseFloat(val);
98 }
99
100 var a = this.patterns.offsetAttribute.exec(attr) || [];
101 var pos = !!( a[3] ); // top or left
102 var box = !!( a[2] ); // width or height
103
104 // use offsets for width/height and abs pos top/left
105 if ( box || (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
106 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
107 } else { // default to zero for other 'auto'
108 val = 0;
109 }
110
111 return val;
112 },
113
114 /**
115 * Returns the unit to use when none is supplied.
116 * @method getDefaultUnit
117 * @param {attr} attr The name of the attribute.
118 * @return {String} The default unit to be used.
119 */
120 getDefaultUnit: function(attr) {
121 if ( this.patterns.defaultUnit.test(attr) ) {
122 return 'px';
123 }
124
125 return '';
126 },
127
128 /**
129 * Sets the actual values to be used during the animation.
130 * @method setRuntimeAttribute
131 * Should only be needed for subclass use.
132 * @param {Object} attr The attribute object
133 * @private
134 */
135 setRuntimeAttribute: function(attr) {
136 var start;
137 var end;
138 var attributes = this.attributes;
139
140 this.runtimeAttributes[attr] = {};
141
142 var isset = function(prop) {
143 return (typeof prop !== 'undefined');
144 };
145
146 if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
147 return false; // note return; nothing to animate to
148 }
149
150 start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
151
152 // To beats by, per SMIL 2.1 spec
153 if ( isset(attributes[attr]['to']) ) {
154 end = attributes[attr]['to'];
155 } else if ( isset(attributes[attr]['by']) ) {
156 if (start.constructor == Array) {
157 end = [];
158 for (var i = 0, len = start.length; i < len; ++i) {
159 end[i] = start[i] + attributes[attr]['by'][i];
160 }
161 } else {
162 end = start + attributes[attr]['by'];
163 }
164 }
165
166 this.runtimeAttributes[attr].start = start;
167 this.runtimeAttributes[attr].end = end;
168
169 // set units if needed
170 this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ? attributes[attr]['unit'] : this.getDefaultUnit(attr);
171 },
172
173 /**
174 * Constructor for Anim instance.
175 * @method init
176 * @param {String | HTMLElement} el Reference to the element that will be animated
177 * @param {Object} attributes The attribute(s) to be animated.
178 * Each attribute is an object with at minimum a "to" or "by" member defined.
179 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
180 * All attribute names use camelCase.
181 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
182 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
183 */
184 init: function(el, attributes, duration, method) {
185 /**
186 * Whether or not the animation is running.
187 * @property isAnimated
188 * @private
189 * @type Boolean
190 */
191 var isAnimated = false;
192
193 /**
194 * A Date object that is created when the animation begins.
195 * @property startTime
196 * @private
197 * @type Date
198 */
199 var startTime = null;
200
201 /**
202 * The number of frames this animation was able to execute.
203 * @property actualFrames
204 * @private
205 * @type Int
206 */
207 var actualFrames = 0;
208
209 /**
210 * The element to be animated.
211 * @property el
212 * @private
213 * @type HTMLElement
214 */
215 el = YAHOO.util.Dom.get(el);
216
217 /**
218 * The collection of attributes to be animated.
219 * Each attribute must have at least a "to" or "by" defined in order to animate.
220 * If "to" is supplied, the animation will end with the attribute at that value.
221 * If "by" is supplied, the animation will end at that value plus its starting value.
222 * If both are supplied, "to" is used, and "by" is ignored.
223 * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
224 * @property attributes
225 * @type Object
226 */
227 this.attributes = attributes || {};
228
229 /**
230 * The length of the animation. Defaults to "1" (second).
231 * @property duration
232 * @type Number
233 */
234 this.duration = duration || 1;
235
236 /**
237 * The method that will provide values to the attribute(s) during the animation.
238 * Defaults to "YAHOO.util.Easing.easeNone".
239 * @property method
240 * @type Function
241 */
242 this.method = method || YAHOO.util.Easing.easeNone;
243
244 /**
245 * Whether or not the duration should be treated as seconds.
246 * Defaults to true.
247 * @property useSeconds
248 * @type Boolean
249 */
250 this.useSeconds = true; // default to seconds
251
252 /**
253 * The location of the current animation on the timeline.
254 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
255 * @property currentFrame
256 * @type Int
257 */
258 this.currentFrame = 0;
259
260 /**
261 * The total number of frames to be executed.
262 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
263 * @property totalFrames
264 * @type Int
265 */
266 this.totalFrames = YAHOO.util.AnimMgr.fps;
267
268
269 /**
270 * Returns a reference to the animated element.
271 * @method getEl
272 * @return {HTMLElement}
273 */
274 this.getEl = function() { return el; };
275
276 /**
277 * Checks whether the element is currently animated.
278 * @method isAnimated
279 * @return {Boolean} current value of isAnimated.
280 */
281 this.isAnimated = function() {
282 return isAnimated;
283 };
284
285 /**
286 * Returns the animation start time.
287 * @method getStartTime
288 * @return {Date} current value of startTime.
289 */
290 this.getStartTime = function() {
291 return startTime;
292 };
293
294 this.runtimeAttributes = {};
295
296
297
298 /**
299 * Starts the animation by registering it with the animation manager.
300 * @method animate
301 */
302 this.animate = function() {
303 if ( this.isAnimated() ) { return false; }
304
305 this.currentFrame = 0;
306
307 this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
308
309 YAHOO.util.AnimMgr.registerElement(this);
310 };
311
312 /**
313 * Stops the animation. Normally called by AnimMgr when animation completes.
314 * @method stop
315 * @param {Boolean} finish (optional) If true, animation will jump to final frame.
316 */
317 this.stop = function(finish) {
318 if (finish) {
319 this.currentFrame = this.totalFrames;
320 this._onTween.fire();
321 }
322 YAHOO.util.AnimMgr.stop(this);
323 };
324
325 var onStart = function() {
326 this.onStart.fire();
327
328 this.runtimeAttributes = {};
329 for (var attr in this.attributes) {
330 this.setRuntimeAttribute(attr);
331 }
332
333 isAnimated = true;
334 actualFrames = 0;
335 startTime = new Date();
336 };
337
338 /**
339 * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
340 * @private
341 */
342
343 var onTween = function() {
344 var data = {
345 duration: new Date() - this.getStartTime(),
346 currentFrame: this.currentFrame
347 };
348
349 data.toString = function() {
350 return (
351 'duration: ' + data.duration +
352 ', currentFrame: ' + data.currentFrame
353 );
354 };
355
356 this.onTween.fire(data);
357
358 var runtimeAttributes = this.runtimeAttributes;
359
360 for (var attr in runtimeAttributes) {
361 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
362 }
363
364 actualFrames += 1;
365 };
366
367 var onComplete = function() {
368 var actual_duration = (new Date() - startTime) / 1000 ;
369
370 var data = {
371 duration: actual_duration,
372 frames: actualFrames,
373 fps: actualFrames / actual_duration
374 };
375
376 data.toString = function() {
377 return (
378 'duration: ' + data.duration +
379 ', frames: ' + data.frames +
380 ', fps: ' + data.fps
381 );
382 };
383
384 isAnimated = false;
385 actualFrames = 0;
386 this.onComplete.fire(data);
387 };
388
389 /**
390 * Custom event that fires after onStart, useful in subclassing
391 * @private
392 */
393 this._onStart = new YAHOO.util.CustomEvent('_start', this, true);
394
395 /**
396 * Custom event that fires when animation begins
397 * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
398 * @event onStart
399 */
400 this.onStart = new YAHOO.util.CustomEvent('start', this);
401
402 /**
403 * Custom event that fires between each frame
404 * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
405 * @event onTween
406 */
407 this.onTween = new YAHOO.util.CustomEvent('tween', this);
408
409 /**
410 * Custom event that fires after onTween
411 * @private
412 */
413 this._onTween = new YAHOO.util.CustomEvent('_tween', this, true);
414
415 /**
416 * Custom event that fires when animation ends
417 * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
418 * @event onComplete
419 */
420 this.onComplete = new YAHOO.util.CustomEvent('complete', this);
421 /**
422 * Custom event that fires after onComplete
423 * @private
424 */
425 this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true);
426
427 this._onStart.subscribe(onStart);
428 this._onTween.subscribe(onTween);
429 this._onComplete.subscribe(onComplete);
430 }
431};
432
433/**
434 * Handles animation queueing and threading.
435 * Used by Anim and subclasses.
436 * @class AnimMgr
437 * @namespace YAHOO.util
438 */
439YAHOO.util.AnimMgr = new function() {
440 /**
441 * Reference to the animation Interval.
442 * @property thread
443 * @private
444 * @type Int
445 */
446 var thread = null;
447
448 /**
449 * The current queue of registered animation objects.
450 * @property queue
451 * @private
452 * @type Array
453 */
454 var queue = [];
455
456 /**
457 * The number of active animations.
458 * @property tweenCount
459 * @private
460 * @type Int
461 */
462 var tweenCount = 0;
463
464 /**
465 * Base frame rate (frames per second).
466 * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
467 * @property fps
468 * @type Int
469 *
470 */
471 this.fps = 200;
472
473 /**
474 * Interval delay in milliseconds, defaults to fastest possible.
475 * @property delay
476 * @type Int
477 *
478 */
479 this.delay = 1;
480
481 /**
482 * Adds an animation instance to the animation queue.
483 * All animation instances must be registered in order to animate.
484 * @method registerElement
485 * @param {object} tween The Anim instance to be be registered
486 */
487 this.registerElement = function(tween) {
488 queue[queue.length] = tween;
489 tweenCount += 1;
490 tween._onStart.fire();
491 this.start();
492 };
493
494 /**
495 * removes an animation instance from the animation queue.
496 * All animation instances must be registered in order to animate.
497 * @method unRegister
498 * @param {object} tween The Anim instance to be be registered
499 * @param {Int} index The index of the Anim instance
500 * @private
501 */
502 this.unRegister = function(tween, index) {
503 tween._onComplete.fire();
504 index = index || getIndex(tween);
505 if (index != -1) { queue.splice(index, 1); }
506
507 tweenCount -= 1;
508 if (tweenCount <= 0) { this.stop(); }
509 };
510
511 /**
512 * Starts the animation thread.
513 * Only one thread can run at a time.
514 * @method start
515 */
516 this.start = function() {
517 if (thread === null) { thread = setInterval(this.run, this.delay); }
518 };
519
520 /**
521 * Stops the animation thread or a specific animation instance.
522 * @method stop
523 * @param {object} tween A specific Anim instance to stop (optional)
524 * If no instance given, Manager stops thread and all animations.
525 */
526 this.stop = function(tween) {
527 if (!tween) {
528 clearInterval(thread);
529 for (var i = 0, len = queue.length; i < len; ++i) {
530 if (queue[i].isAnimated()) {
531 this.unRegister(tween, i);
532 }
533 }
534 queue = [];
535 thread = null;
536 tweenCount = 0;
537 }
538 else {
539 this.unRegister(tween);
540 }
541 };
542
543 /**
544 * Called per Interval to handle each animation frame.
545 * @method run
546 */
547 this.run = function() {
548 for (var i = 0, len = queue.length; i < len; ++i) {
549 var tween = queue[i];
550 if ( !tween || !tween.isAnimated() ) { continue; }
551
552 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
553 {
554 tween.currentFrame += 1;
555
556 if (tween.useSeconds) {
557 correctFrame(tween);
558 }
559 tween._onTween.fire();
560 }
561 else { YAHOO.util.AnimMgr.stop(tween, i); }
562 }
563 };
564
565 var getIndex = function(anim) {
566 for (var i = 0, len = queue.length; i < len; ++i) {
567 if (queue[i] == anim) {
568 return i; // note return;
569 }
570 }
571 return -1;
572 };
573
574 /**
575 * On the fly frame correction to keep animation on time.
576 * @method correctFrame
577 * @private
578 * @param {Object} tween The Anim instance being corrected.
579 */
580 var correctFrame = function(tween) {
581 var frames = tween.totalFrames;
582 var frame = tween.currentFrame;
583 var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
584 var elapsed = (new Date() - tween.getStartTime());
585 var tweak = 0;
586
587 if (elapsed < tween.duration * 1000) { // check if falling behind
588 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
589 } else { // went over duration, so jump to end
590 tweak = frames - (frame + 1);
591 }
592 if (tweak > 0 && isFinite(tweak)) { // adjust if needed
593 if (tween.currentFrame + tweak >= frames) {// dont go past last frame
594 tweak = frames - (frame + 1);
595 }
596
597 tween.currentFrame += tweak;
598 }
599 };
600};
601/**
602 * Used to calculate Bezier splines for any number of control points.
603 * @class Bezier
604 * @namespace YAHOO.util
605 *
606 */
607YAHOO.util.Bezier = new function()
608{
609 /**
610 * Get the current position of the animated element based on t.
611 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
612 * At least 2 points are required (start and end).
613 * First point is start. Last point is end.
614 * Additional control points are optional.
615 * @method getPosition
616 * @param {Array} points An array containing Bezier points
617 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
618 * @return {Array} An array containing int x and y member data
619 */
620 this.getPosition = function(points, t)
621 {
622 var n = points.length;
623 var tmp = [];
624
625 for (var i = 0; i < n; ++i){
626 tmp[i] = [points[i][0], points[i][1]]; // save input
627 }
628
629 for (var j = 1; j < n; ++j) {
630 for (i = 0; i < n - j; ++i) {
631 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
632 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
633 }
634 }
635
636 return [ tmp[0][0], tmp[0][1] ];
637
638 };
639};
640/**
641 * Anim subclass for color transitions.
642 * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233,
643 * [255,255,255], or rgb(255,255,255)</p>
644 * @class ColorAnim
645 * @namespace YAHOO.util
646 * @requires YAHOO.util.Anim
647 * @requires YAHOO.util.AnimMgr
648 * @requires YAHOO.util.Easing
649 * @requires YAHOO.util.Bezier
650 * @requires YAHOO.util.Dom
651 * @requires YAHOO.util.Event
652 * @constructor
653 * @extends YAHOO.util.Anim
654 * @param {HTMLElement | String} el Reference to the element that will be animated
655 * @param {Object} attributes The attribute(s) to be animated.
656 * Each attribute is an object with at minimum a "to" or "by" member defined.
657 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
658 * All attribute names use camelCase.
659 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
660 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
661 */
662(function() {
663 YAHOO.util.ColorAnim = function(el, attributes, duration, method) {
664 YAHOO.util.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
665 };
666
667 YAHOO.extend(YAHOO.util.ColorAnim, YAHOO.util.Anim);
668
669 // shorthand
670 var Y = YAHOO.util;
671 var superclass = Y.ColorAnim.superclass;
672 var proto = Y.ColorAnim.prototype;
673
674 proto.toString = function() {
675 var el = this.getEl();
676 var id = el.id || el.tagName;
677 return ("ColorAnim " + id);
678 };
679
680 proto.patterns.color = /color$/i;
681 proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
682 proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
683 proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
684 proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
685
686 /**
687 * Attempts to parse the given string and return a 3-tuple.
688 * @method parseColor
689 * @param {String} s The string to parse.
690 * @return {Array} The 3-tuple of rgb values.
691 */
692 proto.parseColor = function(s) {
693 if (s.length == 3) { return s; }
694
695 var c = this.patterns.hex.exec(s);
696 if (c && c.length == 4) {
697 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
698 }
699
700 c = this.patterns.rgb.exec(s);
701 if (c && c.length == 4) {
702 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
703 }
704
705 c = this.patterns.hex3.exec(s);
706 if (c && c.length == 4) {
707 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
708 }
709
710 return null;
711 };
712
713 proto.getAttribute = function(attr) {
714 var el = this.getEl();
715 if ( this.patterns.color.test(attr) ) {
716 var val = YAHOO.util.Dom.getStyle(el, attr);
717
718 if (this.patterns.transparent.test(val)) { // bgcolor default
719 var parent = el.parentNode; // try and get from an ancestor
720 val = Y.Dom.getStyle(parent, attr);
721
722 while (parent && this.patterns.transparent.test(val)) {
723 parent = parent.parentNode;
724 val = Y.Dom.getStyle(parent, attr);
725 if (parent.tagName.toUpperCase() == 'HTML') {
726 val = '#fff';
727 }
728 }
729 }
730 } else {
731 val = superclass.getAttribute.call(this, attr);
732 }
733
734 return val;
735 };
736
737 proto.doMethod = function(attr, start, end) {
738 var val;
739
740 if ( this.patterns.color.test(attr) ) {
741 val = [];
742 for (var i = 0, len = start.length; i < len; ++i) {
743 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
744 }
745
746 val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
747 }
748 else {
749 val = superclass.doMethod.call(this, attr, start, end);
750 }
751
752 return val;
753 };
754
755 proto.setRuntimeAttribute = function(attr) {
756 superclass.setRuntimeAttribute.call(this, attr);
757
758 if ( this.patterns.color.test(attr) ) {
759 var attributes = this.attributes;
760 var start = this.parseColor(this.runtimeAttributes[attr].start);
761 var end = this.parseColor(this.runtimeAttributes[attr].end);
762 // fix colors if going "by"
763 if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
764 end = this.parseColor(attributes[attr].by);
765
766 for (var i = 0, len = start.length; i < len; ++i) {
767 end[i] = start[i] + end[i];
768 }
769 }
770
771 this.runtimeAttributes[attr].start = start;
772 this.runtimeAttributes[attr].end = end;
773 }
774 };
775})();/*
776TERMS OF USE - EASING EQUATIONS
777Open source under the BSD License.
778Copyright 2001 Robert Penner All rights reserved.
779
780Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
781
782 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
783 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
784 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
785
786THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
787*/
788
789/**
790 * Singleton that determines how an animation proceeds from start to end.
791 * @class Easing
792 * @namespace YAHOO.util
793*/
794
795YAHOO.util.Easing = {
796
797 /**
798 * Uniform speed between points.
799 * @method easeNone
800 * @param {Number} t Time value used to compute current value
801 * @param {Number} b Starting value
802 * @param {Number} c Delta between start and end values
803 * @param {Number} d Total length of animation
804 * @return {Number} The computed value for the current animation frame
805 */
806 easeNone: function (t, b, c, d) {
807 return c*t/d + b;
808 },
809
810 /**
811 * Begins slowly and accelerates towards end. (quadratic)
812 * @method easeIn
813 * @param {Number} t Time value used to compute current value
814 * @param {Number} b Starting value
815 * @param {Number} c Delta between start and end values
816 * @param {Number} d Total length of animation
817 * @return {Number} The computed value for the current animation frame
818 */
819 easeIn: function (t, b, c, d) {
820 return c*(t/=d)*t + b;
821 },
822
823 /**
824 * Begins quickly and decelerates towards end. (quadratic)
825 * @method easeOut
826 * @param {Number} t Time value used to compute current value
827 * @param {Number} b Starting value
828 * @param {Number} c Delta between start and end values
829 * @param {Number} d Total length of animation
830 * @return {Number} The computed value for the current animation frame
831 */
832 easeOut: function (t, b, c, d) {
833 return -c *(t/=d)*(t-2) + b;
834 },
835
836 /**
837 * Begins slowly and decelerates towards end. (quadratic)
838 * @method easeBoth
839 * @param {Number} t Time value used to compute current value
840 * @param {Number} b Starting value
841 * @param {Number} c Delta between start and end values
842 * @param {Number} d Total length of animation
843 * @return {Number} The computed value for the current animation frame
844 */
845 easeBoth: function (t, b, c, d) {
846 if ((t/=d/2) < 1) return c/2*t*t + b;
847 return -c/2 * ((--t)*(t-2) - 1) + b;
848 },
849
850 /**
851 * Begins slowly and accelerates towards end. (quartic)
852 * @method easeInStrong
853 * @param {Number} t Time value used to compute current value
854 * @param {Number} b Starting value
855 * @param {Number} c Delta between start and end values
856 * @param {Number} d Total length of animation
857 * @return {Number} The computed value for the current animation frame
858 */
859 easeInStrong: function (t, b, c, d) {
860 return c*(t/=d)*t*t*t + b;
861 },
862
863 /**
864 * Begins quickly and decelerates towards end. (quartic)
865 * @method easeOutStrong
866 * @param {Number} t Time value used to compute current value
867 * @param {Number} b Starting value
868 * @param {Number} c Delta between start and end values
869 * @param {Number} d Total length of animation
870 * @return {Number} The computed value for the current animation frame
871 */
872 easeOutStrong: function (t, b, c, d) {
873 return -c * ((t=t/d-1)*t*t*t - 1) + b;
874 },
875
876 /**
877 * Begins slowly and decelerates towards end. (quartic)
878 * @method easeBothStrong
879 * @param {Number} t Time value used to compute current value
880 * @param {Number} b Starting value
881 * @param {Number} c Delta between start and end values
882 * @param {Number} d Total length of animation
883 * @return {Number} The computed value for the current animation frame
884 */
885 easeBothStrong: function (t, b, c, d) {
886 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
887 return -c/2 * ((t-=2)*t*t*t - 2) + b;
888 },
889
890 /**
891 * Snap in elastic effect.
892 * @method elasticIn
893 * @param {Number} t Time value used to compute current value
894 * @param {Number} b Starting value
895 * @param {Number} c Delta between start and end values
896 * @param {Number} d Total length of animation
897 * @param {Number} p Period (optional)
898 * @return {Number} The computed value for the current animation frame
899 */
900
901 elasticIn: function (t, b, c, d, a, p) {
902 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
903 if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
904 else var s = p/(2*Math.PI) * Math.asin (c/a);
905 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
906 },
907
908 /**
909 * Snap out elastic effect.
910 * @method elasticOut
911 * @param {Number} t Time value used to compute current value
912 * @param {Number} b Starting value
913 * @param {Number} c Delta between start and end values
914 * @param {Number} d Total length of animation
915 * @param {Number} p Period (optional)
916 * @return {Number} The computed value for the current animation frame
917 */
918 elasticOut: function (t, b, c, d, a, p) {
919 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
920 if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
921 else var s = p/(2*Math.PI) * Math.asin (c/a);
922 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
923 },
924
925 /**
926 * Snap both elastic effect.
927 * @method elasticBoth
928 * @param {Number} t Time value used to compute current value
929 * @param {Number} b Starting value
930 * @param {Number} c Delta between start and end values
931 * @param {Number} d Total length of animation
932 * @param {Number} p Period (optional)
933 * @return {Number} The computed value for the current animation frame
934 */
935 elasticBoth: function (t, b, c, d, a, p) {
936 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
937 if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
938 else var s = p/(2*Math.PI) * Math.asin (c/a);
939 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
940 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
941 },
942
943 /**
944 * Backtracks slightly, then reverses direction and moves to end.
945 * @method backIn
946 * @param {Number} t Time value used to compute current value
947 * @param {Number} b Starting value
948 * @param {Number} c Delta between start and end values
949 * @param {Number} d Total length of animation
950 * @param {Number} s Overshoot (optional)
951 * @return {Number} The computed value for the current animation frame
952 */
953 backIn: function (t, b, c, d, s) {
954 if (typeof s == 'undefined') s = 1.70158;
955 return c*(t/=d)*t*((s+1)*t - s) + b;
956 },
957
958 /**
959 * Overshoots end, then reverses and comes back to end.
960 * @method backOut
961 * @param {Number} t Time value used to compute current value
962 * @param {Number} b Starting value
963 * @param {Number} c Delta between start and end values
964 * @param {Number} d Total length of animation
965 * @param {Number} s Overshoot (optional)
966 * @return {Number} The computed value for the current animation frame
967 */
968 backOut: function (t, b, c, d, s) {
969 if (typeof s == 'undefined') s = 1.70158;
970 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
971 },
972
973 /**
974 * Backtracks slightly, then reverses direction, overshoots end,
975 * then reverses and comes back to end.
976 * @method backBoth
977 * @param {Number} t Time value used to compute current value
978 * @param {Number} b Starting value
979 * @param {Number} c Delta between start and end values
980 * @param {Number} d Total length of animation
981 * @param {Number} s Overshoot (optional)
982 * @return {Number} The computed value for the current animation frame
983 */
984 backBoth: function (t, b, c, d, s) {
985 if (typeof s == 'undefined') s = 1.70158;
986 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
987 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
988 },
989
990 /**
991 * Bounce off of start.
992 * @method bounceIn
993 * @param {Number} t Time value used to compute current value
994 * @param {Number} b Starting value
995 * @param {Number} c Delta between start and end values
996 * @param {Number} d Total length of animation
997 * @return {Number} The computed value for the current animation frame
998 */
999 bounceIn: function (t, b, c, d) {
1000 return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
1001 },
1002
1003 /**
1004 * Bounces off end.
1005 * @method bounceOut
1006 * @param {Number} t Time value used to compute current value
1007 * @param {Number} b Starting value
1008 * @param {Number} c Delta between start and end values
1009 * @param {Number} d Total length of animation
1010 * @return {Number} The computed value for the current animation frame
1011 */
1012 bounceOut: function (t, b, c, d) {
1013 if ((t/=d) < (1/2.75)) {
1014 return c*(7.5625*t*t) + b;
1015 } else if (t < (2/2.75)) {
1016 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1017 } else if (t < (2.5/2.75)) {
1018 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1019 } else {
1020 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1021 }
1022 },
1023
1024 /**
1025 * Bounces off start and end.
1026 * @method bounceBoth
1027 * @param {Number} t Time value used to compute current value
1028 * @param {Number} b Starting value
1029 * @param {Number} c Delta between start and end values
1030 * @param {Number} d Total length of animation
1031 * @return {Number} The computed value for the current animation frame
1032 */
1033 bounceBoth: function (t, b, c, d) {
1034 if (t < d/2) return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
1035 return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
1036 }
1037};
1038
1039/**
1040 * Anim subclass for moving elements along a path defined by the "points"
1041 * member of "attributes". All "points" are arrays with x, y coordinates.
1042 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1043 * @class Motion
1044 * @namespace YAHOO.util
1045 * @requires YAHOO.util.Anim
1046 * @requires YAHOO.util.AnimMgr
1047 * @requires YAHOO.util.Easing
1048 * @requires YAHOO.util.Bezier
1049 * @requires YAHOO.util.Dom
1050 * @requires YAHOO.util.Event
1051 * @requires YAHOO.util.CustomEvent
1052 * @constructor
1053 * @extends YAHOO.util.Anim
1054 * @param {String | HTMLElement} el Reference to the element that will be animated
1055 * @param {Object} attributes The attribute(s) to be animated.
1056 * Each attribute is an object with at minimum a "to" or "by" member defined.
1057 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1058 * All attribute names use camelCase.
1059 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1060 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
1061 */
1062(function() {
1063 YAHOO.util.Motion = function(el, attributes, duration, method) {
1064 if (el) { // dont break existing subclasses not using YAHOO.extend
1065 YAHOO.util.Motion.superclass.constructor.call(this, el, attributes, duration, method);
1066 }
1067 };
1068
1069 YAHOO.extend(YAHOO.util.Motion, YAHOO.util.ColorAnim);
1070
1071 // shorthand
1072 var Y = YAHOO.util;
1073 var superclass = Y.Motion.superclass;
1074 var proto = Y.Motion.prototype;
1075
1076 proto.toString = function() {
1077 var el = this.getEl();
1078 var id = el.id || el.tagName;
1079 return ("Motion " + id);
1080 };
1081
1082 proto.patterns.points = /^points$/i;
1083
1084 proto.setAttribute = function(attr, val, unit) {
1085 if ( this.patterns.points.test(attr) ) {
1086 unit = unit || 'px';
1087 superclass.setAttribute.call(this, 'left', val[0], unit);
1088 superclass.setAttribute.call(this, 'top', val[1], unit);
1089 } else {
1090 superclass.setAttribute.call(this, attr, val, unit);
1091 }
1092 };
1093
1094 proto.getAttribute = function(attr) {
1095 if ( this.patterns.points.test(attr) ) {
1096 var val = [
1097 superclass.getAttribute.call(this, 'left'),
1098 superclass.getAttribute.call(this, 'top')
1099 ];
1100 } else {
1101 val = superclass.getAttribute.call(this, attr);
1102 }
1103
1104 return val;
1105 };
1106
1107 proto.doMethod = function(attr, start, end) {
1108 var val = null;
1109
1110 if ( this.patterns.points.test(attr) ) {
1111 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
1112 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
1113 } else {
1114 val = superclass.doMethod.call(this, attr, start, end);
1115 }
1116 return val;
1117 };
1118
1119 proto.setRuntimeAttribute = function(attr) {
1120 if ( this.patterns.points.test(attr) ) {
1121 var el = this.getEl();
1122 var attributes = this.attributes;
1123 var start;
1124 var control = attributes['points']['control'] || [];
1125 var end;
1126 var i, len;
1127
1128 if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
1129 control = [control];
1130 } else { // break reference to attributes.points.control
1131 var tmp = [];
1132 for (i = 0, len = control.length; i< len; ++i) {
1133 tmp[i] = control[i];
1134 }
1135 control = tmp;
1136 }
1137
1138 if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
1139 Y.Dom.setStyle(el, 'position', 'relative');
1140 }
1141
1142 if ( isset(attributes['points']['from']) ) {
1143 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
1144 }
1145 else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
1146
1147 start = this.getAttribute('points'); // get actual top & left
1148
1149 // TO beats BY, per SMIL 2.1 spec
1150 if ( isset(attributes['points']['to']) ) {
1151 end = translateValues.call(this, attributes['points']['to'], start);
1152
1153 var pageXY = Y.Dom.getXY(this.getEl());
1154 for (i = 0, len = control.length; i < len; ++i) {
1155 control[i] = translateValues.call(this, control[i], start);
1156 }
1157
1158
1159 } else if ( isset(attributes['points']['by']) ) {
1160 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
1161
1162 for (i = 0, len = control.length; i < len; ++i) {
1163 control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
1164 }
1165 }
1166
1167 this.runtimeAttributes[attr] = [start];
1168
1169 if (control.length > 0) {
1170 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
1171 }
1172
1173 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
1174 }
1175 else {
1176 superclass.setRuntimeAttribute.call(this, attr);
1177 }
1178 };
1179
1180 var translateValues = function(val, start) {
1181 var pageXY = Y.Dom.getXY(this.getEl());
1182 val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
1183
1184 return val;
1185 };
1186
1187 var isset = function(prop) {
1188 return (typeof prop !== 'undefined');
1189 };
1190})();
1191/**
1192 * Anim subclass for scrolling elements to a position defined by the "scroll"
1193 * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
1194 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1195 * @class Scroll
1196 * @namespace YAHOO.util
1197 * @requires YAHOO.util.Anim
1198 * @requires YAHOO.util.AnimMgr
1199 * @requires YAHOO.util.Easing
1200 * @requires YAHOO.util.Bezier
1201 * @requires YAHOO.util.Dom
1202 * @requires YAHOO.util.Event
1203 * @requires YAHOO.util.CustomEvent
1204 * @extends YAHOO.util.Anim
1205 * @constructor
1206 * @param {String or HTMLElement} el Reference to the element that will be animated
1207 * @param {Object} attributes The attribute(s) to be animated.
1208 * Each attribute is an object with at minimum a "to" or "by" member defined.
1209 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1210 * All attribute names use camelCase.
1211 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1212 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
1213 */
1214(function() {
1215 YAHOO.util.Scroll = function(el, attributes, duration, method) {
1216 if (el) { // dont break existing subclasses not using YAHOO.extend
1217 YAHOO.util.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
1218 }
1219 };
1220
1221 YAHOO.extend(YAHOO.util.Scroll, YAHOO.util.ColorAnim);
1222
1223 // shorthand
1224 var Y = YAHOO.util;
1225 var superclass = Y.Scroll.superclass;
1226 var proto = Y.Scroll.prototype;
1227
1228 proto.toString = function() {
1229 var el = this.getEl();
1230 var id = el.id || el.tagName;
1231 return ("Scroll " + id);
1232 };
1233
1234 proto.doMethod = function(attr, start, end) {
1235 var val = null;
1236
1237 if (attr == 'scroll') {
1238 val = [
1239 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
1240 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
1241 ];
1242
1243 } else {
1244 val = superclass.doMethod.call(this, attr, start, end);
1245 }
1246 return val;
1247 };
1248
1249 proto.getAttribute = function(attr) {
1250 var val = null;
1251 var el = this.getEl();
1252
1253 if (attr == 'scroll') {
1254 val = [ el.scrollLeft, el.scrollTop ];
1255 } else {
1256 val = superclass.getAttribute.call(this, attr);
1257 }
1258
1259 return val;
1260 };
1261
1262 proto.setAttribute = function(attr, val, unit) {
1263 var el = this.getEl();
1264
1265 if (attr == 'scroll') {
1266 el.scrollLeft = val[0];
1267 el.scrollTop = val[1];
1268 } else {
1269 superclass.setAttribute.call(this, attr, val, unit);
1270 }
1271 };
1272})();