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