2014-01-03 10:32:13 -08:00
/ *
* Event
* 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 .
* /
/ * *
* A collection of Classes that are shared across all the CreateJS libraries . The classes are included in the minified
* files of each library and are available on the createsjs namespace directly .
*
* < h4 > Example < / h 4 >
* myObject . addEventListener ( "change" , createjs . proxy ( myMethod , scope ) ) ;
*
* @ module CreateJS
* @ main CreateJS
* /
// namespace:
this . createjs = this . createjs || { } ;
( function ( ) {
"use strict" ;
/ * *
* Contains properties and methods shared by all events for use with
* { { # crossLink "EventDispatcher" } } { { / c r o s s L i n k } } .
2014-11-18 15:26:26 -08:00
*
2014-01-03 10:32:13 -08:00
* 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
* * /
var Event = function ( type , bubbles , cancelable ) {
this . initialize ( type , bubbles , cancelable ) ;
} ;
var p = Event . prototype ;
2014-11-18 15:26:26 -08:00
Event . prototype . constructor = Event ;
2014-01-03 10:32:13 -08:00
// events:
// public properties:
/ * *
* The type of event .
* @ property type
* @ type String
* * /
p . type = null ;
/ * *
* The object that generated an event .
* @ property target
* @ type Object
* @ default null
* @ readonly
* /
p . 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
* /
p . currentTarget = null ;
/ * *
* For bubbling events , this indicates the current event phase : < OL >
* < LI > capture phase : starting from the top parent to the target < / L I >
* < LI > at target phase : currently being dispatched from the target < / L I >
* < LI > bubbling phase : from the target to the top parent < / L I >
* < / O L >
* @ property eventPhase
* @ type Number
* @ default 0
* @ readonly
* /
p . eventPhase = 0 ;
/ * *
* Indicates whether the event will bubble through the display list .
* @ property bubbles
* @ type Boolean
* @ default false
* @ readonly
* /
p . bubbles = false ;
/ * *
* Indicates whether the default behaviour of this event can be cancelled via
* { { # crossLink "Event/preventDefault" } } { { / c r o s s L i n k } } . T h i s i s s e t v i a t h e E v e n t c o n s t r u c t o r .
* @ property cancelable
* @ type Boolean
* @ default false
* @ readonly
* /
p . cancelable = false ;
/ * *
* The epoch time at which this event was created .
* @ property timeStamp
* @ type Number
* @ default 0
* @ readonly
* /
p . timeStamp = 0 ;
/ * *
* Indicates if { { # crossLink "Event/preventDefault" } } { { / c r o s s L i n k } } h a s b e e n c a l l e d
* on this event .
* @ property defaultPrevented
* @ type Boolean
* @ default false
* @ readonly
* /
p . defaultPrevented = false ;
/ * *
* Indicates if { { # crossLink "Event/stopPropagation" } } { { / c r o s s L i n k } } o r
* { { # crossLink "Event/stopImmediatePropagation" } } { { / c r o s s L i n k } } h a s b e e n c a l l e d o n t h i s e v e n t .
* @ property propagationStopped
* @ type Boolean
* @ default false
* @ readonly
* /
p . propagationStopped = false ;
/ * *
* Indicates if { { # crossLink "Event/stopImmediatePropagation" } } { { / c r o s s L i n k } } h a s b e e n c a l l e d
* on this event .
* @ property immediatePropagationStopped
* @ type Boolean
* @ default false
* @ readonly
* /
p . immediatePropagationStopped = false ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* Indicates if { { # crossLink "Event/remove" } } { { / c r o s s L i n k } } h a s b e e n c a l l e d o n t h i s e v e n t .
* @ property removed
* @ type Boolean
* @ default false
* @ readonly
* /
p . removed = false ;
// constructor:
/ * *
* Initialization method .
* @ method initialize
* @ 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 .
* @ protected
* * /
p . initialize = function ( type , bubbles , cancelable ) {
this . type = type ;
this . bubbles = bubbles ;
this . cancelable = cancelable ;
this . timeStamp = ( new Date ( ) ) . getTime ( ) ;
} ;
// public methods:
/ * *
* Sets { { # crossLink "Event/defaultPrevented" } } { { / c r o s s L i n k } } t o t r u e .
* Mirrors the DOM event standard .
* @ method preventDefault
* * /
p . preventDefault = function ( ) {
this . defaultPrevented = true ;
} ;
/ * *
* Sets { { # crossLink "Event/propagationStopped" } } { { / c r o s s L i n k } } t o t r u e .
* Mirrors the DOM event standard .
* @ method stopPropagation
* * /
p . stopPropagation = function ( ) {
this . propagationStopped = true ;
} ;
/ * *
* Sets { { # crossLink "Event/propagationStopped" } } { { / c r o s s L i n k } } a n d
* { { # crossLink "Event/immediatePropagationStopped" } } { { / c r o s s L i n k } } t o t r u e .
* Mirrors the DOM event standard .
* @ method stopImmediatePropagation
* * /
p . stopImmediatePropagation = function ( ) {
this . immediatePropagationStopped = this . propagationStopped = true ;
} ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* Causes the active listener to be removed via removeEventListener ( ) ;
2014-11-18 15:26:26 -08:00
*
2014-01-03 10:32:13 -08:00
* myBtn . addEventListener ( "click" , function ( evt ) {
* // do stuff...
* evt . remove ( ) ; // removes this listener.
* } ) ;
2014-11-18 15:26:26 -08:00
*
2014-01-03 10:32:13 -08:00
* @ method remove
* * /
p . remove = function ( ) {
this . removed = true ;
} ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* 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 ) ;
} ;
/ * *
* 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
* 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 .
* /
/ * *
* @ module CreateJS
* /
// namespace:
this . createjs = this . createjs || { } ;
( function ( ) {
"use strict" ;
/ * *
* 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" } } { { / c r o s s L i n k } } m e t h o d .
*
* 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" } } { { / c r o s s L i n k } } m e t h o d , w h i c h m a k e s i t e a s i e r
* to create scoped listeners , listeners that only run once , and listeners with associated arbitrary data . The
* { { # crossLink "EventDispatcher/off" } } { { / c r o s s L i n k } } m e t h o d i s m e r e l y a n a l i a s t o
* { { # crossLink "EventDispatcher/removeEventListener" } } { { / c r o s s L i n k } } .
*
* Another addition to the DOM Level 2 model is the { { # crossLink "EventDispatcher/removeAllEventListeners" } } { { / c r o s s L i n k } }
* 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" } } { { / c r o s s L i n k } } m e t h o d w h i c h r e m o v e s t h e a c t i v e l i s t e n e r .
*
* < h4 > Example < / h 4 >
* Add EventDispatcher capabilities to the "MyClass" class .
*
* EventDispatcher . initialize ( MyClass . prototype ) ;
*
* Add an event ( see { { # crossLink "EventDispatcher/addEventListener" } } { { / c r o s s L i n k } } ) .
*
* 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" } } { { / c r o s s L i n k } }
* 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 .
*
*
* @ class EventDispatcher
* @ constructor
* * /
var EventDispatcher = function ( ) {
/* this.initialize(); */ // not needed.
} ;
var p = EventDispatcher . prototype ;
2014-11-18 15:26:26 -08:00
EventDispatcher . prototype . constructor = EventDispatcher ;
2014-01-03 10:32:13 -08:00
/ * *
* 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 ;
2014-02-02 16:31:06 -08:00
target . willTrigger = p . willTrigger ;
2014-01-03 10:32:13 -08:00
} ;
// constructor:
// private properties:
/ * *
* @ protected
* @ property _listeners
* @ type Object
* * /
p . _listeners = null ;
/ * *
* @ protected
* @ property _captureListeners
* @ type Object
* * /
p . _captureListeners = null ;
// constructor:
/ * *
* Initialization method .
* @ method initialize
* @ protected
* * /
p . initialize = function ( ) { } ;
// 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 < / h 4 >
*
* 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 created anonymous function is returned for use with . removeEventListener ( or . off ) .
*
* < h4 > Example < / h 4 >
*
* 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 > t h a t y o u m u s t p a s s t h e e x a c t f u n c t i o n r e f e r e n c e u s e d w h e n t h e e v e n t w a s a d d e d . I f a p r o x y
* 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 < / h 4 >
*
* 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 .
*
* @ 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 < / h 4 >
*
* // 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 < / h 4 >
*
* // 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 with the specified type .
* @ return { Boolean } Returns the value of eventObj . defaultPrevented .
* * /
2014-11-18 15:26:26 -08:00
p . dispatchEvent = function ( eventObj ) {
2014-01-03 10:32:13 -08:00
if ( typeof eventObj == "string" ) {
// won't bubble, so skip everything if there's no listeners:
var listeners = this . _listeners ;
if ( ! listeners || ! listeners [ eventObj ] ) { return false ; }
eventObj = new createjs . Event ( eventObj ) ;
2014-11-18 15:26:26 -08:00
} else if ( eventObj . target && eventObj . clone ) {
// redispatching an active event object, so clone it:
eventObj = eventObj . clone ( ) ;
2014-01-03 10:32:13 -08:00
}
2014-11-18 15:26:26 -08:00
try { eventObj . target = this ; } catch ( e ) { } // try/catch allows redispatching of native events
2014-01-03 10:32:13 -08:00
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 ;
} ;
/ * *
2014-02-02 16:31:06 -08:00
* Indicates whether there is at least one listener for the specified event type .
2014-01-03 10:32:13 -08:00
* @ 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 ] ) ) ;
} ;
2014-02-02 16:31:06 -08:00
/ * *
* 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" } } { { / c r o s s L i n k } } , b u t i t s e a r c h e s t h e e n t i r e
* 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 ;
} ;
2014-01-03 10:32:13 -08:00
/ * *
* @ 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 ; }
2014-11-18 15:26:26 -08:00
try { eventObj . currentTarget = this ; } catch ( e ) { }
try { eventObj . eventPhase = eventPhase ; } catch ( e ) { }
2014-01-03 10:32:13 -08:00
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 ;
} ( ) ) ;
/ *
2014-11-18 15:26:26 -08:00
* Ticker
* 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 .
* /
/ * *
* @ module CreateJS
* /
// namespace:
this . createjs = this . createjs || { } ;
( function ( ) {
"use strict" ;
2014-11-18 15:56:33 -08:00
2014-11-18 15:26:26 -08:00
// constructor:
2014-11-18 15:56:33 -08:00
/ * *
* 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
* during times of high CPU load . The Ticker class uses a static interface ( ex . < code > Ticker . getPaused ( ) < / c o d e > ) a n d
* should not be instantiated .
*
* < h4 > Example < / h 4 >
*
* createjs . Ticker . addEventListener ( "tick" , handleTick ) ;
* function handleTick ( event ) {
* // Actions carried out each frame
* if ( ! event . paused ) {
* // Actions carried out when the Ticker is not paused.
* }
* }
*
* To update a stage every tick , the { { # crossLink "Stage" } } { { / c r o s s L i n k } } i n s t a n c e c a n a l s o b e u s e d a s a l i s t e n e r , a s
* it will automatically update when it receives a tick event :
*
* createjs . Ticker . addEventListener ( "tick" , stage ) ;
*
* @ class Ticker
* @ uses EventDispatcher
* @ static
* * /
function Ticker ( ) {
throw "Ticker cannot be instantiated." ;
}
2014-11-18 15:26:26 -08:00
// 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 TIMEOUT , but does not require that content be time
* based as with RAF 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 on TIMEOUT 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" } } { { / c r o s s L i n k } } a n d t h e t i c k e v e n t o b j e c t ' s " d e l t a " p r o p e r t i e s
* to make this easier .
*
* Falls back on TIMEOUT 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 "timer"
* @ readonly
* * /
Ticker . TIMEOUT = "timeout" ;
2014-11-18 15:56:33 -08:00
// static events:
2014-11-18 15:26:26 -08:00
/ * *
* Dispatched each tick . The event will be dispatched to each listener even when the Ticker has been paused using
* { { # crossLink "Ticker/setPaused" } } { { / c r o s s L i n k } } .
*
* < h4 > Example < / h 4 >
*
* 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
* /
2014-11-18 15:56:33 -08:00
2014-11-18 15:26:26 -08:00
// public static properties:
/ * *
* Deprecated in favour of { { # crossLink "Ticker/timingMode" } } { { / c r o s s L i n k } } , a n d w i l l b e r e m o v e d i n a f u t u r e v e r s i o n . I f t r u e , t i m i n g M o d e w i l l
* use { { # crossLink "Ticker/RAF_SYNCHED" } } { { / c r o s s L i n k } } b y d e f a u l t .
* @ deprecated Deprecated in favour of { { # crossLink "Ticker/timingMode" } } { { / c r o s s L i n k } } .
* @ 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" } } { { / c r o s s L i n k } } , { { # c r o s s L i n k " T i c k e r / R A F " } } { { / c r o s s L i n k } } , a n d
* { { # crossLink "Ticker/RAF_SYNCHED" } } { { / c r o s s L i n k } } f o r m o d e d e t a i l s .
* @ 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 40 fps ) .
*
* 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 ;
2014-11-18 15:56:33 -08:00
2014-11-18 15:26:26 -08:00
// 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 ) ;
} ;
2014-11-18 15:56:33 -08:00
2014-11-18 15:26:26 -08:00
// private static properties:
/ * *
* @ property _paused
* @ type { Boolean }
* @ protected
* * /
Ticker . _paused = false ;
/ * *
* @ property _inited
* @ type { Boolean }
* @ protected
* * /
Ticker . _inited = false ;
/ * *
* @ property _startTime
* @ type { Number }
* @ protected
* * /
Ticker . _startTime = 0 ;
/ * *
* @ property _pausedTime
* @ type { Number }
* @ protected
* * /
Ticker . _pausedTime = 0 ;
/ * *
* The number of ticks that have passed
* @ property _ticks
* @ type { Number }
* @ protected
* * /
Ticker . _ticks = 0 ;
/ * *
* The number of ticks that have passed while Ticker has been paused
* @ property _pausedTicks
* @ type { Number }
* @ protected
* * /
Ticker . _pausedTicks = 0 ;
/ * *
* @ property _interval
* @ type { Number }
* @ protected
* * /
Ticker . _interval = 50 ;
/ * *
* @ property _lastTime
* @ type { Number }
* @ protected
* * /
Ticker . _lastTime = 0 ;
/ * *
* @ property _times
* @ type { Array }
* @ protected
* * /
Ticker . _times = null ;
/ * *
* @ property _tickTimes
* @ type { Array }
* @ protected
* * /
Ticker . _tickTimes = null ;
/ * *
* Stores the timeout or requestAnimationFrame id .
* @ property _timerId
* @ type { Number }
* @ protected
* * /
Ticker . _timerId = null ;
/ * *
* True if currently using requestAnimationFrame , false if using setTimeout .
* @ property _raf
* @ type { Boolean }
* @ protected
* * /
Ticker . _raf = true ;
2014-11-18 15:56:33 -08:00
2014-11-18 15:26:26 -08:00
// 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 . setInterval ( 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 = null ;
Ticker . _inited = false ;
} ;
/ * *
* Sets the target time ( in milliseconds ) between ticks . Default is 50 ( 20 FPS ) .
*
* Note actual time between ticks may be more than requested depending on CPU load .
* @ method setInterval
* @ static
* @ param { Number } interval Time in milliseconds between ticks . Default value is 50.
* * /
Ticker . setInterval = function ( interval ) {
Ticker . _interval = interval ;
if ( ! Ticker . _inited ) { return ; }
Ticker . _setupTick ( ) ;
} ;
/ * *
* Returns the current target time between ticks , as set with { { # crossLink "Ticker/setInterval" } } { { / c r o s s L i n k } } .
* @ method getInterval
* @ static
* @ return { Number } The current target interval in milliseconds between tick events .
* * /
Ticker . getInterval = function ( ) {
return Ticker . _interval ;
} ;
/ * *
* Sets the target frame rate in frames per second ( FPS ) . For example , with an interval of 40 , < code > getFPS ( ) < / c o d e >
* will return 25 ( 1000 ms per second divided by 40 ms per tick = 25 fps ) .
* @ method setFPS
* @ static
* @ param { Number } value Target number of ticks broadcast per second .
* * /
Ticker . setFPS = function ( value ) {
Ticker . setInterval ( 1000 / value ) ;
} ;
/ * *
* Returns the target frame rate in frames per second ( FPS ) . For example , with an interval of 40 , < code > getFPS ( ) < / c o d e >
* will return 25 ( 1000 ms per second divided by 40 ms per tick = 25 fps ) .
* @ method getFPS
* @ static
* @ return { Number } The current target number of frames / ticks broadcast per second .
* * /
Ticker . getFPS = function ( ) {
return 1000 / Ticker . _interval ;
} ;
/ * *
* 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 20 fps , which indicates an average of 50 ms between
* the end of one tick and the end of the next . However , getMeasuredTickTime ( ) returns 15 ms . This indicates that
* there may be up to 35 ms 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 10 fps , which indicates an average of 100 ms between the end of
* one tick and the end of the next . However , getMeasuredTickTime ( ) returns 20 ms . This would indicate that something
* other than the tick is using ~ 80 ms ( 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 ) ;
} ;
/ * *
* Changes the "paused" state of the Ticker , which can be retrieved by the { { # crossLink "Ticker/getPaused" } } { { / c r o s s L i n k } }
* method , and is passed as the "paused" property of the < code > tick < / c o d e > e v e n t . W h e n t h e t i c k e r i s p a u s e d , a l l
* listeners will still receive a tick event , but the < code > paused < / c o d e > p r o p e r t y w i l l b e f a l s e .
*
* Note that in EaselJS v0 . 5.0 and earlier , "pauseable" listeners would < strong > not < / s t r o n g > r e c e i v e t h e t i c k
* callback when Ticker was paused . This is no longer the case .
*
* < h4 > Example < / h 4 >
*
* createjs . Ticker . addEventListener ( "tick" , handleTick ) ;
* createjs . Ticker . setPaused ( true ) ;
* function handleTick ( event ) {
* console . log ( "Paused:" , event . paused , createjs . Ticker . getPaused ( ) ) ;
* }
*
* @ method setPaused
* @ static
* @ param { Boolean } value Indicates whether to pause ( true ) or unpause ( false ) Ticker .
* * /
Ticker . setPaused = function ( value ) {
Ticker . _paused = value ;
} ;
/ * *
* Returns a boolean indicating whether Ticker is currently paused , as set with { { # crossLink "Ticker/setPaused" } } { { / c r o s s L i n k } } .
* When the ticker is paused , all listeners will still receive a tick event , but this value will be false .
*
* Note that in EaselJS v0 . 5.0 and earlier , "pauseable" listeners would < strong > not < / s t r o n g > r e c e i v e t h e t i c k
* callback when Ticker was paused . This is no longer the case .
*
* < h4 > Example < / h 4 >
*
* createjs . Ticker . addEventListener ( "tick" , handleTick ) ;
* createjs . Ticker . setPaused ( true ) ;
* function handleTick ( event ) {
* console . log ( "Paused:" , createjs . Ticker . getPaused ( ) ) ;
* }
*
* @ method getPaused
* @ static
* @ return { Boolean } Whether the Ticker is currently paused .
* * /
Ticker . getPaused = function ( ) {
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 ( ) - Ticker . _startTime - ( runTime ? Ticker . _pausedTime : 0 ) : - 1 ;
} ;
/ * *
* Similar to getTime ( ) , but returns the time included with the current ( or most recent ) tick event object .
* @ method getEventTime
* @ 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 ) ;
} ;
2014-11-18 15:56:33 -08:00
2014-11-18 15:26:26 -08:00
// 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:
2014-11-18 15:56:33 -08:00
if ( Ticker . _getTime ( ) - Ticker . _lastTime >= ( Ticker . _interval - 1 ) * 0.97 ) {
2014-11-18 15:26:26 -08:00
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 time = Ticker . _getTime ( ) ;
var adjTime = time - Ticker . _startTime ;
var elapsedTime = time - Ticker . _lastTime ;
var paused = Ticker . _paused ;
Ticker . _ticks ++ ;
if ( paused ) {
Ticker . _pausedTicks ++ ;
Ticker . _pausedTime += elapsedTime ;
}
Ticker . _lastTime = time ;
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 = adjTime ;
event . runTime = adjTime - Ticker . _pausedTime ;
Ticker . dispatchEvent ( event ) ;
}
Ticker . _tickTimes . unshift ( Ticker . _getTime ( ) - time ) ;
while ( Ticker . _tickTimes . length > 100 ) { Ticker . _tickTimes . pop ( ) ; }
Ticker . _times . unshift ( adjTime ) ;
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 ( ) ) ;
} ;
2014-11-18 15:56:33 -08:00
createjs . Ticker = Ticker ;
2014-11-18 15:26:26 -08:00
} ( ) ) ;
/ *
2014-01-03 10:32:13 -08:00
* Tween
* 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 .
* /
/ * *
* The TweenJS Javascript library provides a simple but powerful tweening interface . It supports tweening of both
* numeric object properties & CSS style properties , and allows you to chain tweens and actions together to create
* complex sequences .
*
* < h4 > Simple Tween < / h 4 >
* This tween will tween the target ' s alpha property from 0 to 1 for 1 s then call the < code > handleComplete < / c o d e > f u n c t i o n .
*
* target . alpha = 0 ;
* Tween . get ( target ) . to ( { alpha : 1 } , 1000 ) . call ( handleComplete ) ;
* function handleComplete ( ) {
* //Tween complete
* }
*
* < strong > Arguments and Scope < / s t r o n g >
* Tween also supports a ` call() ` with arguments and / or a scope . If no scope is passed , then the function is called
* anonymously ( normal JavaScript behaviour ) . The scope is useful for maintaining scope when doing object - oriented
* style development .
*
* Tween . get ( target ) . to ( { alpha : 0 } )
* . call ( handleComplete , [ argument1 , argument2 ] , this ) ;
*
* < h4 > Chainable Tween < / h 4 >
* This tween will wait 0.5 s , tween the target 's alpha property to 0 over 1s, set it' s visible to false , then call the
* < code > handleComplete < / c o d e > f u n c t i o n .
*
* target . alpha = 1 ;
* Tween . get ( target ) . wait ( 500 ) . to ( { alpha : 0 , visible : false } , 1000 ) . call ( handleComplete ) ;
* function handleComplete ( ) {
* //Tween complete
* }
*
* < h4 > Browser Support < / h 4 >
* TweenJS will work in all browsers .
*
* @ module TweenJS
* @ main TweenJS
* /
// TODO: possibly add a END actionsMode (only runs actions that == position)?
// TODO: evaluate a way to decouple paused from tick registration.
// namespace:
this . createjs = this . createjs || { } ;
( function ( ) {
"use strict" ;
/ * *
* A Tween instance tweens properties for a single target . Instance methods can be chained for easy construction and sequencing :
*
* < h4 > Example < / h 4 >
*
* target . alpha = 1 ;
* 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" } } { { / c r o s s L i n k } } o r p a s s < c o d e > o v e r r i d e : t r u e < / c o d e >
* in the props argument .
*
* Tween . get ( target , { override : true } ) . to ( { x : 100 } ) ;
*
* Subscribe to the "change" event to get notified when a property of the target is changed .
*
* Tween . get ( target , { override : true } ) . to ( { x : 100 } ) . addEventListener ( "change" , handleChange ) ;
* function handleChange ( event ) {
* // The tween changed.
* }
*
* See the Tween { { # crossLink "Tween/get" } } { { / c r o s s L i n k } } m e t h o d f o r a d d i t i o n a l p a r a m d o c u m e n t a t i o n .
* @ 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 . < / L I >
* < LI > useTicks : uses ticks for all durations instead of milliseconds . < / L I >
2014-11-18 15:26:26 -08:00
* < LI > ignoreGlobalPause : sets the { { # crossLink "Tween/ignoreGlobalPause:property" } } { { / c r o s s L i n k } } p r o p e r t y o n t h i s t w e e n . < / L I >
2014-01-03 10:32:13 -08:00
* < 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 . < / L I >
* < LI > position : indicates the initial position for this tween . < / L I >
* < LI > onChange : specifies a listener for the "change" event . < / L I >
* < / U L >
* @ param { Object } [ pluginData ] An object containing data for use by installed plugins . See individual
* plugins ' documentation for details .
* @ extends EventDispatcher
* @ constructor
* /
var Tween = function ( target , props , pluginData ) {
this . initialize ( target , props , pluginData ) ;
} ;
var p = Tween . prototype = new createjs . EventDispatcher ( ) ;
2014-11-18 15:26:26 -08:00
Tween . prototype . constructor = Tween ;
2014-01-03 10:32:13 -08:00
// static interface:
/ * *
* 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 = { } ;
/ * *
* Returns a new tween instance . This is functionally identical to using "new Tween(...)" , but looks cleaner
* with the chained syntax of TweenJS .
* @ example
* 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 . < code > { loop : true , paused : true } < / c o d e > ) .
* All properties default to false . Supported props are : < UL >
* < LI > loop : sets the loop property on this tween . < / L I >
* < LI > useTicks : uses ticks for all durations instead of milliseconds . < / L I >
2014-11-18 15:26:26 -08:00
* < LI > ignoreGlobalPause : sets the { { # crossLink "Tween/ignoreGlobalPause:property" } } { { / c r o s s L i n k } } p r o p e r t y o n t h i s t w e e n . < / L I >
2014-01-03 10:32:13 -08:00
* < 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 . < / L I >
* < LI > position : indicates the initial position for this tween . < / L I >
* < LI > onChange : specifies a listener for the "change" event . < / L I >
* < / U L >
* @ 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 < code > Tween . removeTweens ( target ) < / c o d e > .
* @ 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 ) ;
} ;
/ * *
2014-11-18 15:26:26 -08:00
* Advances all tweens . This typically uses the { { # crossLink "Ticker" } } { { / c r o s s L i n k } } c l a s s , b u t y o u c a n c a l l i t
2014-01-03 10:32:13 -08:00
* 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
* < code > useTicks < / c o d e > s e t t o t r u e .
2014-11-18 15:26:26 -08:00
* @ param { Boolean } paused Indicates whether a global pause is in effect . Tweens with { { # crossLink "Tween/ignoreGlobalPause:property" } } { { / c r o s s L i n k } }
* will ignore this , but all others will pause if this is ` true ` .
2014-01-03 10:32:13 -08:00
* @ 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
* tick events from < code > createjs . Ticker < / c o d e > . N o o t h e r e v e n t s a r e h a n d l e d i n T w e e n .
* @ method handleEvent
2014-11-18 15:26:26 -08:00
* @ param { Object } event An event object passed in by the { { # crossLink "EventDispatcher" } } { { / c r o s s L i n k } } . W i l l
* usually be of type "tick" .
2014-01-03 10:32:13 -08:00
* @ 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 < code > override < / c o d e >
* property is < code > true < / c o d e > .
* @ 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 -- ) {
2014-11-18 15:26:26 -08:00
var tween = tweens [ i ] ;
if ( tween . _target == target ) {
tween . _paused = true ;
tweens . splice ( i , 1 ) ;
2014-01-03 10:32:13 -08:00
}
}
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 ] ;
2014-11-18 15:26:26 -08:00
tween . _paused = true ;
2014-01-03 10:32:13 -08:00
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 ; }
return Tween . _tweens && ! ! Tween . _tweens . length ;
} ;
/ * *
2014-11-18 15:26:26 -08:00
* Installs a plugin , which can modify how certain properties are handled when tweened . See the { { # crossLink "CSSPlugin" } } { { / c r o s s L i n k } }
* for an example of how to write TweenJS plugins .
2014-01-03 10:32:13 -08:00
* @ 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 .
2014-11-18 15:26:26 -08:00
* @ param { Boolean } value If true , the tween is registered . If false the tween is unregistered .
2014-01-03 10:32:13 -08:00
* @ static
* @ protected
* /
Tween . _register = function ( tween , value ) {
var target = tween . _target ;
var tweens = Tween . _tweens ;
if ( value ) {
// 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 ( target ) { target . tweenjs _count -- ; }
var i = tweens . length ;
while ( i -- ) {
if ( tweens [ i ] == tween ) {
tweens . splice ( i , 1 ) ;
return ;
}
}
}
} ;
// public properties:
/ * *
2014-11-18 15:26:26 -08:00
* Causes this tween to continue playing when a global pause is active . For example , if TweenJS is using { { # crossLink "Ticker" } } { { / c r o s s L i n k } } ,
* then setting this to true ( the default ) will cause this tween to be paused when < code > Ticker . setPaused ( true ) < / c o d e >
* is called . See the Tween { { # crossLink "Tween/tick" } } { { / c r o s s L i n k } } m e t h o d f o r m o r e i n f o . C a n b e s e t v i a t h e p r o p s
* parameter .
2014-01-03 10:32:13 -08:00
* @ property ignoreGlobalPause
* @ type Boolean
* @ default false
* /
p . 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
* /
p . loop = false ;
/ * *
* Read - only . 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
* /
p . 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 }
* /
p . pluginData = null ;
// TODO: deprecated.
/ * *
* REMOVED . Use { { # crossLink "EventDispatcher/addEventListener" } } { { / c r o s s L i n k } } a n d t h e { { # c r o s s L i n k " T w e e n / c h a n g e : e v e n t " } } { { / c r o s s L i n k } }
* event .
* @ property onChange
* @ type { Function }
* @ deprecated Use addEventListener and the "change" event .
* /
/ * *
* Read - only . 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 }
* /
p . target = null ;
/ * *
* Read - only . 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 }
* /
p . position = null ;
/ * *
* Read - only . Indicates the tween ' s current position is within a passive wait .
* @ property passive
* @ type { Boolean }
* * /
p . passive = false ;
// events:
/ * *
* Called whenever the tween ' s position changes .
* @ event change
* @ since 0.4 . 0
* * /
// private properties:
/ * *
* @ property _paused
* @ type { Boolean }
* @ default false
* @ protected
* /
p . _paused = false ;
/ * *
* @ property _curQueueProps
* @ type { Object }
* @ protected
* /
p . _curQueueProps = null ;
/ * *
* @ property _initQueueProps
* @ type { Object }
* @ protected
* /
p . _initQueueProps = null ;
/ * *
* @ property _steps
* @ type { Array }
* @ protected
* /
p . _steps = null ;
/ * *
* @ property _actions
* @ type { Array }
* @ protected
* /
p . _actions = null ;
/ * *
* Raw position .
* @ property _prevPosition
* @ type { Number }
* @ default 0
* @ protected
* /
p . _prevPosition = 0 ;
/ * *
* The position within the current step .
* @ property _stepPosition
* @ type { Number }
* @ default 0
* @ protected
* /
p . _stepPosition = 0 ; // this is needed by MovieClip.
/ * *
* Normalized position .
* @ property _prevPos
* @ type { Number }
* @ default - 1
* @ protected
* /
p . _prevPos = - 1 ;
/ * *
* @ property _target
* @ type { Object }
* @ protected
* /
p . _target = null ;
/ * *
* @ property _useTicks
* @ type { Boolean }
* @ default false
* @ protected
* /
p . _useTicks = false ;
/ * *
* @ property _inited
* @ type { boolean }
* @ default false
* @ protected
* /
p . _inited = false ;
// constructor:
/ * *
* @ method initialize
* @ param { Object } target
* @ param { Object } props
* @ param { Object } pluginData
* @ protected
* /
p . initialize = function ( target , props , pluginData ) {
this . target = this . _target = target ;
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 ) ; }
}
this . pluginData = pluginData || { } ;
this . _curQueueProps = { } ;
this . _initQueueProps = { } ;
this . _steps = [ ] ;
this . _actions = [ ] ;
if ( props && props . paused ) { this . _paused = true ; }
else { Tween . _register ( this , true ) ; }
if ( props && props . position != null ) { this . setPosition ( props . position , Tween . NONE ) ; }
} ;
// public methods:
/ * *
* Queues a wait ( essentially an empty tween ) .
* @ example
* //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 < code > useTicks < / c o d e > i s t r u e ) .
* @ param { Boolean } passive Tween properties will not be updated during a passive wait . This
* is mostly useful for use with Timeline ' s 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 .
* @ example
* createjs . Tween . get ( target ) . to ( { alpha : 0 } , 1000 ) ;
* @ method to
* @ param { Object } props An object specifying property target values for this tween ( Ex . < code > { x : 300 } < / c o d e > w o u l d t w e e n t h e x
* property of the target to 300 ) .
* @ param { Number } duration Optional . The duration of the wait in milliseconds ( or in ticks if < code > useTicks < / c o d e > i s t r u e ) .
* Defaults to 0.
* @ param { Function } ease Optional . The easing function to use for this tween . Defaults to a linear ease .
* @ 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 .
* @ example
* //would call myFunction() after 1s.
* myTween . wait ( 1000 ) . call ( myFunction ) ;
* @ method call
* @ param { Function } callback The function to call .
* @ param { Array } params Optional . 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 Optional . 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 .
* @ example
* myTween . wait ( 1000 ) . set ( { visible : false } , foo ) ;
* @ method set
* @ param { Object } props The properties to set ( ex . < code > { visible : false } < / c o d e > ) .
* @ param { Object } target Optional . 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 to play ( unpause ) the specified tween . This enables you to sequence multiple tweens .
* @ example
* 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 to pause the specified tween .
* @ method pause
* @ param { Tween } tween The tween to play . 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 Optional parameter specifying how actions are handled ( ie . call , set , play , pause ) :
* < code > Tween . NONE < / c o d e > ( 0 ) - r u n n o a c t i o n s . < c o d e > T w e e n . L O O P < / c o d e > ( 1 ) - i f n e w p o s i t i o n i s l e s s t h a n o l d , t h e n r u n a l l a c t i o n s
* between old and duration , then all actions between 0 and new . Defaults to < code > LOOP < / c o d e > . < c o d e > T w e e n . R E V E R S E < / c o d e > ( 2 ) - i f n e w
* position is less than old , run all actions between them in reverse .
* @ return { Boolean } Returns true if the tween is complete ( ie . the full tween has run & loop 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 < code > useTicks < / c o d e > i s t r u e ) .
2014-11-18 15:26:26 -08:00
* This is normally called automatically by the Tween engine ( via < code > Tween . tick < / c o d e > ) , b u t i s e x p o s e d f o r
* advanced uses .
2014-01-03 10:32:13 -08:00
* @ method tick
* @ param { Number } delta The time to advance in milliseconds ( or ticks if < code > useTicks < / c o d e > i s t r u e ) .
* /
p . tick = function ( delta ) {
if ( this . _paused ) { return ; }
this . setPosition ( this . _prevPosition + delta ) ;
} ;
/ * *
* Pauses or plays this tween .
* @ method setPaused
* @ param { Boolean } value Indicates whether the tween should be paused ( true ) or played ( false ) .
* @ return { Tween } This tween instance ( for chaining calls )
* /
p . setPaused = function ( value ) {
2014-11-18 15:26:26 -08:00
if ( this . _paused === ! ! value ) { return this ; }
2014-01-03 10:32:13 -08:00
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 = Tween ;
} ( ) ) ;
/ *
* Timeline
* 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 .
* /
/ * *
* @ module TweenJS
* /
// namespace:
this . createjs = this . createjs || { } ;
( function ( ) {
"use strict" ;
/ * *
* 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 addTween for more info .
* @ param { Object } labels An object defining labels for using { { # crossLink "Timeline/gotoAndPlay" } } { { /crossLink}}/ { { # crossLink "Timeline/gotoAndStop" } } { { / c r o s s L i n k } } .
* See { { # crossLink "Timeline/setLabels" } } { { / c r o s s L i n k } }
* 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 . < / L I >
* < LI > useTicks : uses ticks for all durations instead of milliseconds . < / L I >
* < LI > ignoreGlobalPause : sets the ignoreGlobalPause property on this tween . < / L I >
* < LI > paused : indicates whether to start the tween paused . < / L I >
* < LI > position : indicates the initial position for this timeline . < / L I >
* < LI > onChange : specifies a listener to add for the { { # crossLink "Timeline/change:event" } } { { / c r o s s L i n k } } e v e n t . < / L I >
* < / U L >
* @ extends EventDispatcher
* @ constructor
* * /
var Timeline = function ( tweens , labels , props ) {
this . initialize ( tweens , labels , props ) ;
} ;
var p = Timeline . prototype = new createjs . EventDispatcher ( ) ;
2014-11-18 15:26:26 -08:00
Timeline . prototype . constructor = Timeline ;
2014-01-03 10:32:13 -08:00
// public properties:
/ * *
* Causes this timeline to continue playing when a global pause is active .
* @ property ignoreGlobalPause
* @ type Boolean
* * /
p . ignoreGlobalPause = false ;
/ * *
* Read - only property specifying 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 updateDuration for more information .
* @ property duration
* @ type Number
* * /
p . duration = 0 ;
/ * *
* If true , the timeline will loop when it reaches the end . Can be set via the props param .
* @ property loop
* @ type Boolean
* * /
p . loop = false ;
// TODO: deprecated.
/ * *
* REMOVED . Use { { # crossLink "EventDispatcher/addEventListener" } } { { / c r o s s L i n k } } a n d t h e { { # c r o s s L i n k " T i m e l i n e / c h a n g e : e v e n t " } } { { / c r o s s L i n k } }
* event .
* @ property onChange
* @ type Function
* @ deprecated Use addEventListener and the "change" event .
* * /
/ * *
* Read - only . The current normalized position of the timeline . This will always be a value between 0 and duration .
* Changing this property directly will have no effect .
* @ property position
* @ type Object
* * /
p . position = null ;
// events:
/ * *
* Called whenever the timeline ' s position changes .
* @ event change
* @ since 0.5 . 0
* * /
// private properties:
/ * *
* @ property _paused
* @ type Boolean
* @ protected
* * /
p . _paused = false ;
/ * *
* @ property _tweens
* @ type Array [ Tween ]
* @ protected
* * /
p . _tweens = null ;
/ * *
* @ property _labels
* @ type Object
* @ protected
* * /
p . _labels = null ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* @ property _labelList
* @ type Array [ Object ]
* @ protected
* * /
p . _labelList = null ;
/ * *
* @ property _prevPosition
* @ type Number
* @ default 0
* @ protected
* * /
p . _prevPosition = 0 ;
/ * *
* @ property _prevPos
* @ type Number
* @ default - 1
* @ protected
* * /
p . _prevPos = - 1 ;
/ * *
* @ property _useTicks
* @ type Boolean
* @ default false
* @ protected
* * /
p . _useTicks = false ;
// constructor:
/ * *
* Initialization method .
* @ method initialize
* @ protected
* * /
p . initialize = function ( tweens , labels , props ) {
this . _tweens = [ ] ;
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 ) ; }
} ;
// 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 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 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" } } { { / c r o s s L i n k } } .
* @ 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 gotoAndPlay / Stop in the form ` {labelName:time} ` where time is in
* milliseconds ( or ticks if ` useTicks ` is true ) .
* * /
p . setLabels = function ( o ) {
this . _labels = o ? o : { } ;
} ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* 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 ;
} ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* 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. < / L I >
* < LI > "first" if the current position is 4. < / L I >
* < LI > "first" if the current position is 7. < / L I >
* < LI > "second" if the current position is 15. < / L I > < / U L >
* @ 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 ;
} ;
2014-11-18 15:26:26 -08:00
2014-01-03 10:32:13 -08:00
/ * *
* 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" } } { { / c r o s s L i n k } }
* method for more details .
* @ return { Boolean } Returns true if the timeline is complete ( ie . the full timeline has run & loop is false ) .
* * /
p . setPosition = function ( value , actionsMode ) {
if ( value < 0 ) { value = 0 ; }
var t = this . loop ? value % this . duration : 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 Tween . tick ) , 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 ) {
2014-11-18 15:26:26 -08:00
var pos = Number ( positionOrLabel ) ;
2014-01-03 10:32:13 -08:00
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
* @ protected
* * /
p . _goto = function ( positionOrLabel ) {
var pos = this . resolve ( positionOrLabel ) ;
if ( pos != null ) { this . setPosition ( pos ) ; }
} ;
createjs . Timeline = Timeline ;
} ( ) ) ;
/ *
* Ease
* 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 .
* /
/ * *
* @ module TweenJS
* /
// namespace:
this . createjs = this . createjs || { } ;
( function ( ) {
"use strict" ;
// constructor:
/ * *
* 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/#!/TweenJS/demos/sparkTable" > spark table demo < / a > f o r a n o v e r v i e w
* of the different ease types on < a href = "http://tweenjs.com" > TweenJS . com < / a > .
*
* < i > Equations derived from work by Robert Penner . < / i >
* @ class Ease
* @ static
* * /
var Ease = function ( ) {
throw "Ease cannot be instantiated." ;
}
// public static methods:
/ * *
* @ method linear
* @ static
* * /
Ease . linear = function ( t ) { return t ; }
/ * *
* Identical to linear .
* @ method none
* @ static
* * /
Ease . none = Ease . linear ;
/ * *
* Mimics the simple - 100 to 100 easing in Flash Pro .
* @ method get
* @ param amount A value from - 1 ( ease in ) to 1 ( ease out ) indicating the strength and direction of the ease .
* @ static
* * /
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 pow The exponent to use ( ex . 3 would return a cubic ease ) .
* @ static
* * /
Ease . getPowIn = function ( pow ) {
return function ( t ) {
return Math . pow ( t , pow ) ;
}
}
/ * *
* Configurable exponential ease .
* @ method getPowOut
* @ param pow The exponent to use ( ex . 3 would return a cubic ease ) .
* @ static
* * /
Ease . getPowOut = function ( pow ) {
return function ( t ) {
return 1 - Math . pow ( 1 - t , pow ) ;
}
}
/ * *
* Configurable exponential ease .
* @ method getPowInOut
* @ param pow The exponent to use ( ex . 3 would return a cubic ease ) .
* @ static
* * /
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
* @ static
* * /
Ease . quadIn = Ease . getPowIn ( 2 ) ;
/ * *
* @ method quadOut
* @ static
* * /
Ease . quadOut = Ease . getPowOut ( 2 ) ;
/ * *
* @ method quadInOut
* @ static
* * /
Ease . quadInOut = Ease . getPowInOut ( 2 ) ;
/ * *
* @ method cubicIn
* @ static
* * /
Ease . cubicIn = Ease . getPowIn ( 3 ) ;
/ * *
* @ method cubicOut
* @ static
* * /
Ease . cubicOut = Ease . getPowOut ( 3 ) ;
/ * *
* @ method cubicInOut
* @ static
* * /
Ease . cubicInOut = Ease . getPowInOut ( 3 ) ;
/ * *
* @ method quartIn
* @ static
* * /
Ease . quartIn = Ease . getPowIn ( 4 ) ;
/ * *
* @ method quartOut
* @ static
* * /
Ease . quartOut = Ease . getPowOut ( 4 ) ;
/ * *
* @ method quartInOut
* @ static
* * /
Ease . quartInOut = Ease . getPowInOut ( 4 ) ;
/ * *
* @ method quintIn
* @ static
* * /
Ease . quintIn = Ease . getPowIn ( 5 ) ;
/ * *
* @ method quintOut
* @ static
* * /
Ease . quintOut = Ease . getPowOut ( 5 ) ;
/ * *
* @ method quintInOut
* @ static
* * /
Ease . quintInOut = Ease . getPowInOut ( 5 ) ;
/ * *
* @ method sineIn
* @ static
* * /
Ease . sineIn = function ( t ) {
return 1 - Math . cos ( t * Math . PI / 2 ) ;
}
/ * *
* @ method sineOut
* @ static
* * /
Ease . sineOut = function ( t ) {
return Math . sin ( t * Math . PI / 2 ) ;
}
/ * *
* @ method sineInOut
* @ static
* * /
Ease . sineInOut = function ( t ) {
return - 0.5 * ( Math . cos ( Math . PI * t ) - 1 )
}
/ * *
* Configurable "back in" ease .
* @ method getBackIn
* @ param amount The strength of the ease .
* @ static
* * /
Ease . getBackIn = function ( amount ) {
return function ( t ) {
return t * t * ( ( amount + 1 ) * t - amount ) ;
}
}
/ * *
* @ method backIn
* @ static
* * /
Ease . backIn = Ease . getBackIn ( 1.7 ) ;
/ * *
* Configurable "back out" ease .
* @ method getBackOut
* @ param amount The strength of the ease .
* @ static
* * /
Ease . getBackOut = function ( amount ) {
return function ( t ) {
return ( -- t * t * ( ( amount + 1 ) * t + amount ) + 1 ) ;
}
}
/ * *
* @ method backOut
* @ static
* * /
Ease . backOut = Ease . getBackOut ( 1.7 ) ;
/ * *
* Configurable "back in out" ease .
* @ method getBackInOut
* @ param amount The strength of the ease .
* @ static
* * /
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
* @ static
* * /
Ease . backInOut = Ease . getBackInOut ( 1.7 ) ;
/ * *
* @ method circIn
* @ static
* * /
Ease . circIn = function ( t ) {
return - ( Math . sqrt ( 1 - t * t ) - 1 ) ;
}
/ * *
* @ method circOut
* @ static
* * /
Ease . circOut = function ( t ) {
return Math . sqrt ( 1 - ( -- t ) * t ) ;
}
/ * *
* @ method circInOut
* @ static
* * /
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
* @ static
* * /
Ease . bounceIn = function ( t ) {
return 1 - Ease . bounceOut ( 1 - t ) ;
}
/ * *
* @ method bounceOut
* @ static
* * /
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
* @ static
* * /
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 amplitude
* @ param period
* @ static
* * /
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
* @ static
* * /
Ease . elasticIn = Ease . getElasticIn ( 1 , 0.3 ) ;
/ * *
* Configurable elastic ease .
* @ method getElasticOut
* @ param amplitude
* @ param period
* @ static
* * /
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
* @ static
* * /
Ease . elasticOut = Ease . getElasticOut ( 1 , 0.3 ) ;
/ * *
* Configurable elastic ease .
* @ method getElasticInOut
* @ param amplitude
* @ param period
* @ static
* * /
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
* @ static
* * /
Ease . elasticInOut = Ease . getElasticInOut ( 1 , 0.3 * 1.5 ) ;
createjs . Ease = Ease ;
} ( ) ) ;
/ *
* MotionGuidePlugin
* 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 .
* /
/ * *
* @ module TweenJS
* /
// namespace:
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 < / h 4 >
*
* // 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 . < / L I >
* < LI > start : Optional , 0 - 1 : Initial position , default 0 except for when continuing along the same path . < / L I >
* < LI > end : Optional , 0 - 1 : Final position , default 1 if not specified . < / L I >
* < 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 ) , < / L I >
* < LI > "auto" rotates the object along the path relative to the line . < / L I >
* < LI > "cw" / "ccw" force clockwise or counter clockwise rotations including flash like behaviour < / L I >
* < / U L > < / L I >
* < / U L >
* 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
* * /
var MotionGuidePlugin = function ( ) {
throw ( "MotionGuidePlugin cannot be instantiated." )
} ;
// static interface:
/ * *
* @ 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 ;
/ * *
* 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 ) { MotionGuidePlugin . validate ( data ) ; }
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 ;
} ;
// public properties:
// private properties:
// constructor:
// public methods:
// private methods:
createjs . MotionGuidePlugin = MotionGuidePlugin ;
} ( ) ) ;
/ * *
* @ module TweenJS
* /
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
* * /
2014-02-02 16:31:06 -08:00
s . version = /*version*/ "NEXT" ; // injected by build process
2014-01-03 10:32:13 -08:00
/ * *
* The build date for this release in UTC format .
* @ property buildDate
* @ type String
* @ static
* * /
2014-11-18 15:26:26 -08:00
s . buildDate = /*date*/ "Fri, 24 Oct 2014 16:09:53 GMT" ; // injected by build process
2014-01-03 10:32:13 -08:00
} ) ( ) ;