~ted/lazr-js/annoying-debug-message

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/transition/transition.js

  • Committer: Launchpad Patch Queue Manager
  • Date: 2010-09-09 14:20:30 UTC
  • mfrom: (182.1.3 yui-3.2)
  • Revision ID: launchpad@pqm.canonical.com-20100909142030-13w6vo0ixfysxc15
[r=beuno] Update lazr-js to yui-3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.com/yui/license.html
 
5
version: 3.2.0
 
6
build: 2676
 
7
*/
 
8
YUI.add('transition-native', function(Y) {
 
9
 
 
10
/**
 
11
* Provides the transition method for Node.
 
12
* Transition has no API of its own, but adds the transition method to Node.
 
13
*
 
14
* @module transition
 
15
* @requires node
 
16
*/
 
17
 
 
18
var TRANSITION = '-webkit-transition',
 
19
    TRANSITION_PROPERTY_CAMEL = 'WebkitTransition',
 
20
    TRANSITION_PROPERTY = '-webkit-transition-property',
 
21
    TRANSITION_DURATION = '-webkit-transition-duration',
 
22
    TRANSITION_TIMING_FUNCTION = '-webkit-transition-timing-function',
 
23
    TRANSITION_DELAY = '-webkit-transition-delay',
 
24
    TRANSITION_END = 'webkitTransitionEnd',
 
25
    TRANSFORM_CAMEL = 'WebkitTransform',
 
26
 
 
27
    EMPTY_OBJ = {},
 
28
 
 
29
/**
 
30
 * A class for constructing transition instances.
 
31
 * Adds the "transition" method to Node.
 
32
 * @class Transition
 
33
 * @constructor
 
34
 */
 
35
 
 
36
Transition = function() {
 
37
    this.init.apply(this, arguments);
 
38
};
 
39
 
 
40
Transition._toCamel = function(property) {
 
41
    property = property.replace(/-([a-z])/gi, function(m0, m1) {
 
42
        return m1.toUpperCase();
 
43
    });
 
44
 
 
45
    return property;
 
46
};
 
47
 
 
48
Transition._toHyphen = function(property) {
 
49
    property = property.replace(/([A-Z]?)([a-z]+)([A-Z]?)/g, function(m0, m1, m2, m3) {
 
50
        var str = '';
 
51
        if (m1) {
 
52
            str += '-' + m1.toLowerCase();
 
53
        }
 
54
        str += m2;
 
55
        
 
56
        if (m3) {
 
57
            str += '-' + m3.toLowerCase();
 
58
        }
 
59
 
 
60
        return str;
 
61
    }); 
 
62
 
 
63
    return property;
 
64
};
 
65
 
 
66
 
 
67
Transition._reKeywords = /^(?:node|duration|iterations|easing|delay)$/;
 
68
 
 
69
Transition.useNative = false;
 
70
 
 
71
if (TRANSITION in Y.config.doc.documentElement.style) {
 
72
    Transition.useNative = true;
 
73
    Transition.supported = true; // TODO: remove
 
74
}
 
75
 
 
76
Y.Node.DOM_EVENTS[TRANSITION_END] = 1; 
 
77
 
 
78
Transition.NAME = 'transition';
 
79
 
 
80
Transition.DEFAULT_EASING = 'ease';
 
81
Transition.DEFAULT_DURATION = 0.5;
 
82
Transition.DEFAULT_DELAY = 0;
 
83
 
 
84
Transition._nodeAttrs = {};
 
85
 
 
86
Transition.prototype = {
 
87
    constructor: Transition,
 
88
    init: function(node, config) {
 
89
        var anim = this;
 
90
        if (!anim._running) {
 
91
            anim._node = node;
 
92
            anim._config = config;
 
93
            node._transition = anim; // cache for reuse
 
94
 
 
95
            anim._duration = ('duration' in config) ?
 
96
                config.duration: anim.constructor.DEFAULT_DURATION;
 
97
 
 
98
            anim._delay = ('delay' in config) ?
 
99
                config.delay: anim.constructor.DEFAULT_DELAY;
 
100
 
 
101
            anim._easing = config.easing || anim.constructor.DEFAULT_EASING;
 
102
            anim._count = 0; // track number of animated properties
 
103
            anim._running = false;
 
104
 
 
105
            anim.initAttrs(config);
 
106
 
 
107
        }
 
108
 
 
109
        return anim;
 
110
    },
 
111
 
 
112
    addProperty: function(prop, config) {
 
113
        var anim = this,
 
114
            node = this._node,
 
115
            uid = Y.stamp(node),
 
116
            attrs = Transition._nodeAttrs[uid],
 
117
            attr,
 
118
            val;
 
119
 
 
120
        if (!attrs) {
 
121
            attrs = Transition._nodeAttrs[uid] = {};
 
122
        }
 
123
 
 
124
        attr = attrs[prop];
 
125
 
 
126
        // might just be a value
 
127
        if (config && config.value !== undefined) {
 
128
            val = config.value;
 
129
        } else if (config !== undefined) {
 
130
            val = config; 
 
131
            config = EMPTY_OBJ;
 
132
        }
 
133
 
 
134
        if (typeof val === 'function') {
 
135
            val = val.call(node, node);
 
136
        }
 
137
 
 
138
        // take control if another transition owns this property
 
139
        if (attr && attr.transition && attr.transition !== anim) {
 
140
            attr.transition._count--; // remapping attr to this transition
 
141
        }
 
142
 
 
143
        anim._count++; // properties per transition
 
144
 
 
145
        attrs[prop] = {
 
146
            value: val,
 
147
            duration: ((typeof config.duration !== 'undefined') ? config.duration :
 
148
                    anim._duration) || 0.0001, // make 0 async and fire events
 
149
 
 
150
            delay: (typeof config.delay !== 'undefined') ? config.delay :
 
151
                    anim._delay,
 
152
 
 
153
            easing: config.easing || anim._easing,
 
154
 
 
155
            transition: anim
 
156
        };
 
157
    },
 
158
 
 
159
    removeProperty: function(prop) {
 
160
        var anim = this,
 
161
            attrs = Transition._nodeAttrs[Y.stamp(anim._node)];
 
162
 
 
163
        if (attrs && attrs[prop]) {
 
164
            delete attrs[prop];
 
165
            anim._count--;
 
166
        }
 
167
 
 
168
    },
 
169
 
 
170
    initAttrs: function(config) {
 
171
        var attr;
 
172
 
 
173
        if (config.transform && !config[TRANSFORM_CAMEL]) {
 
174
            config[TRANSFORM_CAMEL] = config.transform;
 
175
            delete config.transform; // TODO: copy
 
176
        }
 
177
 
 
178
        for (attr in config) {
 
179
            if (config.hasOwnProperty(attr) && !Transition._reKeywords.test(attr)) {
 
180
                this.addProperty(attr, config[attr]);
 
181
            }
 
182
 
 
183
        }
 
184
    },
 
185
 
 
186
    /**
 
187
     * Starts or an animation.
 
188
     * @method run
 
189
     * @chainable
 
190
     * @private
 
191
     */    
 
192
    run: function(callback) {
 
193
        var anim = this;
 
194
 
 
195
        if (!anim._running) {
 
196
            anim._running = true;
 
197
 
 
198
            anim._node.fire('transition:start', {
 
199
                type: 'transition:start',
 
200
                config: anim._config
 
201
            });
 
202
 
 
203
            anim._start();
 
204
            anim._callback = callback;
 
205
        }
 
206
 
 
207
        return anim;
 
208
    },
 
209
 
 
210
    _start: function() {
 
211
        this._runNative();
 
212
    },
 
213
 
 
214
    _prepDur: function(dur) {
 
215
        dur = parseFloat(dur);
 
216
 
 
217
        return dur + 's';
 
218
    },
 
219
 
 
220
    _runNative: function(time) {
 
221
        var anim = this,
 
222
            node = anim._node,
 
223
            uid = Y.stamp(node),
 
224
            domNode = node._node,
 
225
            style = domNode.style,
 
226
            computed = getComputedStyle(domNode),
 
227
            attrs = Transition._nodeAttrs[uid],
 
228
            cssText = '',
 
229
            cssTransition = computed[TRANSITION_PROPERTY],
 
230
 
 
231
            transitionText = TRANSITION_PROPERTY + ': ',
 
232
            duration = TRANSITION_DURATION + ': ',
 
233
            easing = TRANSITION_TIMING_FUNCTION + ': ',
 
234
            delay = TRANSITION_DELAY + ': ',
 
235
            hyphy,
 
236
            attr,
 
237
            name;
 
238
 
 
239
        // preserve existing transitions
 
240
        if (cssTransition !== 'all') {
 
241
            transitionText += cssTransition + ',';
 
242
            duration += computed[TRANSITION_DURATION] + ',';
 
243
            easing += computed[TRANSITION_TIMING_FUNCTION] + ',';
 
244
            delay += computed[TRANSITION_DELAY] + ',';
 
245
 
 
246
        }
 
247
 
 
248
        // run transitions mapped to this instance
 
249
        for (name in attrs) {
 
250
            hyphy = Transition._toHyphen(name);
 
251
            attr = attrs[name];
 
252
            if (attrs.hasOwnProperty(name) && attr.transition === anim) {
 
253
                if (name in domNode.style) { // only native styles allowed
 
254
                    duration += anim._prepDur(attr.duration) + ',';
 
255
                    delay += anim._prepDur(attr.delay) + ',';
 
256
                    easing += (attr.easing) + ',';
 
257
 
 
258
                    transitionText += hyphy + ',';
 
259
                    cssText += hyphy + ': ' + attr.value + '; ';
 
260
                } else {
 
261
                    this.removeProperty(name);
 
262
                }
 
263
            }
 
264
        }
 
265
 
 
266
        transitionText = transitionText.replace(/,$/, ';');
 
267
        duration = duration.replace(/,$/, ';');
 
268
        easing = easing.replace(/,$/, ';');
 
269
        delay = delay.replace(/,$/, ';');
 
270
 
 
271
        // only one native end event per node
 
272
        if (!node._hasTransitionEnd) {
 
273
            anim._detach = node.on(TRANSITION_END, anim._onNativeEnd);
 
274
            node._hasTransitionEnd = true;
 
275
 
 
276
        }
 
277
 
 
278
        style.cssText += transitionText + duration + easing + delay + cssText;
 
279
 
 
280
    },
 
281
 
 
282
    _end: function(elapsed) {
 
283
        var anim = this,
 
284
            node = anim._node,
 
285
            callback = anim._callback,
 
286
            data = {
 
287
                type: 'transition:end',
 
288
                config: anim._config,
 
289
                elapsedTime: elapsed 
 
290
            };
 
291
 
 
292
        anim._running = false;
 
293
        if (callback) {
 
294
            anim._callback = null;
 
295
            setTimeout(function() { // IE: allow previous update to finish
 
296
                callback.call(node, data);
 
297
            }, 1);
 
298
        }
 
299
 
 
300
        node.fire('transition:end', data);
 
301
    },
 
302
 
 
303
    _endNative: function(name) {
 
304
        var node = this._node,
 
305
            value = node.getComputedStyle(TRANSITION_PROPERTY);
 
306
 
 
307
        if (typeof value === 'string') {
 
308
            value = value.replace(new RegExp('(?:^|,\\s)' + name + ',?'), ',');
 
309
            value = value.replace(/^,|,$/, '');
 
310
            node.setStyle(TRANSITION_PROPERTY_CAMEL, value);
 
311
        }
 
312
    },
 
313
 
 
314
    _onNativeEnd: function(e) {
 
315
        var node = this,
 
316
            uid = Y.stamp(node),
 
317
            event = e._event,
 
318
            name = Transition._toCamel(event.propertyName),
 
319
            elapsed = event.elapsedTime,
 
320
            attrs = Transition._nodeAttrs[uid],
 
321
            attr = attrs[name],
 
322
            anim = (attr) ? attr.transition : null;
 
323
 
 
324
        if (anim) {
 
325
            anim.removeProperty(name);
 
326
            anim._endNative(name);
 
327
 
 
328
            node.fire('transition:propertyEnd', {
 
329
                type: 'propertyEnd',
 
330
                propertyName: name,
 
331
                elapsedTime: elapsed
 
332
            });
 
333
 
 
334
            if (anim._count <= 0)  { // after propertEnd fires
 
335
                anim._end(elapsed);
 
336
            }
 
337
 
 
338
        }
 
339
    },
 
340
 
 
341
    destroy: function() {
 
342
        var anim = this;
 
343
        if (anim._detach) {
 
344
            anim._detach.detach();
 
345
        }
 
346
        anim._node = null;
 
347
    }
 
348
};
 
349
 
 
350
Y.Transition = Transition;
 
351
Y.TransitionNative = Transition; // TODO: remove
 
352
 
 
353
/** 
 
354
 *   Animate one or more css properties to a given value. Requires the "transition" module.
 
355
 *   <pre>example usage:
 
356
 *       Y.one('#demo').transition({
 
357
 *           duration: 1, // in seconds, default is 0.5
 
358
 *           easing: 'ease-out', // default is 'ease'
 
359
 *           delay: '1', // delay start for 1 second, default is 0
 
360
 *
 
361
 *           height: '10px',
 
362
 *           width: '10px',
 
363
 *
 
364
 *           opacity: { // per property
 
365
 *               value: 0,
 
366
 *               duration: 2,
 
367
 *               delay: 2,
 
368
 *               easing: 'ease-in'
 
369
 *           }
 
370
 *       });
 
371
 *   </pre>
 
372
 *   @for Node
 
373
 *   @method transition
 
374
 *   @param {Object} config An object containing one or more style properties, a duration and an easing.
 
375
 *   @param {Function} callback A function to run after the transition has completed. 
 
376
 *   @chainable
 
377
*/
 
378
Y.Node.prototype.transition = function(config, callback) {
 
379
    var anim = this._transition;
 
380
    
 
381
    if (anim && !anim._running) {
 
382
        anim.init(this, config);
 
383
    } else {
 
384
        anim = new Transition(this, config);
 
385
    }
 
386
 
 
387
    anim.run(callback);
 
388
    return this;
 
389
};
 
390
 
 
391
/** 
 
392
 *   Animate one or more css properties to a given value. Requires the "transition" module.
 
393
 *   <pre>example usage:
 
394
 *       Y.all('.demo').transition({
 
395
 *           duration: 1, // in seconds, default is 0.5
 
396
 *           easing: 'ease-out', // default is 'ease'
 
397
 *           delay: '1', // delay start for 1 second, default is 0
 
398
 *
 
399
 *           height: '10px',
 
400
 *           width: '10px',
 
401
 *
 
402
 *           opacity: { // per property
 
403
 *               value: 0,
 
404
 *               duration: 2,
 
405
 *               delay: 2,
 
406
 *               easing: 'ease-in'
 
407
 *           }
 
408
 *       });
 
409
 *   </pre>
 
410
 *   @for NodeList
 
411
 *   @method transition
 
412
 *   @param {Object} config An object containing one or more style properties, a duration and an easing.
 
413
 *   @param {Function} callback A function to run after the transition has completed. The callback fires
 
414
 *       once per item in the NodeList.
 
415
 *   @chainable
 
416
*/
 
417
Y.NodeList.prototype.transition = function(config, callback) {
 
418
    this.each(function(node) {
 
419
        node.transition(config, callback);
 
420
    });
 
421
 
 
422
    return this;
 
423
};
 
424
 
 
425
 
 
426
}, '3.2.0' ,{requires:['node-base']});
 
427
YUI.add('transition-timer', function(Y) {
 
428
 
 
429
/*
 
430
* The Transition Utility provides an API for creating advanced transitions.
 
431
* @module transition
 
432
*/
 
433
 
 
434
/*
 
435
* Provides the base Transition class, for animating numeric properties.
 
436
*
 
437
* @module transition
 
438
* @submodule transition-timer
 
439
*/
 
440
 
 
441
 
 
442
var Transition = Y.Transition;
 
443
 
 
444
Y.mix(Transition.prototype, {
 
445
    _start: function() {
 
446
        if (Transition.useNative) {
 
447
            this._runNative();
 
448
        } else {
 
449
            this._runTimer();
 
450
        }
 
451
    },
 
452
 
 
453
    _runTimer: function() {
 
454
        var anim = this;
 
455
        anim._initAttrs();
 
456
 
 
457
        Transition._running[Y.stamp(anim)] = anim;
 
458
        anim._startTime = new Date();
 
459
        Transition._startTimer();
 
460
    },
 
461
 
 
462
    _endTimer: function() {
 
463
        var anim = this;
 
464
        delete Transition._running[Y.stamp(anim)];
 
465
        anim._startTime = null;
 
466
    },
 
467
 
 
468
    _runFrame: function() {
 
469
        var t = new Date() - this._startTime;
 
470
        this._runAttrs(t);
 
471
    },
 
472
 
 
473
    _runAttrs: function(time) {
 
474
        var anim = this,
 
475
            node = anim._node,
 
476
            uid = Y.stamp(node),
 
477
            attrs = Transition._nodeAttrs[uid],
 
478
            customAttr = Transition.behaviors,
 
479
            done = false,
 
480
            allDone = false,
 
481
            name,
 
482
            attribute,
 
483
            setter,
 
484
            elapsed,
 
485
            delay,
 
486
            d,
 
487
            t,
 
488
            i;
 
489
 
 
490
        for (name in attrs) {
 
491
            attribute = attrs[name];
 
492
            if ((attribute && attribute.transition === anim)) {
 
493
                d = attribute.duration;
 
494
                delay = attribute.delay;
 
495
                elapsed = (time - delay) / 1000;
 
496
                t = time;
 
497
                setter = (i in customAttr && 'set' in customAttr[i]) ?
 
498
                        customAttr[i].set : Transition.DEFAULT_SETTER;
 
499
 
 
500
                done = (t >= d);
 
501
 
 
502
                if (t > d) {
 
503
                    t = d;
 
504
                }
 
505
 
 
506
                if (!delay || time >= delay) {
 
507
                    setter(anim, name, attribute.from, attribute.to, t - delay, d - delay,
 
508
                        attribute.easing, attribute.unit); 
 
509
 
 
510
                    if (done) {
 
511
                        delete attrs[name];
 
512
                        anim._count--;
 
513
 
 
514
                        node.fire('transition:propertyEnd', {
 
515
                            type: 'propertyEnd',
 
516
                            propertyName: name,
 
517
                            config: anim._config,
 
518
                            elapsedTime: elapsed
 
519
                        });
 
520
 
 
521
                        if (!allDone && anim._count <= 0) {
 
522
                            allDone = true;
 
523
                            anim._end(elapsed);
 
524
                            anim._endTimer();
 
525
                        }
 
526
                    }
 
527
                }
 
528
 
 
529
            }
 
530
        }
 
531
    },
 
532
 
 
533
    _initAttrs: function() {
 
534
        var anim = this,
 
535
            customAttr = Transition.behaviors,
 
536
            uid = Y.stamp(anim._node),
 
537
            attrs = Transition._nodeAttrs[uid],
 
538
            attribute,
 
539
            duration,
 
540
            delay,
 
541
            easing,
 
542
            val,
 
543
            name,
 
544
            mTo,
 
545
            mFrom,
 
546
            unit, begin, end;
 
547
 
 
548
        for (name in attrs) {
 
549
            attribute = attrs[name];
 
550
            if (attrs.hasOwnProperty(name) && (attribute && attribute.transition === anim)) {
 
551
                duration = attribute.duration * 1000;
 
552
                delay = attribute.delay * 1000;
 
553
                easing = attribute.easing;
 
554
                val = attribute.value;
 
555
 
 
556
                // only allow supported properties
 
557
                if (name in anim._node._node.style || name in Y.DOM.CUSTOM_STYLES) {
 
558
                    begin = (name in customAttr && 'get' in customAttr[name])  ?
 
559
                            customAttr[name].get(anim, name) : Transition.DEFAULT_GETTER(anim, name);
 
560
 
 
561
                    mFrom = Transition.RE_UNITS.exec(begin);
 
562
                    mTo = Transition.RE_UNITS.exec(val);
 
563
 
 
564
                    begin = mFrom ? mFrom[1] : begin;
 
565
                    end = mTo ? mTo[1] : val;
 
566
                    unit = mTo ? mTo[2] : mFrom ?  mFrom[2] : ''; // one might be zero TODO: mixed units
 
567
 
 
568
                    if (!unit && Transition.RE_DEFAULT_UNIT.test(name)) {
 
569
                        unit = Transition.DEFAULT_UNIT;
 
570
                    }
 
571
 
 
572
                    if (typeof easing === 'string') {
 
573
                        if (easing.indexOf('cubic-bezier') > -1) {
 
574
                            easing = easing.substring(13, easing.length - 1).split(',');
 
575
                        } else if (Transition.easings[easing]) {
 
576
                            easing = Transition.easings[easing];
 
577
                        }
 
578
                    }
 
579
 
 
580
                    attribute.from = Number(begin);
 
581
                    attribute.to = Number(end);
 
582
                    attribute.unit = unit;
 
583
                    attribute.easing = easing;
 
584
                    attribute.duration = duration + delay;
 
585
                    attribute.delay = delay;
 
586
                } else {
 
587
                    delete attrs[name];
 
588
                    anim._count--;
 
589
                }
 
590
            }
 
591
        }
 
592
    },
 
593
 
 
594
    destroy: function() {
 
595
        this.detachAll();
 
596
        this._node = null;
 
597
    }
 
598
}, true);
 
599
 
 
600
Y.mix(Y.Transition, {
 
601
    _runtimeAttrs: {},
 
602
    /*
 
603
     * Regex of properties that should use the default unit.
 
604
     *
 
605
     * @property RE_DEFAULT_UNIT
 
606
     * @static
 
607
     */
 
608
    RE_DEFAULT_UNIT: /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i,
 
609
 
 
610
    /*
 
611
     * The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
 
612
     *
 
613
     * @property DEFAULT_UNIT
 
614
     * @static
 
615
     */
 
616
    DEFAULT_UNIT: 'px',
 
617
 
 
618
    /*
 
619
     * Time in milliseconds passed to setInterval for frame processing 
 
620
     *
 
621
     * @property intervalTime
 
622
     * @default 20
 
623
     * @static
 
624
     */
 
625
    intervalTime: 20,
 
626
 
 
627
    /*
 
628
     * Bucket for custom getters and setters
 
629
     *
 
630
     * @property behaviors
 
631
     * @static
 
632
     */
 
633
    behaviors: {
 
634
        left: {
 
635
            get: function(anim, attr) {
 
636
                return Y.DOM._getAttrOffset(anim._node._node, attr);
 
637
            }
 
638
        }
 
639
    },
 
640
 
 
641
    /*
 
642
     * The default setter to use when setting object properties.
 
643
     *
 
644
     * @property DEFAULT_SETTER
 
645
     * @static
 
646
     */
 
647
    DEFAULT_SETTER: function(anim, att, from, to, elapsed, duration, fn, unit) {
 
648
        from = Number(from);
 
649
        to = Number(to);
 
650
 
 
651
        var node = anim._node,
 
652
            val = Transition.cubicBezier(fn, elapsed / duration);
 
653
 
 
654
        val = from + val[0] * (to - from);
 
655
 
 
656
        if (att in node._node.style || att in Y.DOM.CUSTOM_STYLES) {
 
657
            unit = unit || '';
 
658
            node.setStyle(att, val + unit);
 
659
        } else if (node._node.attributes[att]) {
 
660
            node.setAttribute(att, val);
 
661
        } else {
 
662
            node.set(att, val);
 
663
        }
 
664
    },
 
665
 
 
666
    /*
 
667
     * The default getter to use when getting object properties.
 
668
     *
 
669
     * @property DEFAULT_GETTER
 
670
     * @static
 
671
     */
 
672
    DEFAULT_GETTER: function(anim, att) {
 
673
        var node = anim._node,
 
674
            val = '';
 
675
 
 
676
        if (att in node._node.style || att in Y.DOM.CUSTOM_STYLES) {
 
677
            val = node.getComputedStyle(att);
 
678
        } else if (node._node.attributes[att]) {
 
679
            val = node.getAttribute(att);
 
680
        } else {
 
681
            val = node.get(att);
 
682
        }
 
683
 
 
684
        return val;
 
685
    },
 
686
 
 
687
    _startTimer: function() {
 
688
        if (!Transition._timer) {
 
689
            Transition._timer = setInterval(Transition._runFrame, Transition.intervalTime);
 
690
        }
 
691
    },
 
692
 
 
693
    _stopTimer: function() {
 
694
        clearInterval(Transition._timer);
 
695
        Transition._timer = null;
 
696
    },
 
697
 
 
698
    /*
 
699
     * Called per Interval to handle each animation frame.
 
700
     * @method _runFrame
 
701
     * @private
 
702
     * @static
 
703
     */    
 
704
    _runFrame: function() {
 
705
        var done = true,
 
706
            anim;
 
707
        for (anim in Transition._running) {
 
708
            if (Transition._running[anim]._runFrame) {
 
709
                done = false;
 
710
                Transition._running[anim]._runFrame();
 
711
            }
 
712
        }
 
713
 
 
714
        if (done) {
 
715
            Transition._stopTimer();
 
716
        }
 
717
    },
 
718
 
 
719
    cubicBezier: function(p, t) {
 
720
        var x0 = 0,
 
721
            y0 = 0,
 
722
            x1 = p[0],
 
723
            y1 = p[1],
 
724
            x2 = p[2],
 
725
            y2 = p[3],
 
726
            x3 = 1,
 
727
            y3 = 0,
 
728
 
 
729
            A = x3 - 3 * x2 + 3 * x1 - x0,
 
730
            B = 3 * x2 - 6 * x1 + 3 * x0,
 
731
            C = 3 * x1 - 3 * x0,
 
732
            D = x0,
 
733
            E = y3 - 3 * y2 + 3 * y1 - y0,
 
734
            F = 3 * y2 - 6 * y1 + 3 * y0,
 
735
            G = 3 * y1 - 3 * y0,
 
736
            H = y0,
 
737
 
 
738
            x = (((A*t) + B)*t + C)*t + D,
 
739
            y = (((E*t) + F)*t + G)*t + H;
 
740
 
 
741
        return [x, y];
 
742
    },
 
743
 
 
744
    easings: {
 
745
        ease: [0.25, 0, 1, 0.25],
 
746
        linear: [0, 0, 1, 1],
 
747
        'ease-in': [0.42, 0, 1, 1],
 
748
        'ease-out': [0, 0, 0.58, 1],
 
749
        'ease-in-out': [0.42, 0, 0.58, 1]
 
750
    },
 
751
 
 
752
    _running: {},
 
753
    _timer: null,
 
754
 
 
755
    RE_UNITS: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/
 
756
}, true); 
 
757
 
 
758
Transition.behaviors.top = Transition.behaviors.bottom = Transition.behaviors.right = Transition.behaviors.left;
 
759
 
 
760
Y.Transition = Transition;
 
761
 
 
762
 
 
763
}, '3.2.0' ,{requires:['transition-native', 'node-style']});
 
764
 
 
765
 
 
766
YUI.add('transition', function(Y){}, '3.2.0' ,{use:['transition-native', 'transition-timer']});
 
767