2 * Ext.Anim is used to execute simple animations defined in {@link Ext.anims}. The {@link #run} method can take any of the
3 * properties defined below.
5 * Ext.Anim.run(this, 'fade', {
10 * When using {@link Ext.Anim#run}, ensure you require {@link Ext.Anim} in your application. Either do this using {@link Ext#require}:
12 * Ext.requires('Ext.Anim');
14 * when using {@link Ext#setup}:
17 * requires: ['Ext.Anim'],
18 * onReady: function() {
23 * or when using {@link Ext#application}:
26 * requires: ['Ext.Anim'],
27 * launch: function() {
35 Ext
.define('Ext.Anim', {
39 * @cfg {Boolean} disableAnimations
40 * `true` to disable animations.
42 disableAnimations
: false,
47 * An object of CSS values which the animation begins with. If you define a CSS property here, you must also
48 * define it in the {@link #to} config.
54 * An object of CSS values which the animation ends with. If you define a CSS property here, you must also
55 * define it in the {@link #from} config.
60 * @cfg {Number} duration
61 * Time in milliseconds for the animation to last.
66 * @cfg {Number} delay Time to delay before starting the animation.
71 * @cfg {String} easing
72 * Valid values are 'ease', 'linear', ease-in', 'ease-out', 'ease-in-out', or a cubic-bezier curve as defined by CSS.
74 easing
: 'ease-in-out',
77 * @cfg {Boolean} autoClear
78 * `true` to remove all custom CSS defined in the {@link #to} config when the animation is over.
84 * `true` if you want the animation to slide out of the screen.
89 * @cfg {String} direction
90 * Valid values are: 'left', 'right', 'up', 'down', and `null`.
95 * @cfg {Boolean} reverse
96 * `true` to reverse the animation direction. For example, if the animation direction was set to 'left', it would
103 * @cfg {Function} before
104 * Code to execute before starting the animation.
108 * @cfg {Function} after
109 * Code to execute after the animation ends.
113 * @cfg {Object} scope
114 * Scope to run the {@link #before} function in.
124 constructor: function(config
) {
125 config
= Ext
.apply({}, config
|| {}, this.defaultConfig
);
126 this.config
= config
;
128 this.callSuper([config
]);
133 initConfig: function(el
, runConfig
) {
135 config
= Ext
.apply({}, runConfig
|| {}, me
.config
);
137 config
.el
= el
= Ext
.get(el
);
139 if (config
.reverse
&& me
.opposites
[config
.direction
]) {
140 config
.direction
= me
.opposites
[config
.direction
];
143 if (me
.config
.before
) {
144 me
.config
.before
.call(config
, el
, config
);
147 if (runConfig
.before
) {
148 runConfig
.before
.call(config
.scope
|| config
, el
, config
);
157 run: function(el
, config
) {
159 config
= config
|| {};
163 style
= el
.dom
.style
,
165 after
= config
.after
;
167 if (me
.running
[el
.id
]) {
168 me
.onTransitionEnd(null, el
, {
174 config
= this.initConfig(el
, config
);
176 if (this.disableAnimations
) {
177 for (property
in config
.to
) {
178 if (!config
.to
.hasOwnProperty(property
)) {
181 style
[property
] = config
.to
[property
];
183 this.onTransitionEnd(null, el
, {
190 el
.un('transitionend', me
.onTransitionEnd
, me
);
192 style
.webkitTransitionDuration
= '0ms';
193 for (property
in config
.from) {
194 if (!config
.from.hasOwnProperty(property
)) {
197 style
[property
] = config
.from[property
];
200 setTimeout(function() {
201 // If this element has been destroyed since the timeout started, do nothing
206 // If this is a 3d animation we have to set the perspective on the parent
207 if (config
.is3d
=== true) {
208 el
.parent().setStyle({
209 // See https://sencha.jira.com/browse/TOUCH-1498
210 '-webkit-perspective': '1200',
211 '-webkit-transform-style': 'preserve-3d'
215 style
.webkitTransitionDuration
= config
.duration
+ 'ms';
216 style
.webkitTransitionProperty
= 'all';
217 style
.webkitTransitionTimingFunction
= config
.easing
;
219 // Bind our listener that fires after the animation ends
220 el
.on('transitionend', me
.onTransitionEnd
, me
, {
226 for (property
in config
.to
) {
227 if (!config
.to
.hasOwnProperty(property
)) {
230 style
[property
] = config
.to
[property
];
232 }, config
.delay
|| 5);
234 me
.running
[el
.id
] = config
;
238 onTransitionEnd: function(ev
, el
, o
) {
241 if (this.running
[el
.id
] === undefined) {
245 var style
= el
.dom
.style
,
250 if (config
.autoClear
) {
251 for (property
in config
.to
) {
252 if (!config
.to
.hasOwnProperty(property
) || config
[property
] === false) {
255 style
[property
] = '';
259 style
.webkitTransitionDuration
= null;
260 style
.webkitTransitionProperty
= null;
261 style
.webkitTransitionTimingFunction
= null;
264 el
.parent().setStyle({
265 '-webkit-perspective': '',
266 '-webkit-transform-style': ''
270 if (me
.config
.after
) {
271 me
.config
.after
.call(config
, el
, config
);
275 o
.after
.call(config
.scope
|| me
, el
, config
);
278 delete me
.running
[el
.id
];
282 Ext
.Anim
.seed
= 1000;
285 * Used to run an animation on a specific element. Use the config argument to customize the animation.
286 * @param {Ext.Element/HTMLElement} el The element to animate.
287 * @param {String} anim The animation type, defined in {@link Ext.anims}.
288 * @param {Object} config The config object for the animation.
291 Ext
.Anim
.run = function(el
, anim
, config
) {
292 if (el
.isComponent
) {
298 config
= config
|| {};
301 anim
.run(el
, config
);
304 if (Ext
.isObject(anim
)) {
305 if (config
.before
&& anim
.before
) {
306 config
.before
= Ext
.createInterceptor(config
.before
, anim
.before
, anim
.scope
);
308 if (config
.after
&& anim
.after
) {
309 config
.after
= Ext
.createInterceptor(config
.after
, anim
.after
, anim
.scope
);
311 config
= Ext
.apply({}, config
, anim
);
315 if (!Ext
.anims
[anim
]) {
316 throw anim
+ ' is not a valid animation type.';
319 // add el check to make sure dom exists.
321 Ext
.anims
[anim
].run(el
, config
);
329 * Defines different types of animations.
331 * __Note:__ _flip_, _cube_, and _wipe_ animations do not work on Android.
333 * Please refer to {@link Ext.Anim} on how to use animations.
342 before: function(el
) {
345 curZ
= el
.getStyle('z-index') == 'auto' ? 0 : el
.getStyle('z-index'),
351 zIndex
= Math
.abs(curZ
) + 1;
356 'opacity': fromOpacity
,
360 'opacity': toOpacity
,
369 slide
: new Ext
.Anim({
376 before: function(el
) {
377 var currentZIndex
= el
.getStyle('z-index') == 'auto' ? 0 : el
.getStyle('z-index'),
378 currentOpacity
= el
.getStyle('opacity'),
379 zIndex
= currentZIndex
+ 1,
381 direction
= this.direction
,
386 elH
= el
.getHeight(),
389 if (direction
== 'left' || direction
== 'right') {
397 else if (direction
== 'up' || direction
== 'down') {
406 if (direction
== 'right' || direction
== 'down') {
413 if (this.cover
&& out
) {
416 zIndex
= currentZIndex
;
418 else if (this.reveal
&& !out
) {
421 zIndex
= currentZIndex
;
425 '-webkit-transform': 'translate3d(' + fromX
+ 'px, ' + fromY
+ 'px, 0)',
427 'opacity': currentOpacity
- 0.01
430 '-webkit-transform': 'translate3d(' + toX
+ 'px, ' + toY
+ 'px, 0)',
432 'opacity': currentOpacity
442 before: function(el
) {
447 curZ
= el
.getStyle('z-index') == 'auto' ? 0 : el
.getStyle('z-index'),
458 if (this.scaleOnExit
) {
467 '-webkit-transform': 'scale(' + fromScale
+ ')',
468 '-webkit-transform-origin': '50% 50%',
469 'opacity': fromOpacity
,
474 '-webkit-transform': 'scale(' + toScale
+ ')',
475 '-webkit-transform-origin': '50% 50%',
476 'opacity': toOpacity
,
488 before: function(el
) {
489 var rotateProp
= 'Y',
504 if (this.direction
== 'up' || this.direction
== 'down') {
508 if (this.direction
== 'right' || this.direction
== 'left') {
514 '-webkit-transform': 'rotate' + rotateProp
+ '(' + fromRotate
+ 'deg) scale(' + fromScale
+ ')',
515 '-webkit-backface-visibility': 'hidden'
518 '-webkit-transform': 'rotate' + rotateProp
+ '(' + toRotate
+ 'deg) scale(' + toScale
+ ')',
519 '-webkit-backface-visibility': 'hidden'
531 before: function(el
) {
532 var origin
= '0% 0%',
539 elH
= el
.getHeight(),
540 showTranslateZ
= true,
541 fromTranslate
= ' translateX(0)',
544 if (this.direction
== 'left' || this.direction
== 'right') {
546 origin
= '100% 100%';
554 } else if (this.direction
== 'up' || this.direction
== 'down') {
557 origin
= '100% 100%';
567 if (this.direction
== 'down' || this.direction
== 'right') {
570 origin
= (origin
== '0% 0%') ? '100% 100%': '0% 0%';
573 if (this.style
== 'inner') {
580 toTranslate
= ' translateX(0px)';
583 toTranslate
= fromTranslate
;
589 '-webkit-transform': 'rotate' + rotateProp
+ '(' + fromRotate
+ 'deg)' + (showTranslateZ
? ' translateZ(' + fromZ
+ 'px)': '') + fromTranslate
,
590 '-webkit-transform-origin': origin
593 '-webkit-transform': 'rotate' + rotateProp
+ '(' + toRotate
+ 'deg) translateZ(' + toZ
+ 'px)' + toTranslate
,
594 '-webkit-transform-origin': origin
603 * Because of the amount of calculations involved, this animation is best used on small display
604 * changes or specifically for phone environments. Does not currently accept any parameters.
607 before: function(el
) {
608 var curZ
= el
.getStyle('z-index'),
614 mask
= '-webkit-gradient(linear, left bottom, right bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';
617 '-webkit-mask-image': mask
,
618 '-webkit-mask-size': el
.getWidth() * 3 + 'px ' + el
.getHeight() + 'px',
620 '-webkit-mask-position-x': 0
623 '-webkit-mask-image': mask
,
624 '-webkit-mask-size': el
.getWidth() * 3 + 'px ' + el
.getHeight() + 'px',
626 '-webkit-mask-position-x': -el
.getWidth() * 2 + 'px'