/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk

« back to all changes in this revision

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

  • Committer: Colin Watson
  • Date: 2020-06-08 09:55:03 UTC
  • mfrom: (498.2.2 jquery)
  • Revision ID: cjwatson@canonical.com-20200608095503-n387xggxud2khqsw
[r=cjwatson] Port loggerhead from YUI to jQuery.

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']});