~launchpad-pqm/lazr-js/toolchain

« back to all changes in this revision

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

  • Committer: Sidnei da Silva
  • Date: 2009-11-16 00:51:29 UTC
  • mto: This revision was merged to the branch mainline in revision 154.
  • Revision ID: sidnei.da.silva@canonical.com-20091116005129-8ibwjlboa38glaw5
- Improved generation of skin modules and revamped combo service to make it more twisty.

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-timer', function(Y) {
9
 
 
10
 
/*
11
 
* The Transition Utility provides an API for creating advanced transitions.
12
 
* @module transition
13
 
*/
14
 
 
15
 
/*
16
 
* Provides the base Transition class, for animating numeric properties.
17
 
*
18
 
* @module transition
19
 
* @submodule transition-timer
20
 
*/
21
 
 
22
 
 
23
 
var Transition = Y.Transition;
24
 
 
25
 
Y.mix(Transition.prototype, {
26
 
    _start: function() {
27
 
        if (Transition.useNative) {
28
 
            this._runNative();
29
 
        } else {
30
 
            this._runTimer();
31
 
        }
32
 
    },
33
 
 
34
 
    _runTimer: function() {
35
 
        var anim = this;
36
 
        anim._initAttrs();
37
 
 
38
 
        Transition._running[Y.stamp(anim)] = anim;
39
 
        anim._startTime = new Date();
40
 
        Transition._startTimer();
41
 
    },
42
 
 
43
 
    _endTimer: function() {
44
 
        var anim = this;
45
 
        delete Transition._running[Y.stamp(anim)];
46
 
        anim._startTime = null;
47
 
    },
48
 
 
49
 
    _runFrame: function() {
50
 
        var t = new Date() - this._startTime;
51
 
        this._runAttrs(t);
52
 
    },
53
 
 
54
 
    _runAttrs: function(time) {
55
 
        var anim = this,
56
 
            node = anim._node,
57
 
            uid = Y.stamp(node),
58
 
            attrs = Transition._nodeAttrs[uid],
59
 
            customAttr = Transition.behaviors,
60
 
            done = false,
61
 
            allDone = false,
62
 
            name,
63
 
            attribute,
64
 
            setter,
65
 
            elapsed,
66
 
            delay,
67
 
            d,
68
 
            t,
69
 
            i;
70
 
 
71
 
        for (name in attrs) {
72
 
            attribute = attrs[name];
73
 
            if ((attribute && attribute.transition === anim)) {
74
 
                d = attribute.duration;
75
 
                delay = attribute.delay;
76
 
                elapsed = (time - delay) / 1000;
77
 
                t = time;
78
 
                setter = (i in customAttr && 'set' in customAttr[i]) ?
79
 
                        customAttr[i].set : Transition.DEFAULT_SETTER;
80
 
 
81
 
                done = (t >= d);
82
 
 
83
 
                if (t > d) {
84
 
                    t = d;
85
 
                }
86
 
 
87
 
                if (!delay || time >= delay) {
88
 
                    setter(anim, name, attribute.from, attribute.to, t - delay, d - delay,
89
 
                        attribute.easing, attribute.unit); 
90
 
 
91
 
                    if (done) {
92
 
                        delete attrs[name];
93
 
                        anim._count--;
94
 
 
95
 
                        node.fire('transition:propertyEnd', {
96
 
                            type: 'propertyEnd',
97
 
                            propertyName: name,
98
 
                            config: anim._config,
99
 
                            elapsedTime: elapsed
100
 
                        });
101
 
 
102
 
                        if (!allDone && anim._count <= 0) {
103
 
                            allDone = true;
104
 
                            anim._end(elapsed);
105
 
                            anim._endTimer();
106
 
                        }
107
 
                    }
108
 
                }
109
 
 
110
 
            }
111
 
        }
112
 
    },
113
 
 
114
 
    _initAttrs: function() {
115
 
        var anim = this,
116
 
            customAttr = Transition.behaviors,
117
 
            uid = Y.stamp(anim._node),
118
 
            attrs = Transition._nodeAttrs[uid],
119
 
            attribute,
120
 
            duration,
121
 
            delay,
122
 
            easing,
123
 
            val,
124
 
            name,
125
 
            mTo,
126
 
            mFrom,
127
 
            unit, begin, end;
128
 
 
129
 
        for (name in attrs) {
130
 
            attribute = attrs[name];
131
 
            if (attrs.hasOwnProperty(name) && (attribute && attribute.transition === anim)) {
132
 
                duration = attribute.duration * 1000;
133
 
                delay = attribute.delay * 1000;
134
 
                easing = attribute.easing;
135
 
                val = attribute.value;
136
 
 
137
 
                // only allow supported properties
138
 
                if (name in anim._node._node.style || name in Y.DOM.CUSTOM_STYLES) {
139
 
                    begin = (name in customAttr && 'get' in customAttr[name])  ?
140
 
                            customAttr[name].get(anim, name) : Transition.DEFAULT_GETTER(anim, name);
141
 
 
142
 
                    mFrom = Transition.RE_UNITS.exec(begin);
143
 
                    mTo = Transition.RE_UNITS.exec(val);
144
 
 
145
 
                    begin = mFrom ? mFrom[1] : begin;
146
 
                    end = mTo ? mTo[1] : val;
147
 
                    unit = mTo ? mTo[2] : mFrom ?  mFrom[2] : ''; // one might be zero TODO: mixed units
148
 
 
149
 
                    if (!unit && Transition.RE_DEFAULT_UNIT.test(name)) {
150
 
                        unit = Transition.DEFAULT_UNIT;
151
 
                    }
152
 
 
153
 
                    if (typeof easing === 'string') {
154
 
                        if (easing.indexOf('cubic-bezier') > -1) {
155
 
                            easing = easing.substring(13, easing.length - 1).split(',');
156
 
                        } else if (Transition.easings[easing]) {
157
 
                            easing = Transition.easings[easing];
158
 
                        }
159
 
                    }
160
 
 
161
 
                    attribute.from = Number(begin);
162
 
                    attribute.to = Number(end);
163
 
                    attribute.unit = unit;
164
 
                    attribute.easing = easing;
165
 
                    attribute.duration = duration + delay;
166
 
                    attribute.delay = delay;
167
 
                } else {
168
 
                    delete attrs[name];
169
 
                    anim._count--;
170
 
                }
171
 
            }
172
 
        }
173
 
    },
174
 
 
175
 
    destroy: function() {
176
 
        this.detachAll();
177
 
        this._node = null;
178
 
    }
179
 
}, true);
180
 
 
181
 
Y.mix(Y.Transition, {
182
 
    _runtimeAttrs: {},
183
 
    /*
184
 
     * Regex of properties that should use the default unit.
185
 
     *
186
 
     * @property RE_DEFAULT_UNIT
187
 
     * @static
188
 
     */
189
 
    RE_DEFAULT_UNIT: /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i,
190
 
 
191
 
    /*
192
 
     * The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
193
 
     *
194
 
     * @property DEFAULT_UNIT
195
 
     * @static
196
 
     */
197
 
    DEFAULT_UNIT: 'px',
198
 
 
199
 
    /*
200
 
     * Time in milliseconds passed to setInterval for frame processing 
201
 
     *
202
 
     * @property intervalTime
203
 
     * @default 20
204
 
     * @static
205
 
     */
206
 
    intervalTime: 20,
207
 
 
208
 
    /*
209
 
     * Bucket for custom getters and setters
210
 
     *
211
 
     * @property behaviors
212
 
     * @static
213
 
     */
214
 
    behaviors: {
215
 
        left: {
216
 
            get: function(anim, attr) {
217
 
                return Y.DOM._getAttrOffset(anim._node._node, attr);
218
 
            }
219
 
        }
220
 
    },
221
 
 
222
 
    /*
223
 
     * The default setter to use when setting object properties.
224
 
     *
225
 
     * @property DEFAULT_SETTER
226
 
     * @static
227
 
     */
228
 
    DEFAULT_SETTER: function(anim, att, from, to, elapsed, duration, fn, unit) {
229
 
        from = Number(from);
230
 
        to = Number(to);
231
 
 
232
 
        var node = anim._node,
233
 
            val = Transition.cubicBezier(fn, elapsed / duration);
234
 
 
235
 
        val = from + val[0] * (to - from);
236
 
 
237
 
        if (att in node._node.style || att in Y.DOM.CUSTOM_STYLES) {
238
 
            unit = unit || '';
239
 
            node.setStyle(att, val + unit);
240
 
        } else if (node._node.attributes[att]) {
241
 
            node.setAttribute(att, val);
242
 
        } else {
243
 
            node.set(att, val);
244
 
        }
245
 
    },
246
 
 
247
 
    /*
248
 
     * The default getter to use when getting object properties.
249
 
     *
250
 
     * @property DEFAULT_GETTER
251
 
     * @static
252
 
     */
253
 
    DEFAULT_GETTER: function(anim, att) {
254
 
        var node = anim._node,
255
 
            val = '';
256
 
 
257
 
        if (att in node._node.style || att in Y.DOM.CUSTOM_STYLES) {
258
 
            val = node.getComputedStyle(att);
259
 
        } else if (node._node.attributes[att]) {
260
 
            val = node.getAttribute(att);
261
 
        } else {
262
 
            val = node.get(att);
263
 
        }
264
 
 
265
 
        return val;
266
 
    },
267
 
 
268
 
    _startTimer: function() {
269
 
        if (!Transition._timer) {
270
 
            Transition._timer = setInterval(Transition._runFrame, Transition.intervalTime);
271
 
        }
272
 
    },
273
 
 
274
 
    _stopTimer: function() {
275
 
        clearInterval(Transition._timer);
276
 
        Transition._timer = null;
277
 
    },
278
 
 
279
 
    /*
280
 
     * Called per Interval to handle each animation frame.
281
 
     * @method _runFrame
282
 
     * @private
283
 
     * @static
284
 
     */    
285
 
    _runFrame: function() {
286
 
        var done = true,
287
 
            anim;
288
 
        for (anim in Transition._running) {
289
 
            if (Transition._running[anim]._runFrame) {
290
 
                done = false;
291
 
                Transition._running[anim]._runFrame();
292
 
            }
293
 
        }
294
 
 
295
 
        if (done) {
296
 
            Transition._stopTimer();
297
 
        }
298
 
    },
299
 
 
300
 
    cubicBezier: function(p, t) {
301
 
        var x0 = 0,
302
 
            y0 = 0,
303
 
            x1 = p[0],
304
 
            y1 = p[1],
305
 
            x2 = p[2],
306
 
            y2 = p[3],
307
 
            x3 = 1,
308
 
            y3 = 0,
309
 
 
310
 
            A = x3 - 3 * x2 + 3 * x1 - x0,
311
 
            B = 3 * x2 - 6 * x1 + 3 * x0,
312
 
            C = 3 * x1 - 3 * x0,
313
 
            D = x0,
314
 
            E = y3 - 3 * y2 + 3 * y1 - y0,
315
 
            F = 3 * y2 - 6 * y1 + 3 * y0,
316
 
            G = 3 * y1 - 3 * y0,
317
 
            H = y0,
318
 
 
319
 
            x = (((A*t) + B)*t + C)*t + D,
320
 
            y = (((E*t) + F)*t + G)*t + H;
321
 
 
322
 
        return [x, y];
323
 
    },
324
 
 
325
 
    easings: {
326
 
        ease: [0.25, 0, 1, 0.25],
327
 
        linear: [0, 0, 1, 1],
328
 
        'ease-in': [0.42, 0, 1, 1],
329
 
        'ease-out': [0, 0, 0.58, 1],
330
 
        'ease-in-out': [0.42, 0, 0.58, 1]
331
 
    },
332
 
 
333
 
    _running: {},
334
 
    _timer: null,
335
 
 
336
 
    RE_UNITS: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/
337
 
}, true); 
338
 
 
339
 
Transition.behaviors.top = Transition.behaviors.bottom = Transition.behaviors.right = Transition.behaviors.left;
340
 
 
341
 
Y.Transition = Transition;
342
 
 
343
 
 
344
 
}, '3.2.0' ,{requires:['transition-native', 'node-style']});