UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

155 lines (147 loc) 4.67 kB
/** _enyo.Animator_ is a basic animation component. Call _play_ to start the animation. The animation will run for the period (in milliseconds) specified by its _duration_ property. The _onStep_ event will fire in quick succession and should be handled to do something based on the _value_ property. The _value_ property will progress from _startValue_ to _endValue_ during the animation based on the function referenced by the _easingFunction_ property. The _stop_ method may be called to manually stop an in-progress animation; calling it will fire the _onStop_ event. When an animation completes normally, the _onEnd_ event is fired. Event handlers may be specified as functions. If specified, the handler function will be used to handle the event directly, without sending the event to its owner or bubbling it. The _context_ property can be used to call the supplied event functions in a particular "this" context. During animation, an <a href="#enyo.jobs">enyo.jobs</a> priority of 5 is registered to defer low priority tasks. */ enyo.kind({ name: "enyo.Animator", kind: "Component", published: { //* Animation duration in milliseconds duration: 350, //* Value of _value_ property at the beginning of an animation startValue: 0, //* Value of _value_ property at the end of an animation endValue: 1, //* Node that must be visible in order for the animation to continue. //* This reference is destroyed when the animation ceases. node: null, //* Function that determines how the animation progresses from //* _startValue_ to _endValue_ easingFunction: enyo.easing.cubicOut }, events: { //* Fires when an animation step occurs. onStep: "", //* Fires when the animation finishes normally. onEnd: "", //* Fires when the animation is prematurely stopped. onStop: "" }, //* @protected constructed: enyo.inherit(function (sup) { return function() { sup.apply(this, arguments); this._next = this.bindSafely("next"); }; }), destroy: enyo.inherit(function (sup) { return function() { this.stop(); sup.apply(this, arguments); }; }), //* @public //* Plays the animation. //* For convenience, _inProps_ will be mixed directly into this object. play: function(inProps) { this.stop(); this.reversed = false; if (inProps) { enyo.mixin(this, inProps); } this.t0 = this.t1 = enyo.now(); this.value = this.startValue; // register this jobPriority to block less urgent tasks from executing enyo.jobs.registerPriority(5, this.id); this.job = true; this.next(); return this; }, //* Stops the animation and fires the _onStop_ event. stop: function() { if (this.isAnimating()) { this.cancel(); this.fire("onStop"); return this; } }, //* Reverses the direction of a running animation; returns self if animating. reverse: function() { if (this.isAnimating()) { this.reversed = !this.reversed; var now = this.t1 = enyo.now(); // adjust start time (t0) to allow for animation done so far to replay var elapsed = now - this.t0; this.t0 = now + elapsed - this.duration; // swap start and end values var startValue = this.startValue; this.startValue = this.endValue; this.endValue = startValue; return this; } }, //* Returns true if animation is in progress. isAnimating: function() { return Boolean(this.job); }, //* @protected requestNext: function() { this.job = enyo.requestAnimationFrame(this._next, this.node); }, cancel: function() { enyo.cancelRequestAnimationFrame(this.job); this.node = null; this.job = null; // unblock job queue enyo.jobs.unregisterPriority(this.id); }, shouldEnd: function() { return (this.dt >= this.duration); }, next: function() { this.t1 = enyo.now(); this.dt = this.t1 - this.t0; var args = this.easingFunction.length; var f; if (args === 1) { // time independent f = this.fraction = enyo.easedLerp(this.t0, this.duration, this.easingFunction, this.reversed); this.value = this.startValue + f * (this.endValue - this.startValue); } else { this.value = enyo.easedComplexLerp(this.t0, this.duration, this.easingFunction, this.reversed, this.dt, this.startValue, (this.endValue - this.startValue)); } if (((f >= 1) && (args === 1)) || this.shouldEnd()) { this.value = this.endValue; this.fraction = 1; this.fire("onStep"); this.cancel(); this.fire("onEnd"); } else { this.fire("onStep"); this.requestNext(); } }, fire: function(inEventName) { var fn = this[inEventName]; if (enyo.isString(fn)) { this.bubble(inEventName); } else if (fn) { fn.call(this.context || window, this); } } });