~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/static/javascript/yui/build/anim/anim-debug.js

  • Committer: Matt Nordhoff
  • Date: 2010-02-26 04:37:13 UTC
  • mfrom: (400 trunk)
  • mto: This revision was merged to the branch mainline in revision 401.
  • Revision ID: mnordhoff@mattnordhoff.com-20100226043713-7mw3r6dr9qowutmi
Merge trunk for NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.net/yui/license.txt
 
5
version: 3.0.0pr2
 
6
*/
 
7
YUI.add('anim', function(Y) {
 
8
 
 
9
/**
 
10
 * Y.Animation Utility.
 
11
 * @module anim
 
12
 */
 
13
 
 
14
    /**
 
15
     * Handles animation _queueing and threading.
 
16
     * @class Anim
 
17
     * @constructor
 
18
     * @extends Base
 
19
     */
 
20
 
 
21
    var RUNNING = 'running',
 
22
        START_TIME = 'startTime',
 
23
        ELAPSED_TIME = 'elapsedTime',
 
24
        /**
 
25
        * @event start
 
26
        * @description fires when an animation begins.
 
27
        * @param {Event} ev The start event.
 
28
        * @type Event.Custom
 
29
        */
 
30
        START = 'start',
 
31
 
 
32
        /**
 
33
        * @event tween
 
34
        * @description fires every frame of the animation.
 
35
        * @param {Event} ev The tween event.
 
36
        * @type Event.Custom
 
37
        */
 
38
        TWEEN = 'tween',
 
39
 
 
40
        /**
 
41
        * @event end
 
42
        * @description fires after the animation completes.
 
43
        * @param {Event} ev The end event.
 
44
        * @type Event.Custom
 
45
        */
 
46
        END = 'end',
 
47
        NODE = 'node',
 
48
        PAUSED = 'paused',
 
49
        REVERSE = 'reverse', // TODO: cleanup
 
50
        ITERATION_COUNT = 'iterationCount',
 
51
 
 
52
        NUM = Number;
 
53
 
 
54
    var _running = {},
 
55
        _instances = {},
 
56
        _timer;
 
57
 
 
58
    Y.Anim = function() {
 
59
        Y.Anim.superclass.constructor.apply(this, arguments);
 
60
        _instances[Y.stamp(this)] = this;
 
61
    };
 
62
 
 
63
    Y.Anim.NAME = 'anim';
 
64
 
 
65
    /**
 
66
     * Regex of properties that should use the default unit.
 
67
     *
 
68
     * @property RE_DEFAULT_UNIT
 
69
     * @static
 
70
     */
 
71
    Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
 
72
 
 
73
    /**
 
74
     * The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
 
75
     *
 
76
     * @property DEFAULT_UNIT
 
77
     * @static
 
78
     */
 
79
    Y.Anim.DEFAULT_UNIT = 'px';
 
80
 
 
81
    Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
 
82
        return c * t / d + b; // linear easing
 
83
    };
 
84
 
 
85
    /**
 
86
     * Bucket for custom getters and setters
 
87
     *
 
88
     * @property behaviors
 
89
     * @static
 
90
     */
 
91
    Y.Anim.behaviors = {
 
92
        left: {
 
93
            get: function(anim, attr) {
 
94
                return anim._getOffset(attr);
 
95
            }
 
96
        }
 
97
    };
 
98
 
 
99
    Y.Anim.behaviors.top = Y.Anim.behaviors.left;
 
100
 
 
101
    /**
 
102
     * The default setter to use when setting object properties.
 
103
     *
 
104
     * @property DEFAULT_SETTER
 
105
     * @static
 
106
     */
 
107
    Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
 
108
        unit = unit || '';
 
109
        anim._node.setStyle(att, fn(elapsed, NUM(from), NUM(to) - NUM(from), duration) + unit);
 
110
    };
 
111
 
 
112
    /**
 
113
     * The default getter to use when getting object properties.
 
114
     *
 
115
     * @property DEFAULT_GETTER
 
116
     * @static
 
117
     */
 
118
    Y.Anim.DEFAULT_GETTER = function(anim, prop) {
 
119
        return anim._node.getComputedStyle(prop);
 
120
    };
 
121
 
 
122
    Y.Anim.ATTRS = {
 
123
        /**
 
124
         * The object to be animated.
 
125
         * @attribute node
 
126
         * @type Node
 
127
         */
 
128
        node: {
 
129
            set: function(node) {
 
130
                node = Y.Node.get(node);
 
131
                this._node = node;
 
132
                if (!node) {
 
133
                    Y.fail('Y.Anim: invalid node: ' + node);
 
134
                }
 
135
                return node;
 
136
            }
 
137
        },
 
138
 
 
139
        /**
 
140
         * The length of the animation.  Defaults to "1" (second).
 
141
         * @attribute duration
 
142
         * @type NUM
 
143
         */
 
144
        duration: {
 
145
            value: 1
 
146
        },
 
147
 
 
148
        /**
 
149
         * The method that will provide values to the attribute(s) during the animation. 
 
150
         * Defaults to "Easing.easeNone".
 
151
         * @attribute easing
 
152
         * @type Function
 
153
         */
 
154
        easing: {
 
155
            value: Y.Anim.DEFAULT_EASING,
 
156
 
 
157
            set: function(val) {
 
158
                if (typeof val === 'string' && Y.Easing) {
 
159
                    return Y.Easing[val];
 
160
                }
 
161
            }
 
162
        },
 
163
 
 
164
        /**
 
165
         * The starting values for the animated properties. 
 
166
         * Fields may be strings, numbers, or functions.
 
167
         * If a function is used, the return value becomes the from value.
 
168
         * If no from value is specified, the DEFAULT_GETTER will be used. 
 
169
         * @attribute from
 
170
         * @type Object
 
171
         */
 
172
        from: {},
 
173
 
 
174
        /**
 
175
         * The ending values for the animated properties. 
 
176
         * Fields may be strings, numbers, or functions.
 
177
         * @attribute to
 
178
         * @type Object
 
179
         */
 
180
        to: {},
 
181
 
 
182
        /**
 
183
         * Date stamp for the first frame of the animation.
 
184
         * @attribute startTime
 
185
         * @type Int
 
186
         * @default 0 
 
187
         * @readOnly
 
188
         */
 
189
        startTime: {
 
190
            value: 0,
 
191
            readOnly: true
 
192
        },
 
193
 
 
194
        /**
 
195
         * Current time the animation has been running.
 
196
         * @attribute elapsedTime
 
197
         * @type Int
 
198
         * @default 0 
 
199
         * @readOnly
 
200
         */
 
201
        elapsedTime: {
 
202
            value: 0,
 
203
            readOnly: true
 
204
        },
 
205
 
 
206
        /**
 
207
         * Whether or not the animation is currently running.
 
208
         * @attribute running 
 
209
         * @type Boolean
 
210
         * @default false 
 
211
         * @readOnly
 
212
         */
 
213
        running: {
 
214
            get: function() {
 
215
                return !!_running[Y.stamp(this)];
 
216
            },
 
217
            value: false,
 
218
            readOnly: true
 
219
        },
 
220
 
 
221
        /**
 
222
         * The number of times the animation should run 
 
223
         * @attribute iterations
 
224
         * @type Int
 
225
         * @default 1 
 
226
         */
 
227
        iterations: {
 
228
            value: 1
 
229
        },
 
230
 
 
231
        /**
 
232
         * The number of iterations that have occurred.
 
233
         * Resets when an animation ends (reaches iteration count or stop() called). 
 
234
         * @attribute iterationCount
 
235
         * @type Int
 
236
         * @default 0
 
237
         * @readOnly
 
238
         */
 
239
        iterationCount: {
 
240
            value: 0,
 
241
            readOnly: true
 
242
        },
 
243
 
 
244
        /**
 
245
         * How iterations of the animation should behave. 
 
246
         * Possible values are "normal" and "alternate".
 
247
         * Normal will repeat the animation, alternate will reverse on every other pass.
 
248
         *
 
249
         * @attribute direction
 
250
         * @type String
 
251
         * @default "normal"
 
252
         */
 
253
        direction: {
 
254
            value: 'normal' // | alternate (fwd on odd, rev on even per spec)
 
255
        },
 
256
 
 
257
        /**
 
258
         * Whether or not the animation is currently paused.
 
259
         * @attribute running 
 
260
         * @type Boolean
 
261
         * @default false 
 
262
         * @readOnly
 
263
         */
 
264
        paused: {
 
265
            readOnly: true,
 
266
            value: false
 
267
        },
 
268
 
 
269
        /**
 
270
         * If true, animation begins from last frame
 
271
         * @attribute reverse
 
272
         * @type Boolean
 
273
         * @default false 
 
274
         */
 
275
        reverse: {
 
276
            value: false
 
277
        }
 
278
 
 
279
 
 
280
    };
 
281
 
 
282
    /**
 
283
     * Runs all animation instances.
 
284
     * @method run
 
285
     * @static
 
286
     */    
 
287
    Y.Anim.run = function() {
 
288
        for (var i in _instances) {
 
289
            if (_instances[i].run) {
 
290
                _instances[i].run();
 
291
            }
 
292
        }
 
293
    };
 
294
 
 
295
    /**
 
296
     * Pauses all animation instances.
 
297
     * @method pause
 
298
     * @static
 
299
     */    
 
300
    Y.Anim.pause = function() {
 
301
        for (var i in _running) { // stop timer if nothing running
 
302
            if (_running[i].pause) {
 
303
                _running[i].pause();
 
304
            }
 
305
        }
 
306
        Y.Anim._stopTimer();
 
307
    };
 
308
 
 
309
    /**
 
310
     * Stops all animation instances.
 
311
     * @method stop
 
312
     * @static
 
313
     */    
 
314
    Y.Anim.stop = function() {
 
315
        for (var i in _running) { // stop timer if nothing running
 
316
            if (_running[i].stop) {
 
317
                _running[i].stop();
 
318
            }
 
319
        }
 
320
        Y.Anim._stopTimer();
 
321
    };
 
322
    
 
323
    Y.Anim._startTimer = function() {
 
324
        if (!_timer) {
 
325
            _timer = setInterval(Y.Anim._runFrame, 1);
 
326
        }
 
327
    };
 
328
 
 
329
    Y.Anim._stopTimer = function() {
 
330
        clearInterval(_timer);
 
331
        _timer = 0;
 
332
    };
 
333
 
 
334
    /**
 
335
     * Called per Interval to handle each animation frame.
 
336
     * @method _runFrame
 
337
     * @private
 
338
     * @static
 
339
     */    
 
340
    Y.Anim._runFrame = function() {
 
341
        var done = true;
 
342
        for (var anim in _running) {
 
343
            if (_running[anim]._runFrame) {
 
344
                done = false;
 
345
                _running[anim]._runFrame();
 
346
            }
 
347
        }
 
348
 
 
349
        if (done) {
 
350
            Y.Anim._stopTimer();
 
351
        }
 
352
    };
 
353
 
 
354
    Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
 
355
 
 
356
    var proto = {
 
357
        /**
 
358
         * Starts or resumes an animation.
 
359
         * percent start time marker.
 
360
         * @method run
 
361
         * @chainable
 
362
         */    
 
363
        run: function() {
 
364
            if (!this.get(RUNNING)) {
 
365
                this._start();
 
366
            } else if (this.get(PAUSED)) {
 
367
                this._resume();
 
368
            }
 
369
            return this;
 
370
        },
 
371
 
 
372
        /**
 
373
         * Pauses the animation and
 
374
         * freezes it in its current state and time.
 
375
         * Calling run() will continue where it left off.
 
376
         * @method pause
 
377
         * @chainable
 
378
         */    
 
379
        pause: function() {
 
380
            if (this.get(RUNNING)) {
 
381
                this._pause();
 
382
            }
 
383
            return this;
 
384
        },
 
385
 
 
386
        /**
 
387
         * Stops the animation and resets its time.
 
388
         * @method stop
 
389
         * @chainable
 
390
         */    
 
391
        stop: function(finish) {
 
392
            if (this.get(RUNNING) || this.get(PAUSED)) {
 
393
                this._end(finish);
 
394
            }
 
395
            return this;
 
396
        },
 
397
 
 
398
        _added: false,
 
399
 
 
400
        _start: function() {
 
401
            this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
 
402
            this._actualFrames = 0;
 
403
            if (!this.get(PAUSED)) {
 
404
                this._initAttr();
 
405
            }
 
406
            _running[Y.stamp(this)] = this;
 
407
            Y.Anim._startTimer();
 
408
 
 
409
            this.fire(START);
 
410
        },
 
411
 
 
412
        _pause: function() {
 
413
            this._set(START_TIME, null);
 
414
            this._set(PAUSED, true);
 
415
            delete _running[Y.stamp(this)];
 
416
 
 
417
            /**
 
418
            * @event pause
 
419
            * @description fires when an animation is paused.
 
420
            * @param {Event} ev The pause event.
 
421
            * @type Event.Custom
 
422
            */
 
423
            this.fire('pause');
 
424
        },
 
425
 
 
426
        _resume: function() {
 
427
            this._set(PAUSED, false);
 
428
            _running[Y.stamp(this)] = this;
 
429
 
 
430
            /**
 
431
            * @event resume
 
432
            * @description fires when an animation is resumed (run from pause).
 
433
            * @param {Event} ev The pause event.
 
434
            * @type Event.Custom
 
435
            */
 
436
            this.fire('resume');
 
437
        },
 
438
 
 
439
        _end: function(finish) {
 
440
            this._set(START_TIME, null);
 
441
            this._set(ELAPSED_TIME, 0);
 
442
            this._set(PAUSED, false);
 
443
 
 
444
            delete _running[Y.stamp(this)];
 
445
            this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
 
446
        },
 
447
 
 
448
        _runFrame: function() {
 
449
            var attr = this._runtimeAttr,
 
450
                customAttr = Y.Anim.behaviors,
 
451
                easing = attr.easing,
 
452
                d = attr.duration,
 
453
                t = new Date() - this.get(START_TIME),
 
454
                reversed = this.get(REVERSE),
 
455
                done = (t >= d),
 
456
                lastFrame = d,
 
457
                attribute,
 
458
                setter;
 
459
                
 
460
            if (reversed) {
 
461
                t = d - t;
 
462
                done = (t <= 0);
 
463
                lastFrame = 0;
 
464
            }
 
465
 
 
466
            for (var i in attr) {
 
467
                if (attr[i].to) {
 
468
                    attribute = attr[i];
 
469
                    setter = (i in customAttr && 'set' in customAttr[i]) ?
 
470
                            customAttr[i].set : Y.Anim.DEFAULT_SETTER;
 
471
 
 
472
                    if (!done) {
 
473
                        setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit); 
 
474
                    } else { // ensure final frame value is set
 
475
                       // TODO: handle keyframes 
 
476
                        setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit); 
 
477
                    }
 
478
                }
 
479
            }
 
480
 
 
481
            this._actualFrames += 1;
 
482
            this._set(ELAPSED_TIME, t);
 
483
 
 
484
            this.fire(TWEEN);
 
485
            if (done) {
 
486
                this._lastFrame();
 
487
            }
 
488
        },
 
489
 
 
490
        _lastFrame: function() {
 
491
            var iter = this.get('iterations'),
 
492
                iterCount = this.get(ITERATION_COUNT);
 
493
 
 
494
            iterCount += 1;
 
495
            if (iter === 'infinite' || iterCount < iter) {
 
496
                if (this.get('direction') === 'alternate') {
 
497
                    this.set(REVERSE, !this.get(REVERSE)); // flip it
 
498
                }
 
499
                /**
 
500
                * @event iteration
 
501
                * @description fires when an animation begins an iteration.
 
502
                * @param {Event} ev The iteration event.
 
503
                * @type Event.Custom
 
504
                */
 
505
                this.fire('iteration');
 
506
            } else {
 
507
                iterCount = 0;
 
508
                this._end();
 
509
            }
 
510
 
 
511
            this._set(START_TIME, new Date());
 
512
            this._set(ITERATION_COUNT, iterCount);
 
513
        },
 
514
 
 
515
        _initAttr: function() {
 
516
            var from = this.get('from') || {},
 
517
                to = this.get('to') || {},
 
518
                dur = this.get('duration') * 1000,
 
519
                node = this.get(NODE),
 
520
                easing = this.get('easing') || {},
 
521
                attr = {},
 
522
                customAttr = Y.Anim.behaviors,
 
523
                unit, begin, end;
 
524
 
 
525
            Y.each(to, function(val, name) {
 
526
                if (typeof val === 'function') {
 
527
                    val = val.call(this, node);
 
528
                }
 
529
 
 
530
                begin = from[name];
 
531
                if (begin === undefined) {
 
532
                    begin = (name in customAttr && 'get' in customAttr[name])  ?
 
533
                            customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
 
534
                } else if (typeof begin === 'function') {
 
535
                    begin = begin.call(this, node);
 
536
                }
 
537
 
 
538
                var mFrom = Y.Anim.RE_UNITS.exec(begin);
 
539
                var mTo = Y.Anim.RE_UNITS.exec(val);
 
540
 
 
541
                begin = mFrom ? mFrom[1] : begin;
 
542
                var end = mTo ? mTo[1] : val,
 
543
                    unit = mTo ? mTo[2] : mFrom ?  mFrom[2] : ''; // one might be zero TODO: mixed units
 
544
 
 
545
                if (!unit && Y.Anim.RE_DEFAULT_UNIT.test(name)) {
 
546
                    unit = Y.Anim.DEFAULT_UNIT;
 
547
                }
 
548
 
 
549
                if (!begin || !end) {
 
550
                    Y.fail('invalid "from" or "to" for "' + name + '"', 'Anim');
 
551
                    return;
 
552
                }
 
553
 
 
554
                attr[name] = {
 
555
                    from: begin,
 
556
                    to: end,
 
557
                    unit: unit
 
558
                };
 
559
 
 
560
                attr.duration = dur;
 
561
                attr.easing = easing;
 
562
 
 
563
            }, this);
 
564
 
 
565
            this._runtimeAttr = attr;
 
566
        },
 
567
 
 
568
 
 
569
        // TODO: move to computedStyle? (browsers dont agree on default computed offsets)
 
570
        _getOffset: function(attr) {
 
571
            var node = this._node,
 
572
                val = node.getComputedStyle(attr),
 
573
                get = (attr === 'left') ? 'getX': 'getY',
 
574
                set = (attr === 'left') ? 'setX': 'setY';
 
575
 
 
576
            if (val === 'auto') {
 
577
                var position = node.getStyle('position');
 
578
                if (position === 'absolute' || position === 'fixed') {
 
579
                    val = node[get]();
 
580
                    node[set](val);
 
581
                } else {
 
582
                    val = 0;
 
583
                }
 
584
            }
 
585
 
 
586
            return val;
 
587
        }
 
588
    };
 
589
 
 
590
    Y.extend(Y.Anim, Y.Base, proto);
 
591
/*
 
592
TERMS OF USE - EASING EQUATIONS
 
593
Open source under the BSD License.
 
594
Copyright 2001 Robert Penner All rights reserved.
 
595
 
 
596
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
597
 
 
598
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 
599
 * 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.
 
600
 * 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.
 
601
 
 
602
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.
 
603
*/
 
604
 
 
605
/**
 
606
 * The easing module provides methods for customizing
 
607
 * how an animation behaves during each run.
 
608
 * @class Easing
 
609
 * @module anim
 
610
 * @submodule anim-easing
 
611
 */
 
612
 
 
613
Y.Easing = {
 
614
 
 
615
    /**
 
616
     * Uniform speed between points.
 
617
     * @method easeNone
 
618
     * @param {Number} t Time value used to compute current value
 
619
     * @param {Number} b Starting value
 
620
     * @param {Number} c Delta between start and end values
 
621
     * @param {Number} d Total length of animation
 
622
     * @return {Number} The computed value for the current animation frame
 
623
     */
 
624
    easeNone: function (t, b, c, d) {
 
625
        return c*t/d + b;
 
626
    },
 
627
    
 
628
    /**
 
629
     * Begins slowly and accelerates towards end. (quadratic)
 
630
     * @method easeIn
 
631
     * @param {Number} t Time value used to compute current value
 
632
     * @param {Number} b Starting value
 
633
     * @param {Number} c Delta between start and end values
 
634
     * @param {Number} d Total length of animation
 
635
     * @return {Number} The computed value for the current animation frame
 
636
     */
 
637
    easeIn: function (t, b, c, d) {
 
638
        return c*(t/=d)*t + b;
 
639
    },
 
640
 
 
641
    /**
 
642
     * Begins quickly and decelerates towards end.  (quadratic)
 
643
     * @method easeOut
 
644
     * @param {Number} t Time value used to compute current value
 
645
     * @param {Number} b Starting value
 
646
     * @param {Number} c Delta between start and end values
 
647
     * @param {Number} d Total length of animation
 
648
     * @return {Number} The computed value for the current animation frame
 
649
     */
 
650
    easeOut: function (t, b, c, d) {
 
651
        return -c *(t/=d)*(t-2) + b;
 
652
    },
 
653
    
 
654
    /**
 
655
     * Begins slowly and decelerates towards end. (quadratic)
 
656
     * @method easeBoth
 
657
     * @param {Number} t Time value used to compute current value
 
658
     * @param {Number} b Starting value
 
659
     * @param {Number} c Delta between start and end values
 
660
     * @param {Number} d Total length of animation
 
661
     * @return {Number} The computed value for the current animation frame
 
662
     */
 
663
    easeBoth: function (t, b, c, d) {
 
664
        if ((t/=d/2) < 1) {
 
665
            return c/2*t*t + b;
 
666
        }
 
667
        
 
668
        return -c/2 * ((--t)*(t-2) - 1) + b;
 
669
    },
 
670
    
 
671
    /**
 
672
     * Begins slowly and accelerates towards end. (quartic)
 
673
     * @method easeInStrong
 
674
     * @param {Number} t Time value used to compute current value
 
675
     * @param {Number} b Starting value
 
676
     * @param {Number} c Delta between start and end values
 
677
     * @param {Number} d Total length of animation
 
678
     * @return {Number} The computed value for the current animation frame
 
679
     */
 
680
    easeInStrong: function (t, b, c, d) {
 
681
        return c*(t/=d)*t*t*t + b;
 
682
    },
 
683
    
 
684
    /**
 
685
     * Begins quickly and decelerates towards end.  (quartic)
 
686
     * @method easeOutStrong
 
687
     * @param {Number} t Time value used to compute current value
 
688
     * @param {Number} b Starting value
 
689
     * @param {Number} c Delta between start and end values
 
690
     * @param {Number} d Total length of animation
 
691
     * @return {Number} The computed value for the current animation frame
 
692
     */
 
693
    easeOutStrong: function (t, b, c, d) {
 
694
        return -c * ((t=t/d-1)*t*t*t - 1) + b;
 
695
    },
 
696
    
 
697
    /**
 
698
     * Begins slowly and decelerates towards end. (quartic)
 
699
     * @method easeBothStrong
 
700
     * @param {Number} t Time value used to compute current value
 
701
     * @param {Number} b Starting value
 
702
     * @param {Number} c Delta between start and end values
 
703
     * @param {Number} d Total length of animation
 
704
     * @return {Number} The computed value for the current animation frame
 
705
     */
 
706
    easeBothStrong: function (t, b, c, d) {
 
707
        if ((t/=d/2) < 1) {
 
708
            return c/2*t*t*t*t + b;
 
709
        }
 
710
        
 
711
        return -c/2 * ((t-=2)*t*t*t - 2) + b;
 
712
    },
 
713
 
 
714
    /**
 
715
     * Snap in elastic effect.
 
716
     * @method elasticIn
 
717
     * @param {Number} t Time value used to compute current value
 
718
     * @param {Number} b Starting value
 
719
     * @param {Number} c Delta between start and end values
 
720
     * @param {Number} d Total length of animation
 
721
     * @param {Number} a Amplitude (optional)
 
722
     * @param {Number} p Period (optional)
 
723
     * @return {Number} The computed value for the current animation frame
 
724
     */
 
725
 
 
726
    elasticIn: function (t, b, c, d, a, p) {
 
727
        var s;
 
728
        if (t === 0) {
 
729
            return b;
 
730
        }
 
731
        if ( (t /= d) === 1 ) {
 
732
            return b+c;
 
733
        }
 
734
        if (!p) {
 
735
            p = d* 0.3;
 
736
        }
 
737
        
 
738
        if (!a || a < Math.abs(c)) {
 
739
            a = c; 
 
740
            s = p/4;
 
741
        }
 
742
        else {
 
743
            s = p/(2*Math.PI) * Math.asin (c/a);
 
744
        }
 
745
        
 
746
        return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
 
747
    },
 
748
 
 
749
    /**
 
750
     * Snap out elastic effect.
 
751
     * @method elasticOut
 
752
     * @param {Number} t Time value used to compute current value
 
753
     * @param {Number} b Starting value
 
754
     * @param {Number} c Delta between start and end values
 
755
     * @param {Number} d Total length of animation
 
756
     * @param {Number} a Amplitude (optional)
 
757
     * @param {Number} p Period (optional)
 
758
     * @return {Number} The computed value for the current animation frame
 
759
     */
 
760
    elasticOut: function (t, b, c, d, a, p) {
 
761
        var s;
 
762
        if (t === 0) {
 
763
            return b;
 
764
        }
 
765
        if ( (t /= d) === 1 ) {
 
766
            return b+c;
 
767
        }
 
768
        if (!p) {
 
769
            p=d * 0.3;
 
770
        }
 
771
        
 
772
        if (!a || a < Math.abs(c)) {
 
773
            a = c;
 
774
            s = p / 4;
 
775
        }
 
776
        else {
 
777
            s = p/(2*Math.PI) * Math.asin (c/a);
 
778
        }
 
779
        
 
780
        return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
 
781
    },
 
782
    
 
783
    /**
 
784
     * Snap both elastic effect.
 
785
     * @method elasticBoth
 
786
     * @param {Number} t Time value used to compute current value
 
787
     * @param {Number} b Starting value
 
788
     * @param {Number} c Delta between start and end values
 
789
     * @param {Number} d Total length of animation
 
790
     * @param {Number} a Amplitude (optional)
 
791
     * @param {Number} p Period (optional)
 
792
     * @return {Number} The computed value for the current animation frame
 
793
     */
 
794
    elasticBoth: function (t, b, c, d, a, p) {
 
795
        var s;
 
796
        if (t === 0) {
 
797
            return b;
 
798
        }
 
799
        
 
800
        if ( (t /= d/2) === 2 ) {
 
801
            return b+c;
 
802
        }
 
803
        
 
804
        if (!p) {
 
805
            p = d*(0.3*1.5);
 
806
        }
 
807
        
 
808
        if ( !a || a < Math.abs(c) ) {
 
809
            a = c; 
 
810
            s = p/4;
 
811
        }
 
812
        else {
 
813
            s = p/(2*Math.PI) * Math.asin (c/a);
 
814
        }
 
815
        
 
816
        if (t < 1) {
 
817
            return -0.5*(a*Math.pow(2,10*(t-=1)) * 
 
818
                    Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
 
819
        }
 
820
        return a*Math.pow(2,-10*(t-=1)) * 
 
821
                Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
 
822
    },
 
823
 
 
824
 
 
825
    /**
 
826
     * Backtracks slightly, then reverses direction and moves to end.
 
827
     * @method backIn
 
828
     * @param {Number} t Time value used to compute current value
 
829
     * @param {Number} b Starting value
 
830
     * @param {Number} c Delta between start and end values
 
831
     * @param {Number} d Total length of animation
 
832
     * @param {Number} s Overshoot (optional)
 
833
     * @return {Number} The computed value for the current animation frame
 
834
     */
 
835
    backIn: function (t, b, c, d, s) {
 
836
        if (s == undefined) {
 
837
            s = 1.70158;
 
838
        }
 
839
        if (t === d) {
 
840
            t -= 0.001;
 
841
        }
 
842
        return c*(t/=d)*t*((s+1)*t - s) + b;
 
843
    },
 
844
 
 
845
    /**
 
846
     * Overshoots end, then reverses and comes back to end.
 
847
     * @method backOut
 
848
     * @param {Number} t Time value used to compute current value
 
849
     * @param {Number} b Starting value
 
850
     * @param {Number} c Delta between start and end values
 
851
     * @param {Number} d Total length of animation
 
852
     * @param {Number} s Overshoot (optional)
 
853
     * @return {Number} The computed value for the current animation frame
 
854
     */
 
855
    backOut: function (t, b, c, d, s) {
 
856
        if (typeof s === 'undefined') {
 
857
            s = 1.70158;
 
858
        }
 
859
        return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
 
860
    },
 
861
    
 
862
    /**
 
863
     * Backtracks slightly, then reverses direction, overshoots end, 
 
864
     * then reverses and comes back to end.
 
865
     * @method backBoth
 
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
     * @param {Number} s Overshoot (optional)
 
871
     * @return {Number} The computed value for the current animation frame
 
872
     */
 
873
    backBoth: function (t, b, c, d, s) {
 
874
        if (typeof s === 'undefined') {
 
875
            s = 1.70158; 
 
876
        }
 
877
        
 
878
        if ((t /= d/2 ) < 1) {
 
879
            return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
 
880
        }
 
881
        return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
 
882
    },
 
883
 
 
884
    /**
 
885
     * Bounce off of start.
 
886
     * @method bounceIn
 
887
     * @param {Number} t Time value used to compute current value
 
888
     * @param {Number} b Starting value
 
889
     * @param {Number} c Delta between start and end values
 
890
     * @param {Number} d Total length of animation
 
891
     * @return {Number} The computed value for the current animation frame
 
892
     */
 
893
    bounceIn: function (t, b, c, d) {
 
894
        return c - Y.Easing.bounceOut(d-t, 0, c, d) + b;
 
895
    },
 
896
    
 
897
    /**
 
898
     * Bounces off end.
 
899
     * @method bounceOut
 
900
     * @param {Number} t Time value used to compute current value
 
901
     * @param {Number} b Starting value
 
902
     * @param {Number} c Delta between start and end values
 
903
     * @param {Number} d Total length of animation
 
904
     * @return {Number} The computed value for the current animation frame
 
905
     */
 
906
    bounceOut: function (t, b, c, d) {
 
907
        if ((t/=d) < (1/2.75)) {
 
908
                return c*(7.5625*t*t) + b;
 
909
        } else if (t < (2/2.75)) {
 
910
                return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
 
911
        } else if (t < (2.5/2.75)) {
 
912
                return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
 
913
        }
 
914
        return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
 
915
    },
 
916
    
 
917
    /**
 
918
     * Bounces off start and end.
 
919
     * @method bounceBoth
 
920
     * @param {Number} t Time value used to compute current value
 
921
     * @param {Number} b Starting value
 
922
     * @param {Number} c Delta between start and end values
 
923
     * @param {Number} d Total length of animation
 
924
     * @return {Number} The computed value for the current animation frame
 
925
     */
 
926
    bounceBoth: function (t, b, c, d) {
 
927
        if (t < d/2) {
 
928
            return Y.Easing.bounceIn(t * 2, 0, c, d) * 0.5 + b;
 
929
        }
 
930
        return Y.Easing.bounceOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
 
931
    }
 
932
};
 
933
/**
 
934
 * Adds support for the <code>xy</code> property in <code>from</code> and 
 
935
 * <code>to</code> attributes.
 
936
 * @module anim
 
937
 * @submodule anim-xy
 
938
 * @for Anim
 
939
 */
 
940
 
 
941
var NUM = Number;
 
942
 
 
943
Y.Anim.behaviors.xy = {
 
944
    set: function(anim, att, from, to, elapsed, duration, fn) {
 
945
        anim._node.setXY([
 
946
            fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
 
947
            fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
 
948
        ]);
 
949
    },
 
950
    get: function(anim) {
 
951
        return anim._node.getXY();
 
952
    }
 
953
};
 
954
 
 
955
/**
 
956
 * Adds support for color properties in <code>to</code>
 
957
 * and <code>from</code> attributes.
 
958
 * @module anim
 
959
 * @submodule anim-color
 
960
 * @for Anim
 
961
 */
 
962
 
 
963
var NUM = Number;
 
964
 
 
965
Y.Anim.behaviors.color = {
 
966
    set: function(anim, att, from, to, elapsed, duration, fn) {
 
967
        from = Y.Color.re_RGB.exec(Y.Color.toRGB(from));
 
968
        to = Y.Color.re_RGB.exec(Y.Color.toRGB(to));
 
969
 
 
970
        if (!from || from.length < 3 || !to || to.length < 3) {
 
971
            Y.fail('invalid from or to passed to color behavior');
 
972
        }
 
973
 
 
974
        anim._node.setStyle(att, 'rgb(' + [
 
975
            Math.floor(fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)),
 
976
            Math.floor(fn(elapsed, NUM(from[2]), NUM(to[2]) - NUM(from[2]), duration)),
 
977
            Math.floor(fn(elapsed, NUM(from[3]), NUM(to[3]) - NUM(from[3]), duration))
 
978
        ].join(', ') + ')');
 
979
    },
 
980
    
 
981
    // TODO: default bgcolor const
 
982
    get: function(anim, att) {
 
983
        var val = anim._node.getComputedStyle(att);
 
984
        val = (val === 'transparent') ? 'rgb(255, 255, 255)' : val;
 
985
        return val;
 
986
    }
 
987
};
 
988
 
 
989
Y.each(['backgroundColor',
 
990
        'borderColor',
 
991
        'borderTopColor',
 
992
        'borderRightColor', 
 
993
        'borderBottomColor', 
 
994
        'borderLeftColor'],
 
995
        function(v, i) {
 
996
            Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
 
997
        }
 
998
);
 
999
/**
 
1000
 * Adds support for the <code>scroll</code> property in <code>to</code>
 
1001
 * and <code>from</code> attributes.
 
1002
 * @module anim
 
1003
 * @submodule anim-scroll
 
1004
 * @for Anim
 
1005
 */
 
1006
 
 
1007
var NUM = Number;
 
1008
 
 
1009
Y.Anim.behaviors.scroll = {
 
1010
    set: function(anim, att, from, to, elapsed, duration, fn) {
 
1011
        var
 
1012
            node = anim._node, 
 
1013
            val = ([
 
1014
            fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
 
1015
            fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
 
1016
        ]);
 
1017
 
 
1018
        if (val[0]) {
 
1019
            node.set('scrollLeft', val[0]);
 
1020
        }
 
1021
 
 
1022
        if (val[1]) {
 
1023
            node.set('scrollTop', val[1]);
 
1024
        }
 
1025
    },
 
1026
    get: function(anim) {
 
1027
        var node = anim._node;
 
1028
        return [node.get('scrollLeft'), node.get('scrollTop')];
 
1029
    }
 
1030
};
 
1031
 
 
1032
/**
 
1033
 * Adds support for the <code>curve</code> property for the <code>to</code> 
 
1034
 * attribute.  A curve is zero or more control points and an end point.
 
1035
 * @module anim
 
1036
 * @submodule anim-curve
 
1037
 * @for Anim
 
1038
 */
 
1039
 
 
1040
Y.Anim.behaviors.curve = {
 
1041
    set: function(anim, att, from, to, elapsed, duration, fn) {
 
1042
        from = from.slice.call(from);
 
1043
        to = to.slice.call(to);
 
1044
        var t = fn(elapsed, 0, 100, duration) / 100;
 
1045
        to.unshift(from);
 
1046
        anim._node.setXY(Y.Anim.getBezier(to, t));
 
1047
    },
 
1048
 
 
1049
    get: function(anim, att) {
 
1050
        return anim._node.getXY();
 
1051
    }
 
1052
};
 
1053
 
 
1054
/**
 
1055
 * Get the current position of the animated element based on t.
 
1056
 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
 
1057
 * At least 2 points are required (start and end).
 
1058
 * First point is start. Last point is end.
 
1059
 * Additional control points are optional.     
 
1060
 * @method getBezier
 
1061
 * @static
 
1062
 * @param {Array} points An array containing Bezier points
 
1063
 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
 
1064
 * @return {Array} An array containing int x and y member data
 
1065
 */
 
1066
Y.Anim.getBezier = function(points, t) {  
 
1067
    var n = points.length;
 
1068
    var tmp = [];
 
1069
 
 
1070
    for (var i = 0; i < n; ++i){
 
1071
        tmp[i] = [points[i][0], points[i][1]]; // save input
 
1072
    }
 
1073
    
 
1074
    for (var j = 1; j < n; ++j) {
 
1075
        for (i = 0; i < n - j; ++i) {
 
1076
            tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
 
1077
            tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; 
 
1078
        }
 
1079
    }
 
1080
 
 
1081
    return [ tmp[0][0], tmp[0][1] ]; 
 
1082
 
 
1083
};
 
1084
/**
 
1085
 *  Binds an Anim instance to a Node instance
 
1086
 * @module anim
 
1087
 * @namespace plugin
 
1088
 * @submodule anim-node-plugin
 
1089
 */
 
1090
 
 
1091
var NodeFX = function(config) {
 
1092
    var config = Y.merge(config);
 
1093
    config.node = config.owner;
 
1094
    NodeFX.superclass.constructor.apply(this, arguments);
 
1095
};
 
1096
 
 
1097
NodeFX.NAME = "nodefx";
 
1098
NodeFX.NS = "fx";
 
1099
 
 
1100
Y.extend(NodeFX, Y.Anim);
 
1101
 
 
1102
Y.namespace('plugin');
 
1103
Y.plugin.NodeFX = NodeFX;
 
1104
 
 
1105
 
 
1106
}, '3.0.0pr2' ,{requires:['base', 'node']});