Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Animate.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-util-Animate'>/**
19 </span> * @class Ext.util.Animate
20  * This animation class is a mixin.
21  * 
22  * Ext.util.Animate provides an API for the creation of animated transitions of properties and styles.  
23  * This class is used as a mixin and currently applied to {@link Ext.core.Element}, {@link Ext.CompositeElement}, 
24  * {@link Ext.draw.Sprite}, {@link Ext.draw.CompositeSprite}, and {@link Ext.Component}.  Note that Components 
25  * have a limited subset of what attributes can be animated such as top, left, x, y, height, width, and 
26  * opacity (color, paddings, and margins can not be animated).
27  * 
28  * ## Animation Basics
29  * 
30  * All animations require three things - `easing`, `duration`, and `to` (the final end value for each property) 
31  * you wish to animate. Easing and duration are defaulted values specified below.
32  * Easing describes how the intermediate values used during a transition will be calculated. 
33  * {@link Ext.fx.Anim#easing Easing} allows for a transition to change speed over its duration.
34  * You may use the defaults for easing and duration, but you must always set a 
35  * {@link Ext.fx.Anim#to to} property which is the end value for all animations.  
36  * 
37  * Popular element 'to' configurations are:
38  * 
39  *  - opacity
40  *  - x
41  *  - y
42  *  - color
43  *  - height
44  *  - width 
45  * 
46  * Popular sprite 'to' configurations are:
47  * 
48  *  - translation
49  *  - path
50  *  - scale
51  *  - stroke
52  *  - rotation
53  * 
54  * The default duration for animations is 250 (which is a 1/4 of a second).  Duration is denoted in 
55  * milliseconds.  Therefore 1 second is 1000, 1 minute would be 60000, and so on. The default easing curve 
56  * used for all animations is 'ease'.  Popular easing functions are included and can be found in {@link Ext.fx.Anim#easing Easing}.
57  * 
58  * For example, a simple animation to fade out an element with a default easing and duration:
59  * 
60  *     var p1 = Ext.get('myElementId');
61  * 
62  *     p1.animate({
63  *         to: {
64  *             opacity: 0
65  *         }
66  *     });
67  * 
68  * To make this animation fade out in a tenth of a second:
69  * 
70  *     var p1 = Ext.get('myElementId');
71  * 
72  *     p1.animate({
73  *        duration: 100,
74  *         to: {
75  *             opacity: 0
76  *         }
77  *     });
78  * 
79  * ## Animation Queues
80  * 
81  * By default all animations are added to a queue which allows for animation via a chain-style API.
82  * For example, the following code will queue 4 animations which occur sequentially (one right after the other):
83  * 
84  *     p1.animate({
85  *         to: {
86  *             x: 500
87  *         }
88  *     }).animate({
89  *         to: {
90  *             y: 150
91  *         }
92  *     }).animate({
93  *         to: {
94  *             backgroundColor: '#f00'  //red
95  *         }
96  *     }).animate({
97  *         to: {
98  *             opacity: 0
99  *         }
100  *     });
101  * 
102  * You can change this behavior by calling the {@link Ext.util.Animate#syncFx syncFx} method and all 
103  * subsequent animations for the specified target will be run concurrently (at the same time).
104  * 
105  *     p1.syncFx();  //this will make all animations run at the same time
106  * 
107  *     p1.animate({
108  *         to: {
109  *             x: 500
110  *         }
111  *     }).animate({
112  *         to: {
113  *             y: 150
114  *         }
115  *     }).animate({
116  *         to: {
117  *             backgroundColor: '#f00'  //red
118  *         }
119  *     }).animate({
120  *         to: {
121  *             opacity: 0
122  *         }
123  *     });
124  * 
125  * This works the same as:
126  * 
127  *     p1.animate({
128  *         to: {
129  *             x: 500,
130  *             y: 150,
131  *             backgroundColor: '#f00'  //red
132  *             opacity: 0
133  *         }
134  *     });
135  * 
136  * The {@link Ext.util.Animate#stopAnimation stopAnimation} method can be used to stop any 
137  * currently running animations and clear any queued animations. 
138  * 
139  * ## Animation Keyframes
140  *
141  * You can also set up complex animations with {@link Ext.fx.Anim#keyframe keyframe} which follows the 
142  * CSS3 Animation configuration pattern. Note rotation, translation, and scaling can only be done for sprites. 
143  * The previous example can be written with the following syntax:
144  * 
145  *     p1.animate({
146  *         duration: 1000,  //one second total
147  *         keyframes: {
148  *             25: {     //from 0 to 250ms (25%)
149  *                 x: 0
150  *             },
151  *             50: {   //from 250ms to 500ms (50%)
152  *                 y: 0
153  *             },
154  *             75: {  //from 500ms to 750ms (75%)
155  *                 backgroundColor: '#f00'  //red
156  *             },
157  *             100: {  //from 750ms to 1sec
158  *                 opacity: 0
159  *             }
160  *         }
161  *     });
162  * 
163  * ## Animation Events
164  * 
165  * Each animation you create has events for {@link Ext.fx.Anim#beforeanimation beforeanimation}, 
166  * {@link Ext.fx.Anim#afteranimate afteranimate}, and {@link Ext.fx.Anim#lastframe lastframe}.  
167  * Keyframed animations adds an additional {@link Ext.fx.Animator#keyframe keyframe} event which 
168  * fires for each keyframe in your animation.
169  * 
170  * All animations support the {@link Ext.util.Observable#listeners listeners} configuration to attact functions to these events.
171  *    
172  *     startAnimate: function() {
173  *         var p1 = Ext.get('myElementId');
174  *         p1.animate({
175  *            duration: 100,
176  *             to: {
177  *                 opacity: 0
178  *             },
179  *             listeners: {
180  *                 beforeanimate:  function() {
181  *                     // Execute my custom method before the animation
182  *                     this.myBeforeAnimateFn();
183  *                 },
184  *                 afteranimate: function() {
185  *                     // Execute my custom method after the animation
186  *                     this.myAfterAnimateFn();
187  *                 },
188  *                 scope: this
189  *         });
190  *     },
191  *     myBeforeAnimateFn: function() {
192  *       // My custom logic
193  *     },
194  *     myAfterAnimateFn: function() {
195  *       // My custom logic
196  *     }
197  * 
198  * Due to the fact that animations run asynchronously, you can determine if an animation is currently 
199  * running on any target by using the {@link Ext.util.Animate#getActiveAnimation getActiveAnimation} 
200  * method.  This method will return false if there are no active animations or return the currently 
201  * running {@link Ext.fx.Anim} instance.
202  * 
203  * In this example, we're going to wait for the current animation to finish, then stop any other 
204  * queued animations before we fade our element's opacity to 0:
205  * 
206  *     var curAnim = p1.getActiveAnimation();
207  *     if (curAnim) {
208  *         curAnim.on('afteranimate', function() {
209  *             p1.stopAnimation();
210  *             p1.animate({
211  *                 to: {
212  *                     opacity: 0
213  *                 }
214  *             });
215  *         });
216  *     }
217  * 
218  * @docauthor Jamie Avins &lt;jamie@sencha.com&gt;
219  */
220 Ext.define('Ext.util.Animate', {
221
222     uses: ['Ext.fx.Manager', 'Ext.fx.Anim'],
223
224 <span id='Ext-util-Animate-method-animate'>    /**
225 </span>     * &lt;p&gt;Perform custom animation on this object.&lt;p&gt;
226      * &lt;p&gt;This method is applicable to both the {@link Ext.Component Component} class and the {@link Ext.core.Element Element} class.
227      * It performs animated transitions of certain properties of this object over a specified timeline.&lt;/p&gt;
228      * &lt;p&gt;The sole parameter is an object which specifies start property values, end property values, and properties which
229      * describe the timeline. Of the properties listed below, only &lt;b&gt;&lt;code&gt;to&lt;/code&gt;&lt;/b&gt; is mandatory.&lt;/p&gt;
230      * &lt;p&gt;Properties include&lt;ul&gt;
231      * &lt;li&gt;&lt;code&gt;from&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;An object which specifies start values for the properties being animated.
232      * If not supplied, properties are animated from current settings. The actual properties which may be animated depend upon
233      * ths object being animated. See the sections below on Element and Component animation.&lt;div&gt;&lt;/li&gt;
234      * &lt;li&gt;&lt;code&gt;to&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;An object which specifies end values for the properties being animated.&lt;/div&gt;&lt;/li&gt;
235      * &lt;li&gt;&lt;code&gt;duration&lt;/code&gt;&lt;div class=&quot;sub-desc&quot;&gt;The duration &lt;b&gt;in milliseconds&lt;/b&gt; for which the animation will run.&lt;/div&gt;&lt;/li&gt;
236      * &lt;li&gt;&lt;code&gt;easing&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;A string value describing an easing type to modify the rate of change from the default linear to non-linear. Values may be one of:&lt;code&gt;&lt;ul&gt;
237      * &lt;li&gt;ease&lt;/li&gt;
238      * &lt;li&gt;easeIn&lt;/li&gt;
239      * &lt;li&gt;easeOut&lt;/li&gt;
240      * &lt;li&gt;easeInOut&lt;/li&gt;
241      * &lt;li&gt;backIn&lt;/li&gt;
242      * &lt;li&gt;backOut&lt;/li&gt;
243      * &lt;li&gt;elasticIn&lt;/li&gt;
244      * &lt;li&gt;elasticOut&lt;/li&gt;
245      * &lt;li&gt;bounceIn&lt;/li&gt;
246      * &lt;li&gt;bounceOut&lt;/li&gt;
247      * &lt;/ul&gt;&lt;/code&gt;&lt;/div&gt;&lt;/li&gt;
248      * &lt;li&gt;&lt;code&gt;keyframes&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;This is an object which describes the state of animated properties at certain points along the timeline.
249      * it is an object containing properties who's names are the percentage along the timeline being described and who's values specify the animation state at that point.&lt;/div&gt;&lt;/li&gt;
250      * &lt;li&gt;&lt;code&gt;listeners&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;This is a standard {@link Ext.util.Observable#listeners listeners} configuration object which may be used
251      * to inject behaviour at either the &lt;code&gt;beforeanimate&lt;/code&gt; event or the &lt;code&gt;afteranimate&lt;/code&gt; event.&lt;/div&gt;&lt;/li&gt;
252      * &lt;/ul&gt;&lt;/p&gt;
253      * &lt;h3&gt;Animating an {@link Ext.core.Element Element}&lt;/h3&gt;
254      * When animating an Element, the following properties may be specified in &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;to&lt;/code&gt;, and &lt;code&gt;keyframe&lt;/code&gt; objects:&lt;ul&gt;
255      * &lt;li&gt;&lt;code&gt;x&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The page X position in pixels.&lt;/div&gt;&lt;/li&gt;
256      * &lt;li&gt;&lt;code&gt;y&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The page Y position in pixels&lt;/div&gt;&lt;/li&gt;
257      * &lt;li&gt;&lt;code&gt;left&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's CSS &lt;code&gt;left&lt;/code&gt; value. Units must be supplied.&lt;/div&gt;&lt;/li&gt;
258      * &lt;li&gt;&lt;code&gt;top&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's CSS &lt;code&gt;top&lt;/code&gt; value. Units must be supplied.&lt;/div&gt;&lt;/li&gt;
259      * &lt;li&gt;&lt;code&gt;width&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's CSS &lt;code&gt;width&lt;/code&gt; value. Units must be supplied.&lt;/div&gt;&lt;/li&gt;
260      * &lt;li&gt;&lt;code&gt;height&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's CSS &lt;code&gt;height&lt;/code&gt; value. Units must be supplied.&lt;/div&gt;&lt;/li&gt;
261      * &lt;li&gt;&lt;code&gt;scrollLeft&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's &lt;code&gt;scrollLeft&lt;/code&gt; value.&lt;/div&gt;&lt;/li&gt;
262      * &lt;li&gt;&lt;code&gt;scrollTop&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's &lt;code&gt;scrollLeft&lt;/code&gt; value.&lt;/div&gt;&lt;/li&gt;
263      * &lt;li&gt;&lt;code&gt;opacity&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The element's &lt;code&gt;opacity&lt;/code&gt; value. This must be a value between &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;.&lt;/div&gt;&lt;/li&gt;
264      * &lt;/ul&gt;
265      * &lt;p&gt;&lt;b&gt;Be aware than animating an Element which is being used by an Ext Component without in some way informing the Component about the changed element state
266      * will result in incorrect Component behaviour. This is because the Component will be using the old state of the element. To avoid this problem, it is now possible to
267      * directly animate certain properties of Components.&lt;/b&gt;&lt;/p&gt;
268      * &lt;h3&gt;Animating a {@link Ext.Component Component}&lt;/h3&gt;
269      * When animating an Element, the following properties may be specified in &lt;code&gt;from&lt;/code&gt;, &lt;code&gt;to&lt;/code&gt;, and &lt;code&gt;keyframe&lt;/code&gt; objects:&lt;ul&gt;
270      * &lt;li&gt;&lt;code&gt;x&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The Component's page X position in pixels.&lt;/div&gt;&lt;/li&gt;
271      * &lt;li&gt;&lt;code&gt;y&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The Component's page Y position in pixels&lt;/div&gt;&lt;/li&gt;
272      * &lt;li&gt;&lt;code&gt;left&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The Component's &lt;code&gt;left&lt;/code&gt; value in pixels.&lt;/div&gt;&lt;/li&gt;
273      * &lt;li&gt;&lt;code&gt;top&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The Component's &lt;code&gt;top&lt;/code&gt; value in pixels.&lt;/div&gt;&lt;/li&gt;
274      * &lt;li&gt;&lt;code&gt;width&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The Component's &lt;code&gt;width&lt;/code&gt; value in pixels.&lt;/div&gt;&lt;/li&gt;
275      * &lt;li&gt;&lt;code&gt;width&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;The Component's &lt;code&gt;width&lt;/code&gt; value in pixels.&lt;/div&gt;&lt;/li&gt;
276      * &lt;li&gt;&lt;code&gt;dynamic&lt;/code&gt; &lt;div class=&quot;sub-desc&quot;&gt;Specify as true to update the Component's layout (if it is a Container) at every frame
277      * of the animation. &lt;i&gt;Use sparingly as laying out on every intermediate size change is an expensive operation&lt;/i&gt;.&lt;/div&gt;&lt;/li&gt;
278      * &lt;/ul&gt;
279      * &lt;p&gt;For example, to animate a Window to a new size, ensuring that its internal layout, and any shadow is correct:&lt;/p&gt;
280      * &lt;pre&gt;&lt;code&gt;
281 myWindow = Ext.create('Ext.window.Window', {
282     title: 'Test Component animation',
283     width: 500,
284     height: 300,
285     layout: {
286         type: 'hbox',
287         align: 'stretch'
288     },
289     items: [{
290         title: 'Left: 33%',
291         margins: '5 0 5 5',
292         flex: 1
293     }, {
294         title: 'Left: 66%',
295         margins: '5 5 5 5',
296         flex: 2
297     }]
298 });
299 myWindow.show();
300 myWindow.header.el.on('click', function() {
301     myWindow.animate({
302         to: {
303             width: (myWindow.getWidth() == 500) ? 700 : 500,
304             height: (myWindow.getHeight() == 300) ? 400 : 300,
305         }
306     });
307 });
308 &lt;/code&gt;&lt;/pre&gt;
309      * &lt;p&gt;For performance reasons, by default, the internal layout is only updated when the Window reaches its final &lt;code&gt;&quot;to&quot;&lt;/code&gt; size. If dynamic updating of the Window's child
310      * Components is required, then configure the animation with &lt;code&gt;dynamic: true&lt;/code&gt; and the two child items will maintain their proportions during the animation.&lt;/p&gt;
311      * @param {Object} config An object containing properties which describe the animation's start and end states, and the timeline of the animation.
312      * @return {Object} this
313      */
314     animate: function(animObj) {
315         var me = this;
316         if (Ext.fx.Manager.hasFxBlock(me.id)) {
317             return me;
318         }
319         Ext.fx.Manager.queueFx(Ext.create('Ext.fx.Anim', me.anim(animObj)));
320         return this;
321     },
322
323     // @private - process the passed fx configuration.
324     anim: function(config) {
325         if (!Ext.isObject(config)) {
326             return (config) ? {} : false;
327         }
328
329         var me = this;
330
331         if (config.stopAnimation) {
332             me.stopAnimation();
333         }
334
335         Ext.applyIf(config, Ext.fx.Manager.getFxDefaults(me.id));
336
337         return Ext.apply({
338             target: me,
339             paused: true
340         }, config);
341     },
342
343 <span id='Ext-util-Animate-method-stopFx'>    /**
344 </span>     * @deprecated 4.0 Replaced by {@link #stopAnimation}
345      * Stops any running effects and clears this object's internal effects queue if it contains
346      * any additional effects that haven't started yet.
347      * @return {Ext.core.Element} The Element
348      * @method
349      */
350     stopFx: Ext.Function.alias(Ext.util.Animate, 'stopAnimation'),
351
352 <span id='Ext-util-Animate-method-stopAnimation'>    /**
353 </span>     * Stops any running effects and clears this object's internal effects queue if it contains
354      * any additional effects that haven't started yet.
355      * @return {Ext.core.Element} The Element
356      */
357     stopAnimation: function() {
358         Ext.fx.Manager.stopAnimation(this.id);
359         return this;
360     },
361
362 <span id='Ext-util-Animate-method-syncFx'>    /**
363 </span>     * Ensures that all effects queued after syncFx is called on this object are
364      * run concurrently.  This is the opposite of {@link #sequenceFx}.
365      * @return {Object} this
366      */
367     syncFx: function() {
368         Ext.fx.Manager.setFxDefaults(this.id, {
369             concurrent: true
370         });
371         return this;
372     },
373
374 <span id='Ext-util-Animate-method-sequenceFx'>    /**
375 </span>     * Ensures that all effects queued after sequenceFx is called on this object are
376      * run in sequence.  This is the opposite of {@link #syncFx}.
377      * @return {Object} this
378      */
379     sequenceFx: function() {
380         Ext.fx.Manager.setFxDefaults(this.id, {
381             concurrent: false
382         });
383         return this;
384     },
385
386 <span id='Ext-util-Animate-method-hasActiveFx'>    /**
387 </span>     * @deprecated 4.0 Replaced by {@link #getActiveAnimation}
388      * Returns thq current animation if this object has any effects actively running or queued, else returns false.
389      * @return {Mixed} anim if element has active effects, else false
390      * @method
391      */
392     hasActiveFx: Ext.Function.alias(Ext.util.Animate, 'getActiveAnimation'),
393
394 <span id='Ext-util-Animate-method-getActiveAnimation'>    /**
395 </span>     * Returns thq current animation if this object has any effects actively running or queued, else returns false.
396      * @return {Mixed} anim if element has active effects, else false
397      */
398     getActiveAnimation: function() {
399         return Ext.fx.Manager.getActiveAnimation(this.id);
400     }
401 }, function(){
402     // Apply Animate mixin manually until Element is defined in the proper 4.x way
403     Ext.applyIf(Ext.core.Element.prototype, this.prototype);
404     // We need to call this again so the animation methods get copied over to CE
405     Ext.CompositeElementLite.importElementMethods();
406 });</pre>
407 </body>
408 </html>