|
|
- /*!
- * TweenJS
- * Visit http://createjs.com/ for documentation, updates and examples.
- *
- * Copyright (c) 2010 gskinner.com, inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
- //##############################################################################
- // extend.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- /**
- * @class Utility Methods
- */
-
- /**
- * Sets up the prototype chain and constructor property for a new class.
- *
- * This should be called right after creating the class constructor.
- *
- * function MySubClass() {}
- * createjs.extend(MySubClass, MySuperClass);
- * MySubClass.prototype.doSomething = function() { }
- *
- * var foo = new MySubClass();
- * console.log(foo instanceof MySuperClass); // true
- * console.log(foo.prototype.constructor === MySubClass); // true
- *
- * @method extend
- * @param {Function} subclass The subclass.
- * @param {Function} superclass The superclass to extend.
- * @return {Function} Returns the subclass's new prototype.
- */
- createjs.extend = function(subclass, superclass) {
- "use strict";
-
- function o() { this.constructor = subclass; }
- o.prototype = superclass.prototype;
- return (subclass.prototype = new o());
- };
-
- //##############################################################################
- // promote.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- /**
- * @class Utility Methods
- */
-
- /**
- * Promotes any methods on the super class that were overridden, by creating an alias in the format `prefix_methodName`.
- * It is recommended to use the super class's name as the prefix.
- * An alias to the super class's constructor is always added in the format `prefix_constructor`.
- * This allows the subclass to call super class methods without using `function.call`, providing better performance.
- *
- * For example, if `MySubClass` extends `MySuperClass`, and both define a `draw` method, then calling `promote(MySubClass, "MySuperClass")`
- * would add a `MySuperClass_constructor` method to MySubClass and promote the `draw` method on `MySuperClass` to the
- * prototype of `MySubClass` as `MySuperClass_draw`.
- *
- * This should be called after the class's prototype is fully defined.
- *
- * function ClassA(name) {
- * this.name = name;
- * }
- * ClassA.prototype.greet = function() {
- * return "Hello "+this.name;
- * }
- *
- * function ClassB(name, punctuation) {
- * this.ClassA_constructor(name);
- * this.punctuation = punctuation;
- * }
- * createjs.extend(ClassB, ClassA);
- * ClassB.prototype.greet = function() {
- * return this.ClassA_greet()+this.punctuation;
- * }
- * createjs.promote(ClassB, "ClassA");
- *
- * var foo = new ClassB("World", "!?!");
- * console.log(foo.greet()); // Hello World!?!
- *
- * @method promote
- * @param {Function} subclass The class to promote super class methods on.
- * @param {String} prefix The prefix to add to the promoted method names. Usually the name of the superclass.
- * @return {Function} Returns the subclass.
- */
- createjs.promote = function(subclass, prefix) {
- "use strict";
-
- var subP = subclass.prototype, supP = (Object.getPrototypeOf&&Object.getPrototypeOf(subP))||subP.__proto__;
- if (supP) {
- subP[(prefix+="_") + "constructor"] = supP.constructor; // constructor is not always innumerable
- for (var n in supP) {
- if (subP.hasOwnProperty(n) && (typeof supP[n] == "function")) { subP[prefix + n] = supP[n]; }
- }
- }
- return subclass;
- };
-
- //##############################################################################
- // Event.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- (function() {
- "use strict";
-
- // constructor:
- /**
- * Contains properties and methods shared by all events for use with
- * {{#crossLink "EventDispatcher"}}{{/crossLink}}.
- *
- * Note that Event objects are often reused, so you should never
- * rely on an event object's state outside of the call stack it was received in.
- * @class Event
- * @param {String} type The event type.
- * @param {Boolean} bubbles Indicates whether the event will bubble through the display list.
- * @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled.
- * @constructor
- **/
- function Event(type, bubbles, cancelable) {
-
-
- // public properties:
- /**
- * The type of event.
- * @property type
- * @type String
- **/
- this.type = type;
-
- /**
- * The object that generated an event.
- * @property target
- * @type Object
- * @default null
- * @readonly
- */
- this.target = null;
-
- /**
- * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will
- * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event
- * is generated from childObj, then a listener on parentObj would receive the event with
- * target=childObj (the original target) and currentTarget=parentObj (where the listener was added).
- * @property currentTarget
- * @type Object
- * @default null
- * @readonly
- */
- this.currentTarget = null;
-
- /**
- * For bubbling events, this indicates the current event phase:<OL>
- * <LI> capture phase: starting from the top parent to the target</LI>
- * <LI> at target phase: currently being dispatched from the target</LI>
- * <LI> bubbling phase: from the target to the top parent</LI>
- * </OL>
- * @property eventPhase
- * @type Number
- * @default 0
- * @readonly
- */
- this.eventPhase = 0;
-
- /**
- * Indicates whether the event will bubble through the display list.
- * @property bubbles
- * @type Boolean
- * @default false
- * @readonly
- */
- this.bubbles = !!bubbles;
-
- /**
- * Indicates whether the default behaviour of this event can be cancelled via
- * {{#crossLink "Event/preventDefault"}}{{/crossLink}}. This is set via the Event constructor.
- * @property cancelable
- * @type Boolean
- * @default false
- * @readonly
- */
- this.cancelable = !!cancelable;
-
- /**
- * The epoch time at which this event was created.
- * @property timeStamp
- * @type Number
- * @default 0
- * @readonly
- */
- this.timeStamp = (new Date()).getTime();
-
- /**
- * Indicates if {{#crossLink "Event/preventDefault"}}{{/crossLink}} has been called
- * on this event.
- * @property defaultPrevented
- * @type Boolean
- * @default false
- * @readonly
- */
- this.defaultPrevented = false;
-
- /**
- * Indicates if {{#crossLink "Event/stopPropagation"}}{{/crossLink}} or
- * {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called on this event.
- * @property propagationStopped
- * @type Boolean
- * @default false
- * @readonly
- */
- this.propagationStopped = false;
-
- /**
- * Indicates if {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called
- * on this event.
- * @property immediatePropagationStopped
- * @type Boolean
- * @default false
- * @readonly
- */
- this.immediatePropagationStopped = false;
-
- /**
- * Indicates if {{#crossLink "Event/remove"}}{{/crossLink}} has been called on this event.
- * @property removed
- * @type Boolean
- * @default false
- * @readonly
- */
- this.removed = false;
- }
- var p = Event.prototype;
-
- /**
- * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
- * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
- * for details.
- *
- * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
- *
- * @method initialize
- * @protected
- * @deprecated
- */
- // p.initialize = function() {}; // searchable for devs wondering where it is.
-
- // public methods:
- /**
- * Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true if the event is cancelable.
- * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will
- * cancel the default behaviour associated with the event.
- * @method preventDefault
- **/
- p.preventDefault = function() {
- this.defaultPrevented = this.cancelable&&true;
- };
-
- /**
- * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} to true.
- * Mirrors the DOM event standard.
- * @method stopPropagation
- **/
- p.stopPropagation = function() {
- this.propagationStopped = true;
- };
-
- /**
- * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} and
- * {{#crossLink "Event/immediatePropagationStopped"}}{{/crossLink}} to true.
- * Mirrors the DOM event standard.
- * @method stopImmediatePropagation
- **/
- p.stopImmediatePropagation = function() {
- this.immediatePropagationStopped = this.propagationStopped = true;
- };
-
- /**
- * Causes the active listener to be removed via removeEventListener();
- *
- * myBtn.addEventListener("click", function(evt) {
- * // do stuff...
- * evt.remove(); // removes this listener.
- * });
- *
- * @method remove
- **/
- p.remove = function() {
- this.removed = true;
- };
-
- /**
- * Returns a clone of the Event instance.
- * @method clone
- * @return {Event} a clone of the Event instance.
- **/
- p.clone = function() {
- return new Event(this.type, this.bubbles, this.cancelable);
- };
-
- /**
- * Provides a chainable shortcut method for setting a number of properties on the instance.
- *
- * @method set
- * @param {Object} props A generic object containing properties to copy to the instance.
- * @return {Event} Returns the instance the method is called on (useful for chaining calls.)
- * @chainable
- */
- p.set = function(props) {
- for (var n in props) { this[n] = props[n]; }
- return this;
- };
-
- /**
- * Returns a string representation of this object.
- * @method toString
- * @return {String} a string representation of the instance.
- **/
- p.toString = function() {
- return "[Event (type="+this.type+")]";
- };
-
- createjs.Event = Event;
- }());
-
- //##############################################################################
- // EventDispatcher.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- (function() {
- "use strict";
-
-
- // constructor:
- /**
- * EventDispatcher provides methods for managing queues of event listeners and dispatching events.
- *
- * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the
- * EventDispatcher {{#crossLink "EventDispatcher/initialize"}}{{/crossLink}} method.
- *
- * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the
- * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports
- * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent.
- *
- * EventDispatcher also exposes a {{#crossLink "EventDispatcher/on"}}{{/crossLink}} method, which makes it easier
- * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The
- * {{#crossLink "EventDispatcher/off"}}{{/crossLink}} method is merely an alias to
- * {{#crossLink "EventDispatcher/removeEventListener"}}{{/crossLink}}.
- *
- * Another addition to the DOM Level 2 model is the {{#crossLink "EventDispatcher/removeAllEventListeners"}}{{/crossLink}}
- * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also
- * includes a {{#crossLink "Event/remove"}}{{/crossLink}} method which removes the active listener.
- *
- * <h4>Example</h4>
- * Add EventDispatcher capabilities to the "MyClass" class.
- *
- * EventDispatcher.initialize(MyClass.prototype);
- *
- * Add an event (see {{#crossLink "EventDispatcher/addEventListener"}}{{/crossLink}}).
- *
- * instance.addEventListener("eventName", handlerMethod);
- * function handlerMethod(event) {
- * console.log(event.target + " Was Clicked");
- * }
- *
- * <b>Maintaining proper scope</b><br />
- * Scope (ie. "this") can be be a challenge with events. Using the {{#crossLink "EventDispatcher/on"}}{{/crossLink}}
- * method to subscribe to events simplifies this.
- *
- * instance.addEventListener("click", function(event) {
- * console.log(instance == this); // false, scope is ambiguous.
- * });
- *
- * instance.on("click", function(event) {
- * console.log(instance == this); // true, "on" uses dispatcher scope by default.
- * });
- *
- * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage
- * scope.
- *
- * <b>Browser support</b>
- * The event model in CreateJS can be used separately from the suite in any project, however the inheritance model
- * requires modern browsers (IE9+).
- *
- *
- * @class EventDispatcher
- * @constructor
- **/
- function EventDispatcher() {
-
-
- // private properties:
- /**
- * @protected
- * @property _listeners
- * @type Object
- **/
- this._listeners = null;
-
- /**
- * @protected
- * @property _captureListeners
- * @type Object
- **/
- this._captureListeners = null;
- }
- var p = EventDispatcher.prototype;
-
- /**
- * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
- * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
- * for details.
- *
- * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
- *
- * @method initialize
- * @protected
- * @deprecated
- */
- // p.initialize = function() {}; // searchable for devs wondering where it is.
-
-
- // static public methods:
- /**
- * Static initializer to mix EventDispatcher methods into a target object or prototype.
- *
- * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class
- * EventDispatcher.initialize(myObject); // add to a specific instance
- *
- * @method initialize
- * @static
- * @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a
- * prototype.
- **/
- EventDispatcher.initialize = function(target) {
- target.addEventListener = p.addEventListener;
- target.on = p.on;
- target.removeEventListener = target.off = p.removeEventListener;
- target.removeAllEventListeners = p.removeAllEventListeners;
- target.hasEventListener = p.hasEventListener;
- target.dispatchEvent = p.dispatchEvent;
- target._dispatchEvent = p._dispatchEvent;
- target.willTrigger = p.willTrigger;
- };
-
-
- // public methods:
- /**
- * Adds the specified event listener. Note that adding multiple listeners to the same function will result in
- * multiple callbacks getting fired.
- *
- * <h4>Example</h4>
- *
- * displayObject.addEventListener("click", handleClick);
- * function handleClick(event) {
- * // Click happened.
- * }
- *
- * @method addEventListener
- * @param {String} type The string type of the event.
- * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
- * the event is dispatched.
- * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
- * @return {Function | Object} Returns the listener for chaining or assignment.
- **/
- p.addEventListener = function(type, listener, useCapture) {
- var listeners;
- if (useCapture) {
- listeners = this._captureListeners = this._captureListeners||{};
- } else {
- listeners = this._listeners = this._listeners||{};
- }
- var arr = listeners[type];
- if (arr) { this.removeEventListener(type, listener, useCapture); }
- arr = listeners[type]; // remove may have deleted the array
- if (!arr) { listeners[type] = [listener]; }
- else { arr.push(listener); }
- return listener;
- };
-
- /**
- * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener
- * only run once, associate arbitrary data with the listener, and remove the listener.
- *
- * This method works by creating an anonymous wrapper function and subscribing it with addEventListener.
- * The wrapper function is returned for use with `removeEventListener` (or `off`).
- *
- * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use
- * {{#crossLink "Event/remove"}}{{/crossLink}}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls
- * to `on` with the same params will create multiple listeners.
- *
- * <h4>Example</h4>
- *
- * var listener = myBtn.on("click", handleClick, null, false, {count:3});
- * function handleClick(evt, data) {
- * data.count -= 1;
- * console.log(this == myBtn); // true - scope defaults to the dispatcher
- * if (data.count == 0) {
- * alert("clicked 3 times!");
- * myBtn.off("click", listener);
- * // alternately: evt.remove();
- * }
- * }
- *
- * @method on
- * @param {String} type The string type of the event.
- * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
- * the event is dispatched.
- * @param {Object} [scope] The scope to execute the listener in. Defaults to the dispatcher/currentTarget for function listeners, and to the listener itself for object listeners (ie. using handleEvent).
- * @param {Boolean} [once=false] If true, the listener will remove itself after the first time it is triggered.
- * @param {*} [data] Arbitrary data that will be included as the second parameter when the listener is called.
- * @param {Boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
- * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener.
- **/
- p.on = function(type, listener, scope, once, data, useCapture) {
- if (listener.handleEvent) {
- scope = scope||listener;
- listener = listener.handleEvent;
- }
- scope = scope||this;
- return this.addEventListener(type, function(evt) {
- listener.call(scope, evt, data);
- once&&evt.remove();
- }, useCapture);
- };
-
- /**
- * Removes the specified event listener.
- *
- * <b>Important Note:</b> that you must pass the exact function reference used when the event was added. If a proxy
- * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or
- * closure will not work.
- *
- * <h4>Example</h4>
- *
- * displayObject.removeEventListener("click", handleClick);
- *
- * @method removeEventListener
- * @param {String} type The string type of the event.
- * @param {Function | Object} listener The listener function or object.
- * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
- **/
- p.removeEventListener = function(type, listener, useCapture) {
- var listeners = useCapture ? this._captureListeners : this._listeners;
- if (!listeners) { return; }
- var arr = listeners[type];
- if (!arr) { return; }
- for (var i=0,l=arr.length; i<l; i++) {
- if (arr[i] == listener) {
- if (l==1) { delete(listeners[type]); } // allows for faster checks.
- else { arr.splice(i,1); }
- break;
- }
- }
- };
-
- /**
- * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the
- * .on method.
- *
- * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See
- * {{#crossLink "EventDispatcher/on"}}{{/crossLink}} for an example.
- *
- * @method off
- * @param {String} type The string type of the event.
- * @param {Function | Object} listener The listener function or object.
- * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
- **/
- p.off = p.removeEventListener;
-
- /**
- * Removes all listeners for the specified type, or all listeners of all types.
- *
- * <h4>Example</h4>
- *
- * // Remove all listeners
- * displayObject.removeAllEventListeners();
- *
- * // Remove all click listeners
- * displayObject.removeAllEventListeners("click");
- *
- * @method removeAllEventListeners
- * @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed.
- **/
- p.removeAllEventListeners = function(type) {
- if (!type) { this._listeners = this._captureListeners = null; }
- else {
- if (this._listeners) { delete(this._listeners[type]); }
- if (this._captureListeners) { delete(this._captureListeners[type]); }
- }
- };
-
- /**
- * Dispatches the specified event to all listeners.
- *
- * <h4>Example</h4>
- *
- * // Use a string event
- * this.dispatchEvent("complete");
- *
- * // Use an Event instance
- * var event = new createjs.Event("progress");
- * this.dispatchEvent(event);
- *
- * @method dispatchEvent
- * @param {Object | String | Event} eventObj An object with a "type" property, or a string type.
- * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,
- * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can
- * be used to avoid event object instantiation for non-bubbling events that may not have any listeners.
- * @param {Boolean} [bubbles] Specifies the `bubbles` value when a string was passed to eventObj.
- * @param {Boolean} [cancelable] Specifies the `cancelable` value when a string was passed to eventObj.
- * @return {Boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise.
- **/
- p.dispatchEvent = function(eventObj, bubbles, cancelable) {
- if (typeof eventObj == "string") {
- // skip everything if there's no listeners and it doesn't bubble:
- var listeners = this._listeners;
- if (!bubbles && (!listeners || !listeners[eventObj])) { return true; }
- eventObj = new createjs.Event(eventObj, bubbles, cancelable);
- } else if (eventObj.target && eventObj.clone) {
- // redispatching an active event object, so clone it:
- eventObj = eventObj.clone();
- }
-
- // TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent
- try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events
-
- if (!eventObj.bubbles || !this.parent) {
- this._dispatchEvent(eventObj, 2);
- } else {
- var top=this, list=[top];
- while (top.parent) { list.push(top = top.parent); }
- var i, l=list.length;
-
- // capture & atTarget
- for (i=l-1; i>=0 && !eventObj.propagationStopped; i--) {
- list[i]._dispatchEvent(eventObj, 1+(i==0));
- }
- // bubbling
- for (i=1; i<l && !eventObj.propagationStopped; i++) {
- list[i]._dispatchEvent(eventObj, 3);
- }
- }
- return !eventObj.defaultPrevented;
- };
-
- /**
- * Indicates whether there is at least one listener for the specified event type.
- * @method hasEventListener
- * @param {String} type The string type of the event.
- * @return {Boolean} Returns true if there is at least one listener for the specified event.
- **/
- p.hasEventListener = function(type) {
- var listeners = this._listeners, captureListeners = this._captureListeners;
- return !!((listeners && listeners[type]) || (captureListeners && captureListeners[type]));
- };
-
- /**
- * Indicates whether there is at least one listener for the specified event type on this object or any of its
- * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the
- * specified type is dispatched from this object, it will trigger at least one listener.
- *
- * This is similar to {{#crossLink "EventDispatcher/hasEventListener"}}{{/crossLink}}, but it searches the entire
- * event flow for a listener, not just this object.
- * @method willTrigger
- * @param {String} type The string type of the event.
- * @return {Boolean} Returns `true` if there is at least one listener for the specified event.
- **/
- p.willTrigger = function(type) {
- var o = this;
- while (o) {
- if (o.hasEventListener(type)) { return true; }
- o = o.parent;
- }
- return false;
- };
-
- /**
- * @method toString
- * @return {String} a string representation of the instance.
- **/
- p.toString = function() {
- return "[EventDispatcher]";
- };
-
-
- // private methods:
- /**
- * @method _dispatchEvent
- * @param {Object | String | Event} eventObj
- * @param {Object} eventPhase
- * @protected
- **/
- p._dispatchEvent = function(eventObj, eventPhase) {
- var l, listeners = (eventPhase==1) ? this._captureListeners : this._listeners;
- if (eventObj && listeners) {
- var arr = listeners[eventObj.type];
- if (!arr||!(l=arr.length)) { return; }
- try { eventObj.currentTarget = this; } catch (e) {}
- try { eventObj.eventPhase = eventPhase; } catch (e) {}
- eventObj.removed = false;
-
- arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch
- for (var i=0; i<l && !eventObj.immediatePropagationStopped; i++) {
- var o = arr[i];
- if (o.handleEvent) { o.handleEvent(eventObj); }
- else { o(eventObj); }
- if (eventObj.removed) {
- this.off(eventObj.type, o, eventPhase==1);
- eventObj.removed = false;
- }
- }
- }
- };
-
-
- createjs.EventDispatcher = EventDispatcher;
- }());
-
- //##############################################################################
- // Ticker.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- (function() {
- "use strict";
-
-
- // constructor:
- /**
- * The Ticker provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe to the tick
- * event to be notified when a set time interval has elapsed.
- *
- * Note that the interval that the tick event is called is a target interval, and may be broadcast at a slower interval
- * when under high CPU load. The Ticker class uses a static interface (ex. `Ticker.framerate = 30;`) and
- * can not be instantiated.
- *
- * <h4>Example</h4>
- *
- * createjs.Ticker.addEventListener("tick", handleTick);
- * function handleTick(event) {
- * // Actions carried out each tick (aka frame)
- * if (!event.paused) {
- * // Actions carried out when the Ticker is not paused.
- * }
- * }
- *
- * @class Ticker
- * @uses EventDispatcher
- * @static
- **/
- function Ticker() {
- throw "Ticker cannot be instantiated.";
- }
-
-
- // constants:
- /**
- * In this mode, Ticker uses the requestAnimationFrame API, but attempts to synch the ticks to target framerate. It
- * uses a simple heuristic that compares the time of the RAF return to the target time for the current frame and
- * dispatches the tick when the time is within a certain threshold.
- *
- * This mode has a higher variance for time between frames than {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}},
- * but does not require that content be time based as with {{#crossLink "Ticker/RAF:property"}}{{/crossLink}} while
- * gaining the benefits of that API (screen synch, background throttling).
- *
- * Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so
- * framerates of 10, 12, 15, 20, and 30 work well.
- *
- * Falls back to {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not
- * supported.
- * @property RAF_SYNCHED
- * @static
- * @type {String}
- * @default "synched"
- * @readonly
- **/
- Ticker.RAF_SYNCHED = "synched";
-
- /**
- * In this mode, Ticker passes through the requestAnimationFrame heartbeat, ignoring the target framerate completely.
- * Because requestAnimationFrame frequency is not deterministic, any content using this mode should be time based.
- * You can leverage {{#crossLink "Ticker/getTime"}}{{/crossLink}} and the {{#crossLink "Ticker/tick:event"}}{{/crossLink}}
- * event object's "delta" properties to make this easier.
- *
- * Falls back on {{#crossLink "Ticker/TIMEOUT:property"}}{{/crossLink}} if the requestAnimationFrame API is not
- * supported.
- * @property RAF
- * @static
- * @type {String}
- * @default "raf"
- * @readonly
- **/
- Ticker.RAF = "raf";
-
- /**
- * In this mode, Ticker uses the setTimeout API. This provides predictable, adaptive frame timing, but does not
- * provide the benefits of requestAnimationFrame (screen synch, background throttling).
- * @property TIMEOUT
- * @static
- * @type {String}
- * @default "timeout"
- * @readonly
- **/
- Ticker.TIMEOUT = "timeout";
-
-
- // static events:
- /**
- * Dispatched each tick. The event will be dispatched to each listener even when the Ticker has been paused using
- * {{#crossLink "Ticker/setPaused"}}{{/crossLink}}.
- *
- * <h4>Example</h4>
- *
- * createjs.Ticker.addEventListener("tick", handleTick);
- * function handleTick(event) {
- * console.log("Paused:", event.paused, event.delta);
- * }
- *
- * @event tick
- * @param {Object} target The object that dispatched the event.
- * @param {String} type The event type.
- * @param {Boolean} paused Indicates whether the ticker is currently paused.
- * @param {Number} delta The time elapsed in ms since the last tick.
- * @param {Number} time The total time in ms since Ticker was initialized.
- * @param {Number} runTime The total time in ms that Ticker was not paused since it was initialized. For example,
- * you could determine the amount of time that the Ticker has been paused since initialization with `time-runTime`.
- * @since 0.6.0
- */
-
-
- // public static properties:
- /**
- * Deprecated in favour of {{#crossLink "Ticker/timingMode"}}{{/crossLink}}, and will be removed in a future version. If true, timingMode will
- * use {{#crossLink "Ticker/RAF_SYNCHED"}}{{/crossLink}} by default.
- * @deprecated Deprecated in favour of {{#crossLink "Ticker/timingMode"}}{{/crossLink}}.
- * @property useRAF
- * @static
- * @type {Boolean}
- * @default false
- **/
- Ticker.useRAF = false;
-
- /**
- * Specifies the timing api (setTimeout or requestAnimationFrame) and mode to use. See
- * {{#crossLink "Ticker/TIMEOUT"}}{{/crossLink}}, {{#crossLink "Ticker/RAF"}}{{/crossLink}}, and
- * {{#crossLink "Ticker/RAF_SYNCHED"}}{{/crossLink}} for mode details.
- * @property timingMode
- * @static
- * @type {String}
- * @default Ticker.TIMEOUT
- **/
- Ticker.timingMode = null;
-
- /**
- * Specifies a maximum value for the delta property in the tick event object. This is useful when building time
- * based animations and systems to prevent issues caused by large time gaps caused by background tabs, system sleep,
- * alert dialogs, or other blocking routines. Double the expected frame duration is often an effective value
- * (ex. maxDelta=50 when running at 40fps).
- *
- * This does not impact any other values (ex. time, runTime, etc), so you may experience issues if you enable maxDelta
- * when using both delta and other values.
- *
- * If 0, there is no maximum.
- * @property maxDelta
- * @static
- * @type {number}
- * @default 0
- */
- Ticker.maxDelta = 0;
-
- /**
- * When the ticker is paused, all listeners will still receive a tick event, but the <code>paused</code> property
- * of the event will be `true`. Also, while paused the `runTime` will not increase. See {{#crossLink "Ticker/tick:event"}}{{/crossLink}},
- * {{#crossLink "Ticker/getTime"}}{{/crossLink}}, and {{#crossLink "Ticker/getEventTime"}}{{/crossLink}} for more
- * info.
- *
- * <h4>Example</h4>
- *
- * createjs.Ticker.addEventListener("tick", handleTick);
- * createjs.Ticker.paused = true;
- * function handleTick(event) {
- * console.log(event.paused,
- * createjs.Ticker.getTime(false),
- * createjs.Ticker.getTime(true));
- * }
- *
- * @property paused
- * @static
- * @type {Boolean}
- * @default false
- **/
- Ticker.paused = false;
-
-
- // mix-ins:
- // EventDispatcher methods:
- Ticker.removeEventListener = null;
- Ticker.removeAllEventListeners = null;
- Ticker.dispatchEvent = null;
- Ticker.hasEventListener = null;
- Ticker._listeners = null;
- createjs.EventDispatcher.initialize(Ticker); // inject EventDispatcher methods.
- Ticker._addEventListener = Ticker.addEventListener;
- Ticker.addEventListener = function() {
- !Ticker._inited&&Ticker.init();
- return Ticker._addEventListener.apply(Ticker, arguments);
- };
-
-
- // private static properties:
- /**
- * @property _inited
- * @static
- * @type {Boolean}
- * @protected
- **/
- Ticker._inited = false;
-
- /**
- * @property _startTime
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._startTime = 0;
-
- /**
- * @property _pausedTime
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._pausedTime=0;
-
- /**
- * The number of ticks that have passed
- * @property _ticks
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._ticks = 0;
-
- /**
- * The number of ticks that have passed while Ticker has been paused
- * @property _pausedTicks
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._pausedTicks = 0;
-
- /**
- * @property _interval
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._interval = 50;
-
- /**
- * @property _lastTime
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._lastTime = 0;
-
- /**
- * @property _times
- * @static
- * @type {Array}
- * @protected
- **/
- Ticker._times = null;
-
- /**
- * @property _tickTimes
- * @static
- * @type {Array}
- * @protected
- **/
- Ticker._tickTimes = null;
-
- /**
- * Stores the timeout or requestAnimationFrame id.
- * @property _timerId
- * @static
- * @type {Number}
- * @protected
- **/
- Ticker._timerId = null;
-
- /**
- * True if currently using requestAnimationFrame, false if using setTimeout. This may be different than timingMode
- * if that property changed and a tick hasn't fired.
- * @property _raf
- * @static
- * @type {Boolean}
- * @protected
- **/
- Ticker._raf = true;
-
-
- // static getter / setters:
- /**
- * Use the {{#crossLink "Ticker/interval:property"}}{{/crossLink}} property instead.
- * @method setInterval
- * @static
- * @param {Number} interval
- * @deprecated
- **/
- Ticker.setInterval = function(interval) {
- Ticker._interval = interval;
- if (!Ticker._inited) { return; }
- Ticker._setupTick();
- };
-
- /**
- * Use the {{#crossLink "Ticker/interval:property"}}{{/crossLink}} property instead.
- * @method getInterval
- * @static
- * @return {Number}
- * @deprecated
- **/
- Ticker.getInterval = function() {
- return Ticker._interval;
- };
-
- /**
- * Use the {{#crossLink "Ticker/framerate:property"}}{{/crossLink}} property instead.
- * @method setFPS
- * @static
- * @param {Number} value
- * @deprecated
- **/
- Ticker.setFPS = function(value) {
- Ticker.setInterval(1000/value);
- };
-
- /**
- * Use the {{#crossLink "Ticker/framerate:property"}}{{/crossLink}} property instead.
- * @method getFPS
- * @static
- * @return {Number}
- * @deprecated
- **/
- Ticker.getFPS = function() {
- return 1000/Ticker._interval;
- };
-
- /**
- * Indicates the target time (in milliseconds) between ticks. Default is 50 (20 FPS).
- * Note that actual time between ticks may be more than specified depending on CPU load.
- * This property is ignored if the ticker is using the `RAF` timing mode.
- * @property interval
- * @static
- * @type {Number}
- **/
-
- /**
- * Indicates the target frame rate in frames per second (FPS). Effectively just a shortcut to `interval`, where
- * `framerate == 1000/interval`.
- * @property framerate
- * @static
- * @type {Number}
- **/
- try {
- Object.defineProperties(Ticker, {
- interval: { get: Ticker.getInterval, set: Ticker.setInterval },
- framerate: { get: Ticker.getFPS, set: Ticker.setFPS }
- });
- } catch (e) { console.log(e); }
-
-
- // public static methods:
- /**
- * Starts the tick. This is called automatically when the first listener is added.
- * @method init
- * @static
- **/
- Ticker.init = function() {
- if (Ticker._inited) { return; }
- Ticker._inited = true;
- Ticker._times = [];
- Ticker._tickTimes = [];
- Ticker._startTime = Ticker._getTime();
- Ticker._times.push(Ticker._lastTime = 0);
- Ticker.interval = Ticker._interval;
- };
-
- /**
- * Stops the Ticker and removes all listeners. Use init() to restart the Ticker.
- * @method reset
- * @static
- **/
- Ticker.reset = function() {
- if (Ticker._raf) {
- var f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;
- f&&f(Ticker._timerId);
- } else {
- clearTimeout(Ticker._timerId);
- }
- Ticker.removeAllEventListeners("tick");
- Ticker._timerId = Ticker._times = Ticker._tickTimes = null;
- Ticker._startTime = Ticker._lastTime = Ticker._ticks = 0;
- Ticker._inited = false;
- };
-
- /**
- * Returns the average time spent within a tick. This can vary significantly from the value provided by getMeasuredFPS
- * because it only measures the time spent within the tick execution stack.
- *
- * Example 1: With a target FPS of 20, getMeasuredFPS() returns 20fps, which indicates an average of 50ms between
- * the end of one tick and the end of the next. However, getMeasuredTickTime() returns 15ms. This indicates that
- * there may be up to 35ms of "idle" time between the end of one tick and the start of the next.
- *
- * Example 2: With a target FPS of 30, getFPS() returns 10fps, which indicates an average of 100ms between the end of
- * one tick and the end of the next. However, getMeasuredTickTime() returns 20ms. This would indicate that something
- * other than the tick is using ~80ms (another script, DOM rendering, etc).
- * @method getMeasuredTickTime
- * @static
- * @param {Number} [ticks] The number of previous ticks over which to measure the average time spent in a tick.
- * Defaults to the number of ticks per second. To get only the last tick's time, pass in 1.
- * @return {Number} The average time spent in a tick in milliseconds.
- **/
- Ticker.getMeasuredTickTime = function(ticks) {
- var ttl=0, times=Ticker._tickTimes;
- if (!times || times.length < 1) { return -1; }
-
- // by default, calculate average for the past ~1 second:
- ticks = Math.min(times.length, ticks||(Ticker.getFPS()|0));
- for (var i=0; i<ticks; i++) { ttl += times[i]; }
- return ttl/ticks;
- };
-
- /**
- * Returns the actual frames / ticks per second.
- * @method getMeasuredFPS
- * @static
- * @param {Number} [ticks] The number of previous ticks over which to measure the actual frames / ticks per second.
- * Defaults to the number of ticks per second.
- * @return {Number} The actual frames / ticks per second. Depending on performance, this may differ
- * from the target frames per second.
- **/
- Ticker.getMeasuredFPS = function(ticks) {
- var times = Ticker._times;
- if (!times || times.length < 2) { return -1; }
-
- // by default, calculate fps for the past ~1 second:
- ticks = Math.min(times.length-1, ticks||(Ticker.getFPS()|0));
- return 1000/((times[0]-times[ticks])/ticks);
- };
-
- /**
- * Use the {{#crossLink "Ticker/paused:property"}}{{/crossLink}} property instead.
- * @method setPaused
- * @static
- * @param {Boolean} value
- * @deprecated
- **/
- Ticker.setPaused = function(value) {
- // TODO: deprecated.
- Ticker.paused = value;
- };
-
- /**
- * Use the {{#crossLink "Ticker/paused:property"}}{{/crossLink}} property instead.
- * @method getPaused
- * @static
- * @return {Boolean}
- * @deprecated
- **/
- Ticker.getPaused = function() {
- // TODO: deprecated.
- return Ticker.paused;
- };
-
- /**
- * Returns the number of milliseconds that have elapsed since Ticker was initialized via {{#crossLink "Ticker/init"}}.
- * Returns -1 if Ticker has not been initialized. For example, you could use
- * this in a time synchronized animation to determine the exact amount of time that has elapsed.
- * @method getTime
- * @static
- * @param {Boolean} [runTime=false] If true only time elapsed while Ticker was not paused will be returned.
- * If false, the value returned will be total time elapsed since the first tick event listener was added.
- * @return {Number} Number of milliseconds that have elapsed since Ticker was initialized or -1.
- **/
- Ticker.getTime = function(runTime) {
- return Ticker._startTime ? Ticker._getTime() - (runTime ? Ticker._pausedTime : 0) : -1;
- };
-
- /**
- * Similar to the {{#crossLink "Ticker/getTime"}}{{/crossLink}} method, but returns the time on the most recent {{#crossLink "Ticker/tick:event"}}{{/crossLink}}
- * event object.
- * @method getEventTime
- * @static
- * @param runTime {Boolean} [runTime=false] If true, the runTime property will be returned instead of time.
- * @returns {number} The time or runTime property from the most recent tick event or -1.
- */
- Ticker.getEventTime = function(runTime) {
- return Ticker._startTime ? (Ticker._lastTime || Ticker._startTime) - (runTime ? Ticker._pausedTime : 0) : -1;
- };
-
- /**
- * Returns the number of ticks that have been broadcast by Ticker.
- * @method getTicks
- * @static
- * @param {Boolean} pauseable Indicates whether to include ticks that would have been broadcast
- * while Ticker was paused. If true only tick events broadcast while Ticker is not paused will be returned.
- * If false, tick events that would have been broadcast while Ticker was paused will be included in the return
- * value. The default value is false.
- * @return {Number} of ticks that have been broadcast.
- **/
- Ticker.getTicks = function(pauseable) {
- return Ticker._ticks - (pauseable ? Ticker._pausedTicks : 0);
- };
-
-
- // private static methods:
- /**
- * @method _handleSynch
- * @static
- * @protected
- **/
- Ticker._handleSynch = function() {
- Ticker._timerId = null;
- Ticker._setupTick();
-
- // run if enough time has elapsed, with a little bit of flexibility to be early:
- if (Ticker._getTime() - Ticker._lastTime >= (Ticker._interval-1)*0.97) {
- Ticker._tick();
- }
- };
-
- /**
- * @method _handleRAF
- * @static
- * @protected
- **/
- Ticker._handleRAF = function() {
- Ticker._timerId = null;
- Ticker._setupTick();
- Ticker._tick();
- };
-
- /**
- * @method _handleTimeout
- * @static
- * @protected
- **/
- Ticker._handleTimeout = function() {
- Ticker._timerId = null;
- Ticker._setupTick();
- Ticker._tick();
- };
-
- /**
- * @method _setupTick
- * @static
- * @protected
- **/
- Ticker._setupTick = function() {
- if (Ticker._timerId != null) { return; } // avoid duplicates
-
- var mode = Ticker.timingMode||(Ticker.useRAF&&Ticker.RAF_SYNCHED);
- if (mode == Ticker.RAF_SYNCHED || mode == Ticker.RAF) {
- var f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;
- if (f) {
- Ticker._timerId = f(mode == Ticker.RAF ? Ticker._handleRAF : Ticker._handleSynch);
- Ticker._raf = true;
- return;
- }
- }
- Ticker._raf = false;
- Ticker._timerId = setTimeout(Ticker._handleTimeout, Ticker._interval);
- };
-
- /**
- * @method _tick
- * @static
- * @protected
- **/
- Ticker._tick = function() {
- var paused = Ticker.paused;
- var time = Ticker._getTime();
- var elapsedTime = time-Ticker._lastTime;
- Ticker._lastTime = time;
- Ticker._ticks++;
-
- if (paused) {
- Ticker._pausedTicks++;
- Ticker._pausedTime += elapsedTime;
- }
-
- if (Ticker.hasEventListener("tick")) {
- var event = new createjs.Event("tick");
- var maxDelta = Ticker.maxDelta;
- event.delta = (maxDelta && elapsedTime > maxDelta) ? maxDelta : elapsedTime;
- event.paused = paused;
- event.time = time;
- event.runTime = time-Ticker._pausedTime;
- Ticker.dispatchEvent(event);
- }
-
- Ticker._tickTimes.unshift(Ticker._getTime()-time);
- while (Ticker._tickTimes.length > 100) { Ticker._tickTimes.pop(); }
-
- Ticker._times.unshift(time);
- while (Ticker._times.length > 100) { Ticker._times.pop(); }
- };
-
- /**
- * @method _getTime
- * @static
- * @protected
- **/
- var now = window.performance && (performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow);
- Ticker._getTime = function() {
- return ((now&&now.call(performance))||(new Date().getTime())) - Ticker._startTime;
- };
-
-
- createjs.Ticker = Ticker;
- }());
-
- //##############################################################################
- // Tween.js
- //##############################################################################
-
- // TODO: possibly add a END actionsMode (only runs actions that == position)?
- // TODO: evaluate a way to decouple paused from tick registration.
-
-
- this.createjs = this.createjs||{};
-
- (function() {
- "use strict";
-
-
- // constructor
- /**
- * A Tween instance tweens properties for a single target. Instance methods can be chained for easy construction and sequencing:
- *
- * <h4>Example</h4>
- *
- * target.alpha = 1;
- * createjs.Tween.get(target)
- * .wait(500)
- * .to({alpha:0, visible:false}, 1000)
- * .call(handleComplete);
- * function handleComplete() {
- * //Tween complete
- * }
- *
- * Multiple tweens can point to the same instance, however if they affect the same properties there could be unexpected
- * behaviour. To stop all tweens on an object, use {{#crossLink "Tween/removeTweens"}}{{/crossLink}} or pass `override:true`
- * in the props argument.
- *
- * createjs.Tween.get(target, {override:true}).to({x:100});
- *
- * Subscribe to the {{#crossLink "Tween/change:event"}}{{/crossLink}} event to get notified when a property of the
- * target is changed.
- *
- * createjs.Tween.get(target, {override:true}).to({x:100}).addEventListener("change", handleChange);
- * function handleChange(event) {
- * // The tween changed.
- * }
- *
- * See the Tween {{#crossLink "Tween/get"}}{{/crossLink}} method for additional param documentation.
- * @class Tween
- * @param {Object} target The target object that will have its properties tweened.
- * @param {Object} [props] The configuration properties to apply to this tween instance (ex. `{loop:true, paused:true}`.
- * All properties default to false. Supported props are:<UL>
- * <LI> loop: sets the loop property on this tween.</LI>
- * <LI> useTicks: uses ticks for all durations instead of milliseconds.</LI>
- * <LI> ignoreGlobalPause: sets the {{#crossLink "Tween/ignoreGlobalPause:property"}}{{/crossLink}} property on this tween.</LI>
- * <LI> override: if true, `Tween.removeTweens(target)` will be called to remove any other tweens with the same target.
- * <LI> paused: indicates whether to start the tween paused.</LI>
- * <LI> position: indicates the initial position for this tween.</LI>
- * <LI> onChange: specifies a listener for the "change" event.</LI>
- * </UL>
- * @param {Object} [pluginData] An object containing data for use by installed plugins. See individual
- * plugins' documentation for details.
- * @extends EventDispatcher
- * @constructor
- */
- function Tween(target, props, pluginData) {
-
- // public properties:
- /**
- * Causes this tween to continue playing when a global pause is active. For example, if TweenJS is using {{#crossLink "Ticker"}}{{/crossLink}},
- * then setting this to true (the default) will cause this tween to be paused when <code>Ticker.setPaused(true)</code>
- * is called. See the Tween {{#crossLink "Tween/tick"}}{{/crossLink}} method for more info. Can be set via the props
- * parameter.
- * @property ignoreGlobalPause
- * @type Boolean
- * @default false
- */
- this.ignoreGlobalPause = false;
-
- /**
- * If true, the tween will loop when it reaches the end. Can be set via the props param.
- * @property loop
- * @type {Boolean}
- * @default false
- */
- this.loop = false;
-
- /**
- * Specifies the total duration of this tween in milliseconds (or ticks if useTicks is true).
- * This value is automatically updated as you modify the tween. Changing it directly could result in unexpected
- * behaviour.
- * @property duration
- * @type {Number}
- * @default 0
- * @readonly
- */
- this.duration = 0;
-
- /**
- * Allows you to specify data that will be used by installed plugins. Each plugin uses this differently, but in general
- * you specify data by setting it to a property of pluginData with the same name as the plugin class.
- * @example
- * myTween.pluginData.PluginClassName = data;
- * <br/>
- * Also, most plugins support a property to enable or disable them. This is typically the plugin class name followed by "_enabled".<br/>
- * @example
- * myTween.pluginData.PluginClassName_enabled = false;<br/>
- * <br/>
- * Some plugins also store instance data in this object, usually in a property named _PluginClassName.
- * See the documentation for individual plugins for more details.
- * @property pluginData
- * @type {Object}
- */
- this.pluginData = pluginData || {};
-
- /**
- * The target of this tween. This is the object on which the tweened properties will be changed. Changing
- * this property after the tween is created will not have any effect.
- * @property target
- * @type {Object}
- * @readonly
- */
- this.target = target;
-
- /**
- * The current normalized position of the tween. This will always be a value between 0 and duration.
- * Changing this property directly will have no effect.
- * @property position
- * @type {Object}
- * @readonly
- */
- this.position = null;
-
- /**
- * Indicates the tween's current position is within a passive wait.
- * @property passive
- * @type {Boolean}
- * @default false
- * @readonly
- **/
- this.passive = false;
-
- // private properties:
- /**
- * @property _paused
- * @type {Boolean}
- * @default false
- * @protected
- */
- this._paused = false;
-
- /**
- * @property _curQueueProps
- * @type {Object}
- * @protected
- */
- this._curQueueProps = {};
-
- /**
- * @property _initQueueProps
- * @type {Object}
- * @protected
- */
- this._initQueueProps = {};
-
- /**
- * @property _steps
- * @type {Array}
- * @protected
- */
- this._steps = [];
-
- /**
- * @property _actions
- * @type {Array}
- * @protected
- */
- this._actions = [];
-
- /**
- * Raw position.
- * @property _prevPosition
- * @type {Number}
- * @default 0
- * @protected
- */
- this._prevPosition = 0;
-
- /**
- * The position within the current step.
- * @property _stepPosition
- * @type {Number}
- * @default 0
- * @protected
- */
- this._stepPosition = 0; // this is needed by MovieClip.
-
- /**
- * Normalized position.
- * @property _prevPos
- * @type {Number}
- * @default -1
- * @protected
- */
- this._prevPos = -1;
-
- /**
- * @property _target
- * @type {Object}
- * @protected
- */
- this._target = target;
-
- /**
- * @property _useTicks
- * @type {Boolean}
- * @default false
- * @protected
- */
- this._useTicks = false;
-
- /**
- * @property _inited
- * @type {boolean}
- * @default false
- * @protected
- */
- this._inited = false;
-
- /**
- * Indicates whether the tween is currently registered with Tween.
- * @property _registered
- * @type {boolean}
- * @default false
- * @protected
- */
- this._registered = false;
-
-
- if (props) {
- this._useTicks = props.useTicks;
- this.ignoreGlobalPause = props.ignoreGlobalPause;
- this.loop = props.loop;
- props.onChange && this.addEventListener("change", props.onChange);
- if (props.override) { Tween.removeTweens(target); }
- }
- if (props&&props.paused) { this._paused=true; }
- else { createjs.Tween._register(this,true); }
- if (props&&props.position!=null) { this.setPosition(props.position, Tween.NONE); }
-
- };
-
- var p = createjs.extend(Tween, createjs.EventDispatcher);
-
- // TODO: deprecated
- // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
-
-
- // static properties
- /**
- * Constant defining the none actionsMode for use with setPosition.
- * @property NONE
- * @type Number
- * @default 0
- * @static
- */
- Tween.NONE = 0;
-
- /**
- * Constant defining the loop actionsMode for use with setPosition.
- * @property LOOP
- * @type Number
- * @default 1
- * @static
- */
- Tween.LOOP = 1;
-
- /**
- * Constant defining the reverse actionsMode for use with setPosition.
- * @property REVERSE
- * @type Number
- * @default 2
- * @static
- */
- Tween.REVERSE = 2;
-
- /**
- * Constant returned by plugins to tell the tween not to use default assignment.
- * @property IGNORE
- * @type Object
- * @static
- */
- Tween.IGNORE = {};
-
- /**
- * @property _listeners
- * @type Array[Tween]
- * @static
- * @protected
- */
- Tween._tweens = [];
-
- /**
- * @property _plugins
- * @type Object
- * @static
- * @protected
- */
- Tween._plugins = {};
-
-
- // static methods
- /**
- * Returns a new tween instance. This is functionally identical to using "new Tween(...)", but looks cleaner
- * with the chained syntax of TweenJS.
- * <h4>Example</h4>
- *
- * var tween = createjs.Tween.get(target);
- *
- * @method get
- * @param {Object} target The target object that will have its properties tweened.
- * @param {Object} [props] The configuration properties to apply to this tween instance (ex. `{loop:true, paused:true}`).
- * All properties default to `false`. Supported props are:
- * <UL>
- * <LI> loop: sets the loop property on this tween.</LI>
- * <LI> useTicks: uses ticks for all durations instead of milliseconds.</LI>
- * <LI> ignoreGlobalPause: sets the {{#crossLink "Tween/ignoreGlobalPause:property"}}{{/crossLink}} property on
- * this tween.</LI>
- * <LI> override: if true, `createjs.Tween.removeTweens(target)` will be called to remove any other tweens with
- * the same target.
- * <LI> paused: indicates whether to start the tween paused.</LI>
- * <LI> position: indicates the initial position for this tween.</LI>
- * <LI> onChange: specifies a listener for the {{#crossLink "Tween/change:event"}}{{/crossLink}} event.</LI>
- * </UL>
- * @param {Object} [pluginData] An object containing data for use by installed plugins. See individual plugins'
- * documentation for details.
- * @param {Boolean} [override=false] If true, any previous tweens on the same target will be removed. This is the
- * same as calling `Tween.removeTweens(target)`.
- * @return {Tween} A reference to the created tween. Additional chained tweens, method calls, or callbacks can be
- * applied to the returned tween instance.
- * @static
- */
- Tween.get = function(target, props, pluginData, override) {
- if (override) { Tween.removeTweens(target); }
- return new Tween(target, props, pluginData);
- };
-
- /**
- * Advances all tweens. This typically uses the {{#crossLink "Ticker"}}{{/crossLink}} class, but you can call it
- * manually if you prefer to use your own "heartbeat" implementation.
- * @method tick
- * @param {Number} delta The change in time in milliseconds since the last tick. Required unless all tweens have
- * `useTicks` set to true.
- * @param {Boolean} paused Indicates whether a global pause is in effect. Tweens with {{#crossLink "Tween/ignoreGlobalPause:property"}}{{/crossLink}}
- * will ignore this, but all others will pause if this is `true`.
- * @static
- */
- Tween.tick = function(delta, paused) {
- var tweens = Tween._tweens.slice(); // to avoid race conditions.
- for (var i=tweens.length-1; i>=0; i--) {
- var tween = tweens[i];
- if ((paused && !tween.ignoreGlobalPause) || tween._paused) { continue; }
- tween.tick(tween._useTicks?1:delta);
- }
- };
-
- /**
- * Handle events that result from Tween being used as an event handler. This is included to allow Tween to handle
- * {{#crossLink "Ticker/tick:event"}}{{/crossLink}} events from the createjs {{#crossLink "Ticker"}}{{/crossLink}}.
- * No other events are handled in Tween.
- * @method handleEvent
- * @param {Object} event An event object passed in by the {{#crossLink "EventDispatcher"}}{{/crossLink}}. Will
- * usually be of type "tick".
- * @private
- * @static
- * @since 0.4.2
- */
- Tween.handleEvent = function(event) {
- if (event.type == "tick") {
- this.tick(event.delta, event.paused);
- }
- };
-
- /**
- * Removes all existing tweens for a target. This is called automatically by new tweens if the `override`
- * property is `true`.
- * @method removeTweens
- * @param {Object} target The target object to remove existing tweens from.
- * @static
- */
- Tween.removeTweens = function(target) {
- if (!target.tweenjs_count) { return; }
- var tweens = Tween._tweens;
- for (var i=tweens.length-1; i>=0; i--) {
- var tween = tweens[i];
- if (tween._target == target) {
- tween._paused = true;
- tweens.splice(i, 1);
- }
- }
- target.tweenjs_count = 0;
- };
-
- /**
- * Stop and remove all existing tweens.
- * @method removeAllTweens
- * @static
- * @since 0.4.1
- */
- Tween.removeAllTweens = function() {
- var tweens = Tween._tweens;
- for (var i= 0, l=tweens.length; i<l; i++) {
- var tween = tweens[i];
- tween._paused = true;
- tween.target&&(tween.target.tweenjs_count = 0);
- }
- tweens.length = 0;
- };
-
- /**
- * Indicates whether there are any active tweens (and how many) on the target object (if specified) or in general.
- * @method hasActiveTweens
- * @param {Object} [target] The target to check for active tweens. If not specified, the return value will indicate
- * if there are any active tweens on any target.
- * @return {Boolean} If there are active tweens.
- * @static
- */
- Tween.hasActiveTweens = function(target) {
- if (target) { return target.tweenjs_count != null && !!target.tweenjs_count; }
- return Tween._tweens && !!Tween._tweens.length;
- };
-
- /**
- * Installs a plugin, which can modify how certain properties are handled when tweened. See the {{#crossLink "CSSPlugin"}}{{/crossLink}}
- * for an example of how to write TweenJS plugins.
- * @method installPlugin
- * @static
- * @param {Object} plugin The plugin class to install
- * @param {Array} properties An array of properties that the plugin will handle.
- */
- Tween.installPlugin = function(plugin, properties) {
- var priority = plugin.priority;
- if (priority == null) { plugin.priority = priority = 0; }
- for (var i=0,l=properties.length,p=Tween._plugins;i<l;i++) {
- var n = properties[i];
- if (!p[n]) { p[n] = [plugin]; }
- else {
- var arr = p[n];
- for (var j=0,jl=arr.length;j<jl;j++) {
- if (priority < arr[j].priority) { break; }
- }
- p[n].splice(j,0,plugin);
- }
- }
- };
-
- /**
- * Registers or unregisters a tween with the ticking system.
- * @method _register
- * @param {Tween} tween The tween instance to register or unregister.
- * @param {Boolean} value If `true`, the tween is registered. If `false` the tween is unregistered.
- * @static
- * @protected
- */
- Tween._register = function(tween, value) {
- var target = tween._target;
- var tweens = Tween._tweens;
- if (value && !tween._registered) {
- // TODO: this approach might fail if a dev is using sealed objects in ES5
- if (target) { target.tweenjs_count = target.tweenjs_count ? target.tweenjs_count+1 : 1; }
- tweens.push(tween);
- if (!Tween._inited && createjs.Ticker) { createjs.Ticker.addEventListener("tick", Tween); Tween._inited = true; }
- } else if (!value && tween._registered) {
- if (target) { target.tweenjs_count--; }
- var i = tweens.length;
- while (i--) {
- if (tweens[i] == tween) {
- tweens.splice(i, 1);
- break;
- }
- }
- }
- tween._registered = value;
- };
-
-
- // events:
- /**
- * Called whenever the tween's position changes.
- * @event change
- * @since 0.4.0
- **/
-
-
- // public methods:
- /**
- * Queues a wait (essentially an empty tween).
- * <h4>Example</h4>
- *
- * //This tween will wait 1s before alpha is faded to 0.
- * createjs.Tween.get(target).wait(1000).to({alpha:0}, 1000);
- *
- * @method wait
- * @param {Number} duration The duration of the wait in milliseconds (or in ticks if `useTicks` is true).
- * @param {Boolean} [passive] Tween properties will not be updated during a passive wait. This
- * is mostly useful for use with {{#crossLink "Timeline"}}{{/crossLink}} instances that contain multiple tweens
- * affecting the same target at different times.
- * @return {Tween} This tween instance (for chaining calls).
- **/
- p.wait = function(duration, passive) {
- if (duration == null || duration <= 0) { return this; }
- var o = this._cloneProps(this._curQueueProps);
- return this._addStep({d:duration, p0:o, e:this._linearEase, p1:o, v:passive});
- };
-
- /**
- * Queues a tween from the current values to the target properties. Set duration to 0 to jump to these value.
- * Numeric properties will be tweened from their current value in the tween to the target value. Non-numeric
- * properties will be set at the end of the specified duration.
- * <h4>Example</h4>
- *
- * createjs.Tween.get(target).to({alpha:0}, 1000);
- *
- * @method to
- * @param {Object} props An object specifying property target values for this tween (Ex. `{x:300}` would tween the x
- * property of the target to 300).
- * @param {Number} [duration=0] The duration of the wait in milliseconds (or in ticks if `useTicks` is true).
- * @param {Function} [ease="linear"] The easing function to use for this tween. See the {{#crossLink "Ease"}}{{/crossLink}}
- * class for a list of built-in ease functions.
- * @return {Tween} This tween instance (for chaining calls).
- */
- p.to = function(props, duration, ease) {
- if (isNaN(duration) || duration < 0) { duration = 0; }
- return this._addStep({d:duration||0, p0:this._cloneProps(this._curQueueProps), e:ease, p1:this._cloneProps(this._appendQueueProps(props))});
- };
-
- /**
- * Queues an action to call the specified function.
- * <h4>Example</h4>
- *
- * //would call myFunction() after 1 second.
- * myTween.wait(1000).call(myFunction);
- *
- * @method call
- * @param {Function} callback The function to call.
- * @param {Array} [params]. The parameters to call the function with. If this is omitted, then the function
- * will be called with a single param pointing to this tween.
- * @param {Object} [scope]. The scope to call the function in. If omitted, it will be called in the target's
- * scope.
- * @return {Tween} This tween instance (for chaining calls).
- */
- p.call = function(callback, params, scope) {
- return this._addAction({f:callback, p:params ? params : [this], o:scope ? scope : this._target});
- };
-
- // TODO: add clarification between this and a 0 duration .to:
- /**
- * Queues an action to set the specified props on the specified target. If target is null, it will use this tween's
- * target.
- * <h4>Example</h4>
- *
- * myTween.wait(1000).set({visible:false},foo);
- *
- * @method set
- * @param {Object} props The properties to set (ex. `{visible:false}`).
- * @param {Object} [target] The target to set the properties on. If omitted, they will be set on the tween's target.
- * @return {Tween} This tween instance (for chaining calls).
- */
- p.set = function(props, target) {
- return this._addAction({f:this._set, o:this, p:[props, target ? target : this._target]});
- };
-
- /**
- * Queues an action to play (unpause) the specified tween. This enables you to sequence multiple tweens.
- * <h4>Example</h4>
- *
- * myTween.to({x:100},500).play(otherTween);
- *
- * @method play
- * @param {Tween} tween The tween to play.
- * @return {Tween} This tween instance (for chaining calls).
- */
- p.play = function(tween) {
- if (!tween) { tween = this; }
- return this.call(tween.setPaused, [false], tween);
- };
-
- /**
- * Queues an action to pause the specified tween.
- * @method pause
- * @param {Tween} tween The tween to pause. If null, it pauses this tween.
- * @return {Tween} This tween instance (for chaining calls)
- */
- p.pause = function(tween) {
- if (!tween) { tween = this; }
- return this.call(tween.setPaused, [true], tween);
- };
-
- /**
- * Advances the tween to a specified position.
- * @method setPosition
- * @param {Number} value The position to seek to in milliseconds (or ticks if useTicks is true).
- * @param {Number} [actionsMode=1] Specifies how actions are handled (ie. call, set, play, pause):
- * <ul>
- * <li>{{#crossLink "Tween/NONE:property"}}{{/crossLink}} (0) - run no actions.</li>
- * <li>{{#crossLink "Tween/LOOP:property"}}{{/crossLink}} (1) - if new position is less than old, then run all
- * actions between old and duration, then all actions between 0 and new.</li>
- * <li>{{#crossLink "Tween/REVERSE:property"}}{{/crossLink}} (2) - if new position is less than old, run all
- * actions between them in reverse.</li>
- * </ul>
- * @return {Boolean} Returns `true` if the tween is complete (ie. the full tween has run & {{#crossLink "Tween/loop:property"}}{{/crossLink}}
- * is `false`).
- */
- p.setPosition = function(value, actionsMode) {
- if (value < 0) { value = 0; }
- if (actionsMode == null) { actionsMode = 1; }
-
- // normalize position:
- var t = value;
- var end = false;
- if (t >= this.duration) {
- if (this.loop) { t = t%this.duration; }
- else {
- t = this.duration;
- end = true;
- }
- }
- if (t == this._prevPos) { return end; }
-
-
- var prevPos = this._prevPos;
- this.position = this._prevPos = t; // set this in advance in case an action modifies position.
- this._prevPosition = value;
-
- // handle tweens:
- if (this._target) {
- if (end) {
- // addresses problems with an ending zero length step.
- this._updateTargetProps(null,1);
- } else if (this._steps.length > 0) {
- // find our new tween index:
- for (var i=0, l=this._steps.length; i<l; i++) {
- if (this._steps[i].t > t) { break; }
- }
- var step = this._steps[i-1];
- this._updateTargetProps(step,(this._stepPosition = t-step.t)/step.d);
- }
- }
-
- // run actions:
- if (actionsMode != 0 && this._actions.length > 0) {
- if (this._useTicks) {
- // only run the actions we landed on.
- this._runActions(t,t);
- } else if (actionsMode == 1 && t<prevPos) {
- if (prevPos != this.duration) { this._runActions(prevPos, this.duration); }
- this._runActions(0, t, true);
- } else {
- this._runActions(prevPos, t);
- }
- }
-
- if (end) { this.setPaused(true); }
-
- this.dispatchEvent("change");
- return end;
- };
-
- /**
- * Advances this tween by the specified amount of time in milliseconds (or ticks if`useTicks` is `true`).
- * This is normally called automatically by the Tween engine (via {{#crossLink "Tween/tick"}}{{/crossLink}}), but is
- * exposed for advanced uses.
- * @method tick
- * @param {Number} delta The time to advance in milliseconds (or ticks if `useTicks` is `true`).
- */
- p.tick = function(delta) {
- if (this._paused) { return; }
- this.setPosition(this._prevPosition+delta);
- };
-
- /**
- * Pauses or plays this tween.
- * @method setPaused
- * @param {Boolean} [value=true] Indicates whether the tween should be paused (`true`) or played (`false`).
- * @return {Tween} This tween instance (for chaining calls)
- */
- p.setPaused = function(value) {
- if (this._paused === !!value) { return this; }
- this._paused = !!value;
- Tween._register(this, !value);
- return this;
- };
-
- // tiny api (primarily for tool output):
- p.w = p.wait;
- p.t = p.to;
- p.c = p.call;
- p.s = p.set;
-
- /**
- * Returns a string representation of this object.
- * @method toString
- * @return {String} a string representation of the instance.
- */
- p.toString = function() {
- return "[Tween]";
- };
-
- /**
- * @method clone
- * @protected
- */
- p.clone = function() {
- throw("Tween can not be cloned.")
- };
-
- // private methods:
- /**
- * @method _updateTargetProps
- * @param {Object} step
- * @param {Number} ratio
- * @protected
- */
- p._updateTargetProps = function(step, ratio) {
- var p0,p1,v,v0,v1,arr;
- if (!step && ratio == 1) {
- // GDS: when does this run? Just at the very end? Shouldn't.
- this.passive = false;
- p0 = p1 = this._curQueueProps;
- } else {
- this.passive = !!step.v;
- if (this.passive) { return; } // don't update props.
- // apply ease to ratio.
- if (step.e) { ratio = step.e(ratio,0,1,1); }
- p0 = step.p0;
- p1 = step.p1;
- }
-
- for (var n in this._initQueueProps) {
- if ((v0 = p0[n]) == null) { p0[n] = v0 = this._initQueueProps[n]; }
- if ((v1 = p1[n]) == null) { p1[n] = v1 = v0; }
- if (v0 == v1 || ratio == 0 || ratio == 1 || (typeof(v0) != "number")) {
- // no interpolation - either at start, end, values don't change, or the value is non-numeric.
- v = ratio == 1 ? v1 : v0;
- } else {
- v = v0+(v1-v0)*ratio;
- }
-
- var ignore = false;
- if (arr = Tween._plugins[n]) {
- for (var i=0,l=arr.length;i<l;i++) {
- var v2 = arr[i].tween(this, n, v, p0, p1, ratio, !!step&&p0==p1, !step);
- if (v2 == Tween.IGNORE) { ignore = true; }
- else { v = v2; }
- }
- }
- if (!ignore) { this._target[n] = v; }
- }
-
- };
-
- /**
- * @method _runActions
- * @param {Number} startPos
- * @param {Number} endPos
- * @param {Boolean} includeStart
- * @protected
- */
- p._runActions = function(startPos, endPos, includeStart) {
- var sPos = startPos;
- var ePos = endPos;
- var i = -1;
- var j = this._actions.length;
- var k = 1;
- if (startPos > endPos) {
- // running backwards, flip everything:
- sPos = endPos;
- ePos = startPos;
- i = j;
- j = k = -1;
- }
- while ((i+=k) != j) {
- var action = this._actions[i];
- var pos = action.t;
- if (pos == ePos || (pos > sPos && pos < ePos) || (includeStart && pos == startPos) ) {
- action.f.apply(action.o, action.p);
- }
- }
- };
-
- /**
- * @method _appendQueueProps
- * @param {Object} o
- * @protected
- */
- p._appendQueueProps = function(o) {
- var arr,oldValue,i, l, injectProps;
- for (var n in o) {
- if (this._initQueueProps[n] === undefined) {
- oldValue = this._target[n];
-
- // init plugins:
- if (arr = Tween._plugins[n]) {
- for (i=0,l=arr.length;i<l;i++) {
- oldValue = arr[i].init(this, n, oldValue);
- }
- }
- this._initQueueProps[n] = this._curQueueProps[n] = (oldValue===undefined) ? null : oldValue;
- } else {
- oldValue = this._curQueueProps[n];
- }
- }
-
- for (var n in o) {
- oldValue = this._curQueueProps[n];
- if (arr = Tween._plugins[n]) {
- injectProps = injectProps||{};
- for (i=0, l=arr.length;i<l;i++) {
- // TODO: remove the check for .step in the next version. It's here for backwards compatibility.
- if (arr[i].step) { arr[i].step(this, n, oldValue, o[n], injectProps); }
- }
- }
- this._curQueueProps[n] = o[n];
- }
- if (injectProps) { this._appendQueueProps(injectProps); }
- return this._curQueueProps;
- };
-
- /**
- * @method _cloneProps
- * @param {Object} props
- * @protected
- */
- p._cloneProps = function(props) {
- var o = {};
- for (var n in props) {
- o[n] = props[n];
- }
- return o;
- };
-
- /**
- * @method _addStep
- * @param {Object} o
- * @protected
- */
- p._addStep = function(o) {
- if (o.d > 0) {
- this._steps.push(o);
- o.t = this.duration;
- this.duration += o.d;
- }
- return this;
- };
-
- /**
- * @method _addAction
- * @param {Object} o
- * @protected
- */
- p._addAction = function(o) {
- o.t = this.duration;
- this._actions.push(o);
- return this;
- };
-
- /**
- * @method _set
- * @param {Object} props
- * @param {Object} o
- * @protected
- */
- p._set = function(props, o) {
- for (var n in props) {
- o[n] = props[n];
- }
- };
-
- createjs.Tween = createjs.promote(Tween, "EventDispatcher");
-
- }());
-
- //##############################################################################
- // Timeline.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
-
- (function() {
- "use strict";
-
-
- // constructor
- /**
- * The Timeline class synchronizes multiple tweens and allows them to be controlled as a group. Please note that if a
- * timeline is looping, the tweens on it may appear to loop even if the "loop" property of the tween is false.
- * @class Timeline
- * @param {Array} tweens An array of Tweens to add to this timeline. See {{#crossLink "Timeline/addTween"}}{{/crossLink}}
- * for more info.
- * @param {Object} labels An object defining labels for using {{#crossLink "Timeline/gotoAndPlay"}}{{/crossLink}}/{{#crossLink "Timeline/gotoAndStop"}}{{/crossLink}}.
- * See {{#crossLink "Timeline/setLabels"}}{{/crossLink}}
- * for details.
- * @param {Object} props The configuration properties to apply to this tween instance (ex. `{loop:true}`). All properties
- * default to false. Supported props are:<UL>
- * <LI> loop: sets the loop property on this tween.</LI>
- * <LI> useTicks: uses ticks for all durations instead of milliseconds.</LI>
- * <LI> ignoreGlobalPause: sets the ignoreGlobalPause property on this tween.</LI>
- * <LI> paused: indicates whether to start the tween paused.</LI>
- * <LI> position: indicates the initial position for this timeline.</LI>
- * <LI> onChange: specifies a listener to add for the {{#crossLink "Timeline/change:event"}}{{/crossLink}} event.</LI>
- * </UL>
- * @extends EventDispatcher
- * @constructor
- **/
- function Timeline(tweens, labels, props) {
- this.EventDispatcher_constructor();
-
- // public properties:
- /**
- * Causes this timeline to continue playing when a global pause is active.
- * @property ignoreGlobalPause
- * @type Boolean
- **/
- this.ignoreGlobalPause = false;
-
- /**
- * The total duration of this timeline in milliseconds (or ticks if `useTicks `is `true`). This value is usually
- * automatically updated as you modify the timeline. See {{#crossLink "Timeline/updateDuration"}}{{/crossLink}}
- * for more information.
- * @property duration
- * @type Number
- * @default 0
- * @readonly
- **/
- this.duration = 0;
-
- /**
- * If true, the timeline will loop when it reaches the end. Can be set via the props param.
- * @property loop
- * @type Boolean
- **/
- this.loop = false;
-
- /**
- * The current normalized position of the timeline. This will always be a value between 0 and
- * {{#crossLink "Timeline/duration:property"}}{{/crossLink}}.
- * Changing this property directly will have no effect.
- * @property position
- * @type Object
- * @readonly
- **/
- this.position = null;
-
- // private properties:
- /**
- * @property _paused
- * @type Boolean
- * @protected
- **/
- this._paused = false;
-
- /**
- * @property _tweens
- * @type Array[Tween]
- * @protected
- **/
- this._tweens = [];
-
- /**
- * @property _labels
- * @type Object
- * @protected
- **/
- this._labels = null;
-
- /**
- * @property _labelList
- * @type Array[Object]
- * @protected
- **/
- this._labelList = null;
-
- /**
- * @property _prevPosition
- * @type Number
- * @default 0
- * @protected
- **/
- this._prevPosition = 0;
-
- /**
- * @property _prevPos
- * @type Number
- * @default -1
- * @protected
- **/
- this._prevPos = -1;
-
- /**
- * @property _useTicks
- * @type Boolean
- * @default false
- * @protected
- **/
- this._useTicks = false;
-
- /**
- * Indicates whether the timeline is currently registered with Tween.
- * @property _registered
- * @type {boolean}
- * @default false
- * @protected
- */
- this._registered = false;
-
-
- if (props) {
- this._useTicks = props.useTicks;
- this.loop = props.loop;
- this.ignoreGlobalPause = props.ignoreGlobalPause;
- props.onChange&&this.addEventListener("change", props.onChange);
- }
- if (tweens) { this.addTween.apply(this, tweens); }
- this.setLabels(labels);
- if (props&&props.paused) { this._paused=true; }
- else { createjs.Tween._register(this,true); }
- if (props&&props.position!=null) { this.setPosition(props.position, createjs.Tween.NONE); }
-
- };
-
- var p = createjs.extend(Timeline, createjs.EventDispatcher);
-
- // TODO: deprecated
- // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
-
-
- // events:
- /**
- * Called whenever the timeline's position changes.
- * @event change
- * @since 0.5.0
- **/
-
-
- // public methods:
- /**
- * Adds one or more tweens (or timelines) to this timeline. The tweens will be paused (to remove them from the
- * normal ticking system) and managed by this timeline. Adding a tween to multiple timelines will result in
- * unexpected behaviour.
- * @method addTween
- * @param {Tween} ...tween The tween(s) to add. Accepts multiple arguments.
- * @return {Tween} The first tween that was passed in.
- **/
- p.addTween = function(tween) {
- var l = arguments.length;
- if (l > 1) {
- for (var i=0; i<l; i++) { this.addTween(arguments[i]); }
- return arguments[0];
- } else if (l == 0) { return null; }
- this.removeTween(tween);
- this._tweens.push(tween);
- tween.setPaused(true);
- tween._paused = false;
- tween._useTicks = this._useTicks;
- if (tween.duration > this.duration) { this.duration = tween.duration; }
- if (this._prevPos >= 0) { tween.setPosition(this._prevPos, createjs.Tween.NONE); }
- return tween;
- };
-
- /**
- * Removes one or more tweens from this timeline.
- * @method removeTween
- * @param {Tween} ...tween The tween(s) to remove. Accepts multiple arguments.
- * @return Boolean Returns `true` if all of the tweens were successfully removed.
- **/
- p.removeTween = function(tween) {
- var l = arguments.length;
- if (l > 1) {
- var good = true;
- for (var i=0; i<l; i++) { good = good && this.removeTween(arguments[i]); }
- return good;
- } else if (l == 0) { return false; }
-
- var tweens = this._tweens;
- var i = tweens.length;
- while (i--) {
- if (tweens[i] == tween) {
- tweens.splice(i, 1);
- if (tween.duration >= this.duration) { this.updateDuration(); }
- return true;
- }
- }
- return false;
- };
-
- /**
- * Adds a label that can be used with {{#crossLink "Timeline/gotoAndPlay"}}{{/crossLink}}/{{#crossLink "Timeline/gotoAndStop"}}{{/crossLink}}.
- * @method addLabel
- * @param {String} label The label name.
- * @param {Number} position The position this label represents.
- **/
- p.addLabel = function(label, position) {
- this._labels[label] = position;
- var list = this._labelList;
- if (list) {
- for (var i= 0,l=list.length; i<l; i++) { if (position < list[i].position) { break; } }
- list.splice(i, 0, {label:label, position:position});
- }
- };
-
- /**
- * Defines labels for use with gotoAndPlay/Stop. Overwrites any previously set labels.
- * @method setLabels
- * @param {Object} o An object defining labels for using {{#crossLink "Timeline/gotoAndPlay"}}{{/crossLink}}/{{#crossLink "Timeline/gotoAndStop"}}{{/crossLink}}
- * in the form `{labelName:time}` where time is in milliseconds (or ticks if `useTicks` is `true`).
- **/
- p.setLabels = function(o) {
- this._labels = o ? o : {};
- };
-
- /**
- * Returns a sorted list of the labels defined on this timeline.
- * @method getLabels
- * @return {Array[Object]} A sorted array of objects with label and position properties.
- **/
- p.getLabels = function() {
- var list = this._labelList;
- if (!list) {
- list = this._labelList = [];
- var labels = this._labels;
- for (var n in labels) {
- list.push({label:n, position:labels[n]});
- }
- list.sort(function (a,b) { return a.position- b.position; });
- }
- return list;
- };
-
- /**
- * Returns the name of the label on or immediately before the current position. For example, given a timeline with
- * two labels, "first" on frame index 4, and "second" on frame 8, getCurrentLabel would return:
- * <UL>
- * <LI>null if the current position is 2.</LI>
- * <LI>"first" if the current position is 4.</LI>
- * <LI>"first" if the current position is 7.</LI>
- * <LI>"second" if the current position is 15.</LI>
- * </UL>
- * @method getCurrentLabel
- * @return {String} The name of the current label or null if there is no label
- **/
- p.getCurrentLabel = function() {
- var labels = this.getLabels();
- var pos = this.position;
- var l = labels.length;
- if (l) {
- for (var i = 0; i<l; i++) { if (pos < labels[i].position) { break; } }
- return (i==0) ? null : labels[i-1].label;
- }
- return null;
- };
-
- /**
- * Unpauses this timeline and jumps to the specified position or label.
- * @method gotoAndPlay
- * @param {String|Number} positionOrLabel The position in milliseconds (or ticks if `useTicks` is `true`)
- * or label to jump to.
- **/
- p.gotoAndPlay = function(positionOrLabel) {
- this.setPaused(false);
- this._goto(positionOrLabel);
- };
-
- /**
- * Pauses this timeline and jumps to the specified position or label.
- * @method gotoAndStop
- * @param {String|Number} positionOrLabel The position in milliseconds (or ticks if `useTicks` is `true`) or label
- * to jump to.
- **/
- p.gotoAndStop = function(positionOrLabel) {
- this.setPaused(true);
- this._goto(positionOrLabel);
- };
-
- /**
- * Advances the timeline to the specified position.
- * @method setPosition
- * @param {Number} value The position to seek to in milliseconds (or ticks if `useTicks` is `true`).
- * @param {Number} [actionsMode] parameter specifying how actions are handled. See the Tween {{#crossLink "Tween/setPosition"}}{{/crossLink}}
- * method for more details.
- * @return {Boolean} Returns `true` if the timeline is complete (ie. the full timeline has run & {{#crossLink "Timeline/loop:property"}}{{/crossLink}}
- * is `false`).
- **/
- p.setPosition = function(value, actionsMode) {
- var t = this._calcPosition(value);
- var end = !this.loop && value >= this.duration;
- if (t == this._prevPos) { return end; }
- this._prevPosition = value;
- this.position = this._prevPos = t; // in case an action changes the current frame.
- for (var i=0, l=this._tweens.length; i<l; i++) {
- this._tweens[i].setPosition(t, actionsMode);
- if (t != this._prevPos) { return false; } // an action changed this timeline's position.
- }
- if (end) { this.setPaused(true); }
- this.dispatchEvent("change");
- return end;
- };
-
- /**
- * Pauses or plays this timeline.
- * @method setPaused
- * @param {Boolean} value Indicates whether the tween should be paused (`true`) or played (`false`).
- **/
- p.setPaused = function(value) {
- this._paused = !!value;
- createjs.Tween._register(this, !value);
- };
-
- /**
- * Recalculates the duration of the timeline. The duration is automatically updated when tweens are added or removed,
- * but this method is useful if you modify a tween after it was added to the timeline.
- * @method updateDuration
- **/
- p.updateDuration = function() {
- this.duration = 0;
- for (var i=0,l=this._tweens.length; i<l; i++) {
- var tween = this._tweens[i];
- if (tween.duration > this.duration) { this.duration = tween.duration; }
- }
- };
-
- /**
- * Advances this timeline by the specified amount of time in milliseconds (or ticks if `useTicks` is `true`).
- * This is normally called automatically by the Tween engine (via the {{#crossLink "Tween/tick:event"}}{{/crossLink}}
- * event), but is exposed for advanced uses.
- * @method tick
- * @param {Number} delta The time to advance in milliseconds (or ticks if useTicks is true).
- **/
- p.tick = function(delta) {
- this.setPosition(this._prevPosition+delta);
- };
-
- /**
- * If a numeric position is passed, it is returned unchanged. If a string is passed, the position of the
- * corresponding frame label will be returned, or `null` if a matching label is not defined.
- * @method resolve
- * @param {String|Number} positionOrLabel A numeric position value or label string.
- **/
- p.resolve = function(positionOrLabel) {
- var pos = Number(positionOrLabel);
- if (isNaN(pos)) { pos = this._labels[positionOrLabel]; }
- return pos;
- };
-
- /**
- * Returns a string representation of this object.
- * @method toString
- * @return {String} a string representation of the instance.
- **/
- p.toString = function() {
- return "[Timeline]";
- };
-
- /**
- * @method clone
- * @protected
- **/
- p.clone = function() {
- throw("Timeline can not be cloned.")
- };
-
- // private methods:
- /**
- * @method _goto
- * @param {String | Number} positionOrLabel
- * @protected
- **/
- p._goto = function(positionOrLabel) {
- var pos = this.resolve(positionOrLabel);
- if (pos != null) { this.setPosition(pos); }
- };
-
- /**
- * @method _calcPosition
- * @param {Number} value
- * @return {Number}
- * @protected
- **/
- p._calcPosition = function(value) {
- if (value < 0) { return 0; }
- if (value < this.duration) { return value; }
- return this.loop ? value%this.duration : this.duration;
- };
-
- createjs.Timeline = createjs.promote(Timeline, "EventDispatcher");
-
- }());
-
- //##############################################################################
- // Ease.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- (function() {
- "use strict";
-
- /**
- * The Ease class provides a collection of easing functions for use with TweenJS. It does not use the standard 4 param
- * easing signature. Instead it uses a single param which indicates the current linear ratio (0 to 1) of the tween.
- *
- * Most methods on Ease can be passed directly as easing functions:
- *
- * Tween.get(target).to({x:100}, 500, Ease.linear);
- *
- * However, methods beginning with "get" will return an easing function based on parameter values:
- *
- * Tween.get(target).to({y:200}, 500, Ease.getPowIn(2.2));
- *
- * Please see the <a href="http://www.createjs.com/Demos/TweenJS/Tween_SparkTable">spark table demo</a> for an
- * overview of the different ease types on <a href="http://tweenjs.com">TweenJS.com</a>.
- *
- * <em>Equations derived from work by Robert Penner.</em>
- * @class Ease
- * @static
- **/
- function Ease() {
- throw "Ease cannot be instantiated.";
- }
-
-
- // static methods and properties
- /**
- * @method linear
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.linear = function(t) { return t; };
-
- /**
- * Identical to linear.
- * @method none
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.none = Ease.linear;
-
- /**
- * Mimics the simple -100 to 100 easing in Flash Pro.
- * @method get
- * @param {Number} amount A value from -1 (ease in) to 1 (ease out) indicating the strength and direction of the ease.
- * @static
- * @return {Function}
- **/
- Ease.get = function(amount) {
- if (amount < -1) { amount = -1; }
- if (amount > 1) { amount = 1; }
- return function(t) {
- if (amount==0) { return t; }
- if (amount<0) { return t*(t*-amount+1+amount); }
- return t*((2-t)*amount+(1-amount));
- };
- };
-
- /**
- * Configurable exponential ease.
- * @method getPowIn
- * @param {Number} pow The exponent to use (ex. 3 would return a cubic ease).
- * @static
- * @return {Function}
- **/
- Ease.getPowIn = function(pow) {
- return function(t) {
- return Math.pow(t,pow);
- };
- };
-
- /**
- * Configurable exponential ease.
- * @method getPowOut
- * @param {Number} pow The exponent to use (ex. 3 would return a cubic ease).
- * @static
- * @return {Function}
- **/
- Ease.getPowOut = function(pow) {
- return function(t) {
- return 1-Math.pow(1-t,pow);
- };
- };
-
- /**
- * Configurable exponential ease.
- * @method getPowInOut
- * @param {Number} pow The exponent to use (ex. 3 would return a cubic ease).
- * @static
- * @return {Function}
- **/
- Ease.getPowInOut = function(pow) {
- return function(t) {
- if ((t*=2)<1) return 0.5*Math.pow(t,pow);
- return 1-0.5*Math.abs(Math.pow(2-t,pow));
- };
- };
-
- /**
- * @method quadIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quadIn = Ease.getPowIn(2);
- /**
- * @method quadOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quadOut = Ease.getPowOut(2);
- /**
- * @method quadInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quadInOut = Ease.getPowInOut(2);
-
- /**
- * @method cubicIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.cubicIn = Ease.getPowIn(3);
- /**
- * @method cubicOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.cubicOut = Ease.getPowOut(3);
- /**
- * @method cubicInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.cubicInOut = Ease.getPowInOut(3);
-
- /**
- * @method quartIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quartIn = Ease.getPowIn(4);
- /**
- * @method quartOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quartOut = Ease.getPowOut(4);
- /**
- * @method quartInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quartInOut = Ease.getPowInOut(4);
-
- /**
- * @method quintIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quintIn = Ease.getPowIn(5);
- /**
- * @method quintOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quintOut = Ease.getPowOut(5);
- /**
- * @method quintInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.quintInOut = Ease.getPowInOut(5);
-
- /**
- * @method sineIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.sineIn = function(t) {
- return 1-Math.cos(t*Math.PI/2);
- };
-
- /**
- * @method sineOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.sineOut = function(t) {
- return Math.sin(t*Math.PI/2);
- };
-
- /**
- * @method sineInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.sineInOut = function(t) {
- return -0.5*(Math.cos(Math.PI*t) - 1);
- };
-
- /**
- * Configurable "back in" ease.
- * @method getBackIn
- * @param {Number} amount The strength of the ease.
- * @static
- * @return {Function}
- **/
- Ease.getBackIn = function(amount) {
- return function(t) {
- return t*t*((amount+1)*t-amount);
- };
- };
- /**
- * @method backIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.backIn = Ease.getBackIn(1.7);
-
- /**
- * Configurable "back out" ease.
- * @method getBackOut
- * @param {Number} amount The strength of the ease.
- * @static
- * @return {Function}
- **/
- Ease.getBackOut = function(amount) {
- return function(t) {
- return (--t*t*((amount+1)*t + amount) + 1);
- };
- };
- /**
- * @method backOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.backOut = Ease.getBackOut(1.7);
-
- /**
- * Configurable "back in out" ease.
- * @method getBackInOut
- * @param {Number} amount The strength of the ease.
- * @static
- * @return {Function}
- **/
- Ease.getBackInOut = function(amount) {
- amount*=1.525;
- return function(t) {
- if ((t*=2)<1) return 0.5*(t*t*((amount+1)*t-amount));
- return 0.5*((t-=2)*t*((amount+1)*t+amount)+2);
- };
- };
- /**
- * @method backInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.backInOut = Ease.getBackInOut(1.7);
-
- /**
- * @method circIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.circIn = function(t) {
- return -(Math.sqrt(1-t*t)- 1);
- };
-
- /**
- * @method circOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.circOut = function(t) {
- return Math.sqrt(1-(--t)*t);
- };
-
- /**
- * @method circInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.circInOut = function(t) {
- if ((t*=2) < 1) return -0.5*(Math.sqrt(1-t*t)-1);
- return 0.5*(Math.sqrt(1-(t-=2)*t)+1);
- };
-
- /**
- * @method bounceIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.bounceIn = function(t) {
- return 1-Ease.bounceOut(1-t);
- };
-
- /**
- * @method bounceOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.bounceOut = function(t) {
- if (t < 1/2.75) {
- return (7.5625*t*t);
- } else if (t < 2/2.75) {
- return (7.5625*(t-=1.5/2.75)*t+0.75);
- } else if (t < 2.5/2.75) {
- return (7.5625*(t-=2.25/2.75)*t+0.9375);
- } else {
- return (7.5625*(t-=2.625/2.75)*t +0.984375);
- }
- };
-
- /**
- * @method bounceInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.bounceInOut = function(t) {
- if (t<0.5) return Ease.bounceIn (t*2) * .5;
- return Ease.bounceOut(t*2-1)*0.5+0.5;
- };
-
- /**
- * Configurable elastic ease.
- * @method getElasticIn
- * @param {Number} amplitude
- * @param {Number} period
- * @static
- * @return {Function}
- **/
- Ease.getElasticIn = function(amplitude,period) {
- var pi2 = Math.PI*2;
- return function(t) {
- if (t==0 || t==1) return t;
- var s = period/pi2*Math.asin(1/amplitude);
- return -(amplitude*Math.pow(2,10*(t-=1))*Math.sin((t-s)*pi2/period));
- };
- };
- /**
- * @method elasticIn
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.elasticIn = Ease.getElasticIn(1,0.3);
-
- /**
- * Configurable elastic ease.
- * @method getElasticOut
- * @param {Number} amplitude
- * @param {Number} period
- * @static
- * @return {Function}
- **/
- Ease.getElasticOut = function(amplitude,period) {
- var pi2 = Math.PI*2;
- return function(t) {
- if (t==0 || t==1) return t;
- var s = period/pi2 * Math.asin(1/amplitude);
- return (amplitude*Math.pow(2,-10*t)*Math.sin((t-s)*pi2/period )+1);
- };
- };
- /**
- * @method elasticOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.elasticOut = Ease.getElasticOut(1,0.3);
-
- /**
- * Configurable elastic ease.
- * @method getElasticInOut
- * @param {Number} amplitude
- * @param {Number} period
- * @static
- * @return {Function}
- **/
- Ease.getElasticInOut = function(amplitude,period) {
- var pi2 = Math.PI*2;
- return function(t) {
- var s = period/pi2 * Math.asin(1/amplitude);
- if ((t*=2)<1) return -0.5*(amplitude*Math.pow(2,10*(t-=1))*Math.sin( (t-s)*pi2/period ));
- return amplitude*Math.pow(2,-10*(t-=1))*Math.sin((t-s)*pi2/period)*0.5+1;
- };
- };
- /**
- * @method elasticInOut
- * @param {Number} t
- * @static
- * @return {Number}
- **/
- Ease.elasticInOut = Ease.getElasticInOut(1,0.3*1.5);
-
- createjs.Ease = Ease;
-
- }());
-
- //##############################################################################
- // MotionGuidePlugin.js
- //##############################################################################
-
- this.createjs = this.createjs||{};
-
- (function() {
- "use strict";
-
- /**
- * A TweenJS plugin for working with motion guides.
- *
- * To use, install the plugin after TweenJS has loaded. Next tween the 'guide' property with an object as detailed below.
- *
- * createjs.MotionGuidePlugin.install();
- *
- * <h4>Example</h4>
- *
- * // Using a Motion Guide
- * createjs.Tween.get(target).to({guide:{ path:[0,0, 0,200,200,200, 200,0,0,0] }},7000);
- * // Visualizing the line
- * graphics.moveTo(0,0).curveTo(0,200,200,200).curveTo(200,0,0,0);
- *
- * Each path needs pre-computation to ensure there's fast performance. Because of the pre-computation there's no
- * built in support for path changes mid tween. These are the Guide Object's properties:<UL>
- * <LI> path: Required, Array : The x/y points used to draw the path with a moveTo and 1 to n curveTo calls.</LI>
- * <LI> start: Optional, 0-1 : Initial position, default 0 except for when continuing along the same path.</LI>
- * <LI> end: Optional, 0-1 : Final position, default 1 if not specified.</LI>
- * <LI> orient: Optional, string : "fixed"/"auto"/"cw"/"ccw"<UL>
- * <LI>"fixed" forces the object to face down the path all movement (relative to start rotation),</LI>
- * <LI>"auto" rotates the object along the path relative to the line.</LI>
- * <LI>"cw"/"ccw" force clockwise or counter clockwise rotations including flash like behaviour</LI>
- * </UL></LI>
- * </UL>
- * Guide objects should not be shared between tweens even if all properties are identical, the library stores
- * information on these objects in the background and sharing them can cause unexpected behaviour. Values
- * outside 0-1 range of tweens will be a "best guess" from the appropriate part of the defined curve.
- *
- * @class MotionGuidePlugin
- * @constructor
- **/
- function MotionGuidePlugin() {
- throw("MotionGuidePlugin cannot be instantiated.")
- };
-
-
- // static properties:
- /**
- * @property priority
- * @protected
- * @static
- **/
- MotionGuidePlugin.priority = 0; // high priority, should run sooner
-
- /**
- * @property temporary variable storage
- * @private
- * @static
- */
- MotionGuidePlugin._rotOffS;
- /**
- * @property temporary variable storage
- * @private
- * @static
- */
- MotionGuidePlugin._rotOffE;
- /**
- * @property temporary variable storage
- * @private
- * @static
- */
- MotionGuidePlugin._rotNormS;
- /**
- * @property temporary variable storage
- * @private
- * @static
- */
- MotionGuidePlugin._rotNormE;
-
-
- // static methods
- /**
- * Installs this plugin for use with TweenJS. Call this once after TweenJS is loaded to enable this plugin.
- * @method install
- * @static
- **/
- MotionGuidePlugin.install = function() {
- createjs.Tween.installPlugin(MotionGuidePlugin, ["guide", "x", "y", "rotation"]);
- return createjs.Tween.IGNORE;
- };
-
- /**
- * @method init
- * @protected
- * @static
- **/
- MotionGuidePlugin.init = function(tween, prop, value) {
- var target = tween.target;
- if(!target.hasOwnProperty("x")){ target.x = 0; }
- if(!target.hasOwnProperty("y")){ target.y = 0; }
- if(!target.hasOwnProperty("rotation")){ target.rotation = 0; }
-
- if(prop=="rotation"){ tween.__needsRot = true; }
- return prop=="guide"?null:value;
- };
-
- /**
- * @method step
- * @protected
- * @static
- **/
- MotionGuidePlugin.step = function(tween, prop, startValue, endValue, injectProps) {
- // other props
- if(prop == "rotation"){
- tween.__rotGlobalS = startValue;
- tween.__rotGlobalE = endValue;
- MotionGuidePlugin.testRotData(tween, injectProps);
- }
- if(prop != "guide"){ return endValue; }
-
- // guide only information - Start -
- var temp, data = endValue;
- if(!data.hasOwnProperty("path")){ data.path = []; }
- var path = data.path;
- if(!data.hasOwnProperty("end")){ data.end = 1; }
- if(!data.hasOwnProperty("start")){
- data.start = (startValue&&startValue.hasOwnProperty("end")&&startValue.path===path)?startValue.end:0;
- }
-
- // Figure out subline information
- if(data.hasOwnProperty("_segments") && data._length){ return endValue; }
- var l = path.length;
- var accuracy = 10; // Adjust to improve line following precision but sacrifice performance (# of seg)
- if(l >= 6 && (l-2) % 4 == 0){ // Enough points && contains correct number per entry ignoring start
- data._segments = [];
- data._length = 0;
- for(var i=2; i<l; i+=4){
- var sx = path[i-2], sy = path[i-1];
- var cx = path[i+0], cy = path[i+1];
- var ex = path[i+2], ey = path[i+3];
- var oldX = sx, oldY = sy;
- var tempX, tempY, total = 0;
- var sublines = [];
- for(var j=1; j<=accuracy; j++){
- var t = j/accuracy;
- var inv = 1 - t;
- tempX = inv*inv * sx + 2 * inv * t * cx + t*t * ex;
- tempY = inv*inv * sy + 2 * inv * t * cy + t*t * ey;
- total += sublines[sublines.push(Math.sqrt((temp=tempX-oldX)*temp + (temp=tempY-oldY)*temp))-1];
- oldX = tempX;
- oldY = tempY;
- }
- data._segments.push(total);
- data._segments.push(sublines);
- data._length += total;
- }
- } else {
- throw("invalid 'path' data, please see documentation for valid paths");
- }
-
- // Setup x/y tweens
- temp = data.orient;
- data.orient = true;
- var o = {};
- MotionGuidePlugin.calc(data, data.start, o);
- tween.__rotPathS = Number(o.rotation.toFixed(5));
- MotionGuidePlugin.calc(data, data.end, o);
- tween.__rotPathE = Number(o.rotation.toFixed(5));
- data.orient = false; //here and now we don't know if we need to
- MotionGuidePlugin.calc(data, data.end, injectProps);
- data.orient = temp;
-
- // Setup rotation properties
- if(!data.orient){ return endValue; }
- tween.__guideData = data;
- MotionGuidePlugin.testRotData(tween, injectProps);
- return endValue;
- };
-
- /**
- * @method testRotData
- * @protected
- * @static
- **/
- MotionGuidePlugin.testRotData = function(tween, injectProps){
-
- // no rotation informat? if we need it come back, if we don't use 0 & ensure we have guide data
- if(tween.__rotGlobalS === undefined || tween.__rotGlobalE === undefined){
- if(tween.__needsRot){ return; }
- if(tween._curQueueProps.rotation !== undefined){
- tween.__rotGlobalS = tween.__rotGlobalE = tween._curQueueProps.rotation;
- } else {
- tween.__rotGlobalS = tween.__rotGlobalE = injectProps.rotation = tween.target.rotation || 0;
- }
- }
- if(tween.__guideData === undefined){ return; }
-
- // Process rotation properties
- var data = tween.__guideData;
- var rotGlobalD = tween.__rotGlobalE - tween.__rotGlobalS;
- var rotPathD = tween.__rotPathE - tween.__rotPathS;
- var rot = rotGlobalD - rotPathD;
-
- if(data.orient == "auto"){
- if(rot > 180){ rot -= 360; }
- else if(rot < -180){ rot += 360; }
-
- } else if(data.orient == "cw"){
- while(rot < 0){ rot += 360; }
- if(rot == 0 && rotGlobalD > 0 && rotGlobalD != 180){ rot += 360; }
-
- } else if(data.orient == "ccw"){
- rot = rotGlobalD - ((rotPathD > 180)?(360-rotPathD):(rotPathD)); // sign flipping on path
- while(rot > 0){ rot -= 360; }
- if(rot == 0 && rotGlobalD < 0 && rotGlobalD != -180){ rot -= 360; }
- }
-
- data.rotDelta = rot;
- data.rotOffS = tween.__rotGlobalS - tween.__rotPathS;
-
- // reset
- tween.__rotGlobalS = tween.__rotGlobalE = tween.__guideData = tween.__needsRot = undefined;
- };
-
- /**
- * @method tween
- * @protected
- * @static
- **/
- MotionGuidePlugin.tween = function(tween, prop, value, startValues, endValues, ratio, wait, end) {
- var data = endValues.guide;
- if(data == undefined || data === startValues.guide){ return value; }
- if(data.lastRatio != ratio){
- // first time through so calculate what I need to
- var t = ((data.end-data.start)*(wait?data.end:ratio)+data.start);
- MotionGuidePlugin.calc(data, t, tween.target);
- switch(data.orient){
- case "cw": // mix in the original rotation
- case "ccw":
- case "auto": tween.target.rotation += data.rotOffS + data.rotDelta*ratio; break;
- case "fixed": // follow fixed behaviour to solve potential issues
- default: tween.target.rotation += data.rotOffS; break;
- }
- data.lastRatio = ratio;
- }
- if(prop == "rotation" && ((!data.orient) || data.orient == "false")){ return value; }
- return tween.target[prop];
- };
-
- /**
- * Determine the appropriate x/y/rotation information about a path for a given ratio along the path.
- * Assumes a path object with all optional parameters specified.
- * @param data Data object you would pass to the "guide:" property in a Tween
- * @param ratio 0-1 Distance along path, values outside 0-1 are "best guess"
- * @param target Object to copy the results onto, will use a new object if not supplied.
- * @return {Object} The target object or a new object w/ the tweened properties
- * @static
- */
- MotionGuidePlugin.calc = function(data, ratio, target) {
- if(data._segments == undefined){ throw("Missing critical pre-calculated information, please file a bug"); }
- if(target == undefined){ target = {x:0, y:0, rotation:0}; }
- var seg = data._segments;
- var path = data.path;
-
- // find segment
- var pos = data._length * ratio;
- var cap = seg.length - 2;
- var n = 0;
- while(pos > seg[n] && n < cap){
- pos -= seg[n];
- n+=2;
- }
-
- // find subline
- var sublines = seg[n+1];
- var i = 0;
- cap = sublines.length-1;
- while(pos > sublines[i] && i < cap){
- pos -= sublines[i];
- i++;
- }
- var t = (i/++cap)+(pos/(cap*sublines[i]));
-
- // find x/y
- n = (n*2)+2;
- var inv = 1 - t;
- target.x = inv*inv * path[n-2] + 2 * inv * t * path[n+0] + t*t * path[n+2];
- target.y = inv*inv * path[n-1] + 2 * inv * t * path[n+1] + t*t * path[n+3];
-
- // orientation
- if(data.orient){
- target.rotation = 57.2957795 * Math.atan2(
- (path[n+1]-path[n-1])*inv + (path[n+3]-path[n+1])*t,
- (path[n+0]-path[n-2])*inv + (path[n+2]-path[n+0])*t);
- }
-
- return target;
- };
-
- createjs.MotionGuidePlugin = MotionGuidePlugin;
-
- }());
-
- //##############################################################################
- // version.js
- //##############################################################################
-
- this.createjs = this.createjs || {};
-
- (function() {
- "use strict";
-
- /**
- * Static class holding library specific information such as the version and buildDate of
- * the library.
- * @class TweenJS
- **/
- var s = createjs.TweenJS = createjs.TweenJS || {};
-
- /**
- * The version string for this release.
- * @property version
- * @type String
- * @static
- **/
- s.version = /*=version*/"0.6.2"; // injected by build process
-
- /**
- * The build date for this release in UTC format.
- * @property buildDate
- * @type String
- * @static
- **/
- s.buildDate = /*=date*/"Thu, 26 Nov 2015 20:44:31 GMT"; // injected by build process
-
- })();
|