<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-fx-Anim'>/**
|
</span> * This class manages animation for a specific {@link #target}. The animation allows
|
* animation of various properties on the target, such as size, position, color and others.
|
*
|
* ## Starting Conditions
|
*
|
* The starting conditions for the animation are provided by the {@link #from} configuration.
|
* Any/all of the properties in the {@link #from} configuration can be specified. If a particular
|
* property is not defined, the starting value for that property will be read directly from the target.
|
*
|
* ## End Conditions
|
*
|
* The ending conditions for the animation are provided by the {@link #to} configuration. These mark
|
* the final values once the animations has finished. The values in the {@link #from} can mirror
|
* those in the {@link #to} configuration to provide a starting point.
|
*
|
* ## Other Options
|
*
|
* - {@link #duration}: Specifies the time period of the animation.
|
* - {@link #easing}: Specifies the easing of the animation.
|
* - {@link #iterations}: Allows the animation to repeat a number of times.
|
* - {@link #alternate}: Used in conjunction with {@link #iterations}, reverses the direction every second iteration.
|
*
|
* ## Example Code
|
*
|
* @example
|
* var myComponent = Ext.create('Ext.Component', {
|
* renderTo: document.body,
|
* width: 200,
|
* height: 200,
|
* style: 'border: 1px solid red;'
|
* });
|
*
|
* Ext.create('Ext.fx.Anim', {
|
* target: myComponent,
|
* duration: 1000,
|
* from: {
|
* width: 400 //starting width 400
|
* },
|
* to: {
|
* width: 300, //end width 300
|
* height: 300 // end height 300
|
* }
|
* });
|
*/
|
Ext.define('Ext.fx.Anim', {
|
|
/* Begin Definitions */
|
|
mixins: {
|
observable: 'Ext.util.Observable'
|
},
|
|
requires: ['Ext.fx.Manager', 'Ext.fx.Animator', 'Ext.fx.Easing', 'Ext.fx.CubicBezier', 'Ext.fx.PropertyHandler'],
|
|
/* End Definitions */
|
|
<span id='Ext-fx-Anim-property-isAnimation'> /**
|
</span> * @property {Boolean} isAnimation
|
* `true` in this class to identify an object as an instantiated Anim, or subclass thereof.
|
*/
|
isAnimation: true,
|
|
<span id='Ext-fx-Anim-cfg-callback'> /**
|
</span> * @cfg {Function} callback
|
* A function to be run after the animation has completed.
|
*/
|
|
<span id='Ext-fx-Anim-cfg-scope'> /**
|
</span> * @cfg {Function} scope
|
* The scope that the {@link #callback} function will be called with
|
*/
|
|
<span id='Ext-fx-Anim-cfg-duration'> /**
|
</span> * @cfg {Number} duration
|
* Time in milliseconds for a single animation to last. If the {@link #iterations} property is
|
* specified, then each animate will take the same duration for each iteration.
|
*/
|
duration: 250,
|
|
<span id='Ext-fx-Anim-cfg-delay'> /**
|
</span> * @cfg {Number} delay
|
* Time to delay before starting the animation.
|
*/
|
delay: 0,
|
|
<span id='Ext-fx-Anim-property-delayStart'> /* @private used to track a delayed starting time */
|
</span> delayStart: 0,
|
|
<span id='Ext-fx-Anim-cfg-dynamic'> /**
|
</span> * @cfg {Boolean} dynamic
|
* Currently only for Component Animation: Only set a component's outer element size bypassing layouts.
|
* Set to true to do full layouts for every frame of the animation.
|
*/
|
dynamic: false,
|
|
<span id='Ext-fx-Anim-cfg-easing'> /**
|
</span> * @cfg {String} easing
|
* This describes how the intermediate values used during a transition will be calculated.
|
* It allows for a transition to change speed over its duration.
|
*
|
* - backIn
|
* - backOut
|
* - bounceIn
|
* - bounceOut
|
* - ease
|
* - easeIn
|
* - easeOut
|
* - easeInOut
|
* - elasticIn
|
* - elasticOut
|
* - cubic-bezier(x1, y1, x2, y2)
|
*
|
* Note that cubic-bezier will create a custom easing curve following the CSS3 [transition-timing-function][0]
|
* specification. The four values specify points P1 and P2 of the curve as (x1, y1, x2, y2). All values must
|
* be in the range [0, 1] or the definition is invalid.
|
*
|
* [0]: http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag
|
*/
|
easing: 'ease',
|
|
<span id='Ext-fx-Anim-cfg-keyframes'> /**
|
</span> * @cfg {Object} keyframes
|
* Animation keyframes follow the CSS3 Animation configuration pattern. 'from' is always considered '0%' and 'to'
|
* is considered '100%'. **Every keyframe declaration must have a keyframe rule for 0% and 100%, possibly defined using
|
* "from" or "to".** A keyframe declaration without these keyframe selectors is invalid and will not be available for
|
* animation. The keyframe declaration for a keyframe rule consists of properties and values. Properties that are unable to
|
* be animated are ignored in these rules, with the exception of 'easing' which can be changed at each keyframe. For example:
|
*
|
* keyframes : {
|
* '0%': {
|
* left: 100
|
* },
|
* '40%': {
|
* left: 150
|
* },
|
* '60%': {
|
* left: 75
|
* },
|
* '100%': {
|
* left: 100
|
* }
|
* }
|
*/
|
|
<span id='Ext-fx-Anim-property-damper'> /**
|
</span> * @private
|
*/
|
damper: 1,
|
|
<span id='Ext-fx-Anim-property-bezierRE'> /**
|
</span> * @private
|
*/
|
bezierRE: /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
|
|
<span id='Ext-fx-Anim-cfg-reverse'> /**
|
</span> * Run the animation from the end to the beginning
|
* Defaults to false.
|
* @cfg {Boolean} reverse
|
*/
|
reverse: false,
|
|
<span id='Ext-fx-Anim-property-running'> /**
|
</span> * Flag to determine if the animation has started
|
* @property running
|
* @type Boolean
|
*/
|
running: false,
|
|
<span id='Ext-fx-Anim-property-paused'> /**
|
</span> * Flag to determine if the animation is paused. Only set this to true if you need to
|
* keep the Anim instance around to be unpaused later; otherwise call {@link #end}.
|
* @property paused
|
* @type Boolean
|
*/
|
paused: false,
|
|
<span id='Ext-fx-Anim-cfg-iterations'> /**
|
</span> * @cfg {Number} iterations
|
* Number of times to execute the animation.
|
*/
|
iterations: 1,
|
|
<span id='Ext-fx-Anim-cfg-alternate'> /**
|
</span> * @cfg {Boolean} alternate
|
* Used in conjunction with iterations to reverse the animation each time an iteration completes.
|
*/
|
alternate: false,
|
|
<span id='Ext-fx-Anim-property-currentIteration'> /**
|
</span> * Current iteration the animation is running.
|
* @property currentIteration
|
* @type Number
|
*/
|
currentIteration: 0,
|
|
<span id='Ext-fx-Anim-property-startTime'> /**
|
</span> * Starting time of the animation.
|
* @property startTime
|
* @type Date
|
*/
|
startTime: 0,
|
|
<span id='Ext-fx-Anim-property-propHandlers'> /**
|
</span> * Contains a cache of the interpolators to be used.
|
* @private
|
* @property propHandlers
|
* @type Object
|
*/
|
|
<span id='Ext-fx-Anim-cfg-target'> /**
|
</span> * @cfg {String/Object} target
|
* The {@link Ext.fx.target.Target} to apply the animation to. This should only be specified when creating an Ext.fx.Anim directly.
|
* The target does not need to be a {@link Ext.fx.target.Target} instance, it can be the underlying object. For example, you can
|
* pass a Component, Element or Sprite as the target and the Anim will create the appropriate {@link Ext.fx.target.Target} object
|
* automatically.
|
*/
|
|
<span id='Ext-fx-Anim-cfg-from'> /**
|
</span> * @cfg {Object} from
|
* An object containing property/value pairs for the beginning of the animation. If not specified, the current state of the
|
* Ext.fx.target will be used. For example:
|
*
|
* from: {
|
* opacity: 0, // Transparent
|
* color: '#ffffff', // White
|
* left: 0
|
* }
|
*
|
*/
|
|
<span id='Ext-fx-Anim-cfg-to'> /**
|
</span> * @cfg {Object} to (required)
|
* An object containing property/value pairs for the end of the animation. For example:
|
*
|
* to: {
|
* opacity: 1, // Opaque
|
* color: '#00ff00', // Green
|
* left: 500
|
* }
|
*
|
*/
|
|
<span id='Ext-fx-Anim-property-frameCount'> // @private
|
</span> frameCount: 0,
|
|
<span id='Ext-fx-Anim-method-constructor'> // @private
|
</span> constructor: function(config) {
|
var me = this,
|
curve;
|
|
config = config || {};
|
// If keyframes are passed, they really want an Animator instead.
|
if (config.keyframes) {
|
return new Ext.fx.Animator(config);
|
}
|
Ext.apply(me, config);
|
if (me.from === undefined) {
|
me.from = {};
|
}
|
me.propHandlers = {};
|
me.config = config;
|
me.target = Ext.fx.Manager.createTarget(me.target);
|
me.easingFn = Ext.fx.Easing[me.easing];
|
me.target.dynamic = me.dynamic;
|
|
// If not a pre-defined curve, try a cubic-bezier
|
if (!me.easingFn) {
|
me.easingFn = String(me.easing).match(me.bezierRE);
|
if (me.easingFn && me.easingFn.length == 5) {
|
curve = me.easingFn;
|
me.easingFn = Ext.fx.CubicBezier.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]);
|
}
|
}
|
me.id = Ext.id(null, 'ext-anim-');
|
me.addEvents(
|
<span id='Ext-fx-Anim-event-beforeanimate'> /**
|
</span> * @event beforeanimate
|
* Fires before the animation starts. A handler can return false to cancel the animation.
|
* @param {Ext.fx.Anim} this
|
*/
|
'beforeanimate',
|
<span id='Ext-fx-Anim-event-afteranimate'> /**
|
</span> * @event afteranimate
|
* Fires when the animation is complete.
|
* @param {Ext.fx.Anim} this
|
* @param {Date} startTime
|
*/
|
'afteranimate',
|
<span id='Ext-fx-Anim-event-lastframe'> /**
|
</span> * @event lastframe
|
* Fires when the animation's last frame has been set.
|
* @param {Ext.fx.Anim} this
|
* @param {Date} startTime
|
*/
|
'lastframe'
|
);
|
me.mixins.observable.constructor.call(me);
|
Ext.fx.Manager.addAnim(me);
|
},
|
|
<span id='Ext-fx-Anim-method-setAttr'> /**
|
</span> * @private
|
* Helper to the target
|
*/
|
setAttr: function(attr, value) {
|
return Ext.fx.Manager.items.get(this.id).setAttr(this.target, attr, value);
|
},
|
|
<span id='Ext-fx-Anim-method-initAttrs'> /**
|
</span> * @private
|
* Set up the initial currentAttrs hash.
|
*/
|
initAttrs: function() {
|
var me = this,
|
from = me.from,
|
to = me.to,
|
initialFrom = me.initialFrom || {},
|
out = {},
|
start, end, propHandler, attr;
|
|
for (attr in to) {
|
if (to.hasOwnProperty(attr)) {
|
start = me.target.getAttr(attr, from[attr]);
|
end = to[attr];
|
// Use default (numeric) property handler
|
if (!Ext.fx.PropertyHandler[attr]) {
|
if (Ext.isObject(end)) {
|
propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler.object;
|
} else {
|
propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler.defaultHandler;
|
}
|
}
|
// Use custom handler
|
else {
|
propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler[attr];
|
}
|
out[attr] = propHandler.get(start, end, me.damper, initialFrom[attr], attr);
|
}
|
}
|
me.currentAttrs = out;
|
},
|
|
<span id='Ext-fx-Anim-method-start'> /**
|
</span> * @private
|
* Fires beforeanimate and sets the running flag.
|
*/
|
start: function(startTime) {
|
var me = this,
|
delay = me.delay,
|
delayStart = me.delayStart,
|
delayDelta;
|
|
if (delay) {
|
if (!delayStart) {
|
me.delayStart = startTime;
|
return;
|
}
|
else {
|
delayDelta = startTime - delayStart;
|
if (delayDelta < delay) {
|
return;
|
}
|
else {
|
// Compensate for frame delay;
|
startTime = new Date(delayStart.getTime() + delay);
|
}
|
}
|
}
|
if (me.fireEvent('beforeanimate', me) !== false) {
|
me.startTime = startTime;
|
if (!me.paused && !me.currentAttrs) {
|
me.initAttrs();
|
}
|
me.running = true;
|
me.frameCount = 0;
|
}
|
},
|
|
<span id='Ext-fx-Anim-method-runAnim'> /**
|
</span> * @private
|
* Calculate attribute value at the passed timestamp.
|
* @returns a hash of the new attributes.
|
*/
|
runAnim: function(elapsedTime) {
|
var me = this,
|
attrs = me.currentAttrs,
|
duration = me.duration,
|
easingFn = me.easingFn,
|
propHandlers = me.propHandlers,
|
ret = {},
|
easing, values, attr, lastFrame;
|
|
if (elapsedTime >= duration) {
|
elapsedTime = duration;
|
lastFrame = true;
|
}
|
if (me.reverse) {
|
elapsedTime = duration - elapsedTime;
|
}
|
|
for (attr in attrs) {
|
if (attrs.hasOwnProperty(attr)) {
|
values = attrs[attr];
|
easing = lastFrame ? 1 : easingFn(elapsedTime / duration);
|
ret[attr] = propHandlers[attr].set(values, easing);
|
}
|
}
|
me.frameCount++;
|
|
return ret;
|
},
|
|
<span id='Ext-fx-Anim-method-lastFrame'> /**
|
</span> * @private
|
* Perform lastFrame cleanup and handle iterations
|
* @returns a hash of the new attributes.
|
*/
|
lastFrame: function() {
|
var me = this,
|
iter = me.iterations,
|
iterCount = me.currentIteration;
|
|
iterCount++;
|
if (iterCount < iter) {
|
if (me.alternate) {
|
me.reverse = !me.reverse;
|
}
|
me.startTime = new Date();
|
me.currentIteration = iterCount;
|
// Turn off paused for CSS3 Transitions
|
me.paused = false;
|
}
|
else {
|
me.currentIteration = 0;
|
me.end();
|
me.fireEvent('lastframe', me, me.startTime);
|
}
|
},
|
|
<span id='Ext-fx-Anim-property-endWasCalled'> endWasCalled: 0,
|
</span>
|
<span id='Ext-fx-Anim-method-end'> /**
|
</span> * Fire afteranimate event and end the animation. Usually called automatically when the
|
* animation reaches its final frame, but can also be called manually to pre-emptively
|
* stop and destroy the running animation.
|
*/
|
end: function() {
|
if (this.endWasCalled++) {
|
return;
|
}
|
var me = this;
|
me.startTime = 0;
|
me.paused = false;
|
me.running = false;
|
Ext.fx.Manager.removeAnim(me);
|
me.fireEvent('afteranimate', me, me.startTime);
|
Ext.callback(me.callback, me.scope, [me, me.startTime]);
|
},
|
|
<span id='Ext-fx-Anim-method-isReady'> isReady: function() {
|
</span> return this.paused === false && this.running === false && this.iterations > 0;
|
},
|
|
<span id='Ext-fx-Anim-method-isRunning'> isRunning: function() {
|
</span> return this.paused === false && this.running === true && this.isAnimator !== true;
|
}
|
});
|
// Set flag to indicate that Fx is available. Class might not be available immediately.
|
Ext.enableFx = true;
|
</pre>
|
</body>
|
</html>
|