Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Manager2.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-fx-Manager'>/**
19 </span> * @class Ext.fx.Manager
20  * Animation Manager which keeps track of all current animations and manages them on a frame by frame basis.
21  * @private
22  * @singleton
23  */
24
25 Ext.define('Ext.fx.Manager', {
26
27     /* Begin Definitions */
28
29     singleton: true,
30
31     requires: ['Ext.util.MixedCollection',
32                'Ext.fx.target.Element',
33                'Ext.fx.target.CompositeElement',
34                'Ext.fx.target.Sprite',
35                'Ext.fx.target.CompositeSprite',
36                'Ext.fx.target.Component'],
37
38     mixins: {
39         queue: 'Ext.fx.Queue'
40     },
41
42     /* End Definitions */
43
44     constructor: function() {
45         this.items = Ext.create('Ext.util.MixedCollection');
46         this.mixins.queue.constructor.call(this);
47
48         // this.requestAnimFrame = (function() {
49         //     var raf = window.requestAnimationFrame ||
50         //               window.webkitRequestAnimationFrame ||
51         //               window.mozRequestAnimationFrame ||
52         //               window.oRequestAnimationFrame ||
53         //               window.msRequestAnimationFrame;
54         //     if (raf) {
55         //         return function(callback, element) {
56         //             raf(callback);
57         //         };
58         //     }
59         //     else {
60         //         return function(callback, element) {
61         //             window.setTimeout(callback, Ext.fx.Manager.interval);
62         //         };
63         //     }
64         // })();
65     },
66
67 <span id='Ext-fx-Manager-cfg-interval'>    /**
68 </span>     * @cfg {Number} interval Default interval in miliseconds to calculate each frame.  Defaults to 16ms (~60fps)
69      */
70     interval: 16,
71
72 <span id='Ext-fx-Manager-cfg-forceJS'>    /**
73 </span>     * @cfg {Boolean} forceJS Turn off to not use CSS3 transitions when they are available
74      */
75     forceJS: true,
76
77     // @private Target factory
78     createTarget: function(target) {
79         var me = this,
80             useCSS3 = !me.forceJS &amp;&amp; Ext.supports.Transitions,
81             targetObj;
82
83         me.useCSS3 = useCSS3;
84
85         // dom id
86         if (Ext.isString(target)) {
87             target = Ext.get(target);
88         }
89         // dom element
90         if (target &amp;&amp; target.tagName) {
91             target = Ext.get(target);
92             targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
93             me.targets.add(targetObj);
94             return targetObj;
95         }
96         if (Ext.isObject(target)) {
97             // Element
98             if (target.dom) {
99                 targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
100             }
101             // Element Composite
102             else if (target.isComposite) {
103                 targetObj = Ext.create('Ext.fx.target.' + 'CompositeElement' + (useCSS3 ? 'CSS' : ''), target);
104             }
105             // Draw Sprite
106             else if (target.isSprite) {
107                 targetObj = Ext.create('Ext.fx.target.Sprite', target);
108             }
109             // Draw Sprite Composite
110             else if (target.isCompositeSprite) {
111                 targetObj = Ext.create('Ext.fx.target.CompositeSprite', target);
112             }
113             // Component
114             else if (target.isComponent) {
115                 targetObj = Ext.create('Ext.fx.target.Component', target);
116             }
117             else if (target.isAnimTarget) {
118                 return target;
119             }
120             else {
121                 return null;
122             }
123             me.targets.add(targetObj);
124             return targetObj;
125         }
126         else {
127             return null;
128         }
129     },
130
131 <span id='Ext-fx-Manager-method-addAnim'>    /**
132 </span>     * Add an Anim to the manager. This is done automatically when an Anim instance is created.
133      * @param {Ext.fx.Anim} anim
134      */
135     addAnim: function(anim) {
136         var items = this.items,
137             task = this.task;
138         // var me = this,
139         //     items = me.items,
140         //     cb = function() {
141         //         if (items.length) {
142         //             me.task = true;
143         //             me.runner();
144         //             me.requestAnimFrame(cb);
145         //         }
146         //         else {
147         //             me.task = false;
148         //         }
149         //     };
150
151         items.add(anim);
152
153         // Start the timer if not already running
154         if (!task &amp;&amp; items.length) {
155             task = this.task = {
156                 run: this.runner,
157                 interval: this.interval,
158                 scope: this
159             };
160             Ext.TaskManager.start(task);
161         }
162
163         // //Start the timer if not already running
164         // if (!me.task &amp;&amp; items.length) {
165         //     me.requestAnimFrame(cb);
166         // }
167     },
168
169 <span id='Ext-fx-Manager-method-removeAnim'>    /**
170 </span>     * Remove an Anim from the manager. This is done automatically when an Anim ends.
171      * @param {Ext.fx.Anim} anim
172      */
173     removeAnim: function(anim) {
174         // this.items.remove(anim);
175         var items = this.items,
176             task = this.task;
177         items.remove(anim);
178         // Stop the timer if there are no more managed Anims
179         if (task &amp;&amp; !items.length) {
180             Ext.TaskManager.stop(task);
181             delete this.task;
182         }
183     },
184
185 <span id='Ext-fx-Manager-method-startingFilter'>    /**
186 </span>     * @private
187      * Filter function to determine which animations need to be started
188      */
189     startingFilter: function(o) {
190         return o.paused === false &amp;&amp; o.running === false &amp;&amp; o.iterations &gt; 0;
191     },
192
193 <span id='Ext-fx-Manager-method-runningFilter'>    /**
194 </span>     * @private
195      * Filter function to determine which animations are still running
196      */
197     runningFilter: function(o) {
198         return o.paused === false &amp;&amp; o.running === true &amp;&amp; o.isAnimator !== true;
199     },
200
201 <span id='Ext-fx-Manager-method-runner'>    /**
202 </span>     * @private
203      * Runner function being called each frame
204      */
205     runner: function() {
206         var me = this,
207             items = me.items;
208
209         me.targetData = {};
210         me.targetArr = {};
211
212         // Single timestamp for all animations this interval
213         me.timestamp = new Date();
214
215         // Start any items not current running
216         items.filterBy(me.startingFilter).each(me.startAnim, me);
217
218         // Build the new attributes to be applied for all targets in this frame
219         items.filterBy(me.runningFilter).each(me.runAnim, me);
220
221         // Apply all the pending changes to their targets
222         me.applyPendingAttrs();
223     },
224
225 <span id='Ext-fx-Manager-method-startAnim'>    /**
226 </span>     * @private
227      * Start the individual animation (initialization)
228      */
229     startAnim: function(anim) {
230         anim.start(this.timestamp);
231     },
232
233 <span id='Ext-fx-Manager-method-runAnim'>    /**
234 </span>     * @private
235      * Run the individual animation for this frame
236      */
237     runAnim: function(anim) {
238         if (!anim) {
239             return;
240         }
241         var me = this,
242             targetId = anim.target.getId(),
243             useCSS3 = me.useCSS3 &amp;&amp; anim.target.type == 'element',
244             elapsedTime = me.timestamp - anim.startTime,
245             target, o;
246
247         this.collectTargetData(anim, elapsedTime, useCSS3);
248
249         // For CSS3 animation, we need to immediately set the first frame's attributes without any transition
250         // to get a good initial state, then add the transition properties and set the final attributes.
251         if (useCSS3) {
252             // Flush the collected attributes, without transition
253             anim.target.setAttr(me.targetData[targetId], true);
254
255             // Add the end frame data
256             me.targetData[targetId] = [];
257             me.collectTargetData(anim, anim.duration, useCSS3);
258
259             // Pause the animation so runAnim doesn't keep getting called
260             anim.paused = true;
261
262             target = anim.target.target;
263             // We only want to attach an event on the last element in a composite
264             if (anim.target.isComposite) {
265                 target = anim.target.target.last();
266             }
267
268             // Listen for the transitionend event
269             o = {};
270             o[Ext.supports.CSS3TransitionEnd] = anim.lastFrame;
271             o.scope = anim;
272             o.single = true;
273             target.on(o);
274         }
275         // For JS animation, trigger the lastFrame handler if this is the final frame
276         else if (elapsedTime &gt;= anim.duration) {
277             me.applyPendingAttrs(true);
278             delete me.targetData[targetId];
279             delete me.targetArr[targetId];
280             anim.lastFrame();
281         }
282     },
283
284 <span id='Ext-fx-Manager-method-collectTargetData'>    /**
285 </span>     * Collect target attributes for the given Anim object at the given timestamp
286      * @param {Ext.fx.Anim} anim The Anim instance
287      * @param {Number} timestamp Time after the anim's start time
288      */
289     collectTargetData: function(anim, elapsedTime, useCSS3) {
290         var targetId = anim.target.getId(),
291             targetData = this.targetData[targetId],
292             data;
293         
294         if (!targetData) {
295             targetData = this.targetData[targetId] = [];
296             this.targetArr[targetId] = anim.target;
297         }
298
299         data = {
300             duration: anim.duration,
301             easing: (useCSS3 &amp;&amp; anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing,
302             attrs: {}
303         };
304         Ext.apply(data.attrs, anim.runAnim(elapsedTime));
305         targetData.push(data);
306     },
307
308 <span id='Ext-fx-Manager-method-applyPendingAttrs'>    /**
309 </span>     * @private
310      * Apply all pending attribute changes to their targets
311      */
312     applyPendingAttrs: function(isLastFrame) {
313         var targetData = this.targetData,
314             targetArr = this.targetArr,
315             targetId;
316         for (targetId in targetData) {
317             if (targetData.hasOwnProperty(targetId)) {
318                 targetArr[targetId].setAttr(targetData[targetId], false, isLastFrame);
319             }
320         }
321     }
322 });
323 </pre>
324 </body>
325 </html>