~ubuntu-branches/ubuntu/natty/otrs2/natty-updates

« back to all changes in this revision

Viewing changes to var/httpd/htdocs/yui/2.7.0/build/animation/animation.js

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2010-08-09 19:43:44 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20100809194344-absef1ut5mfj3qhv
Tags: 2.4.7+dfsg1-1
* Strip out yui from the source in the dfsg version.
  Closes: #591196
* Depend on libjs-yui and link to this package, instead of using the embedded
  yui version. This changes make the flash ticket statistics unuseable!
  Closes: #592146

Show diffs side-by-side

added added

removed removed

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