lib-flex-animation-code-10-com-gskinner-motion-GTween.ax (swf ) [ flash ] flex
* @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween by Grant Skinner. Aug 15, 2008 * Visit www.gskinner.com/blog for documentation, updates and more free code. * * * Copyright (c) 2008 Grant Skinner * * 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. *
* <b>@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween ©2008 Grant Skinner, gskinner.com. Visit www.gskinner.com/blog for documentation, updates and more free code. Licensed under the MIT license. See the source file header for more information.</b> *
* @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween is a light-weight instance oriented tween engine. This means that you instantiate tweens for specific purposes, and then reuse, update or discard them. * This is different than centralized tween engines where you "register" tweens with a single object. This provides a more familiar and useful interface * for object oriented programmers. *
* In addition to a more traditional setProperty/setProperties tweening interface, @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween also provides a unique proxy interface to tween and access properties of target objects * in a more dynamic fashion. This allows you to work with properties directly, and mostly ignore the details of the tween. The proxy "stands in" * for your object when working with tweened properties. For example, you can modify destination values (the value you are tweening to), in the middle of a tween. * You can also access them dynamically, like so: *
*mySpriteTween.proxy.rotation += 50;
*
* Assuming no destination value has been set for rotation previously, the above example will get the current rotation from the target, add 50 to it, set it as the destination * value for rotation, and start the tween. If the tween has already started, it will adjust for the new values. This is a hugely powerful feature that * requires a bit of exploring to completely understand the potential. See the documentation for the "proxy" property for more information. *
* For a light weight engine (<5kb), @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween boasts a number of advanced features:*
*- frame or time based animation engine *
- works with any numeric properties on any object (not just display objects) *
- sequenced tweens using nextTween *
- synchronized child tweens *
- pause and resume individual tweens or all tweens *
- jump directly to the end or beginning of a tween with .end() or .beginning() *
- jump to any arbitrary point in the tween with .position *
- auto hide for alpha tweens, sets visible to false when alpha is 0 or less with .autoHide *
- smart tweening for rotation (rotates in the shortest direction) with .useSmartRotation *
- uses setSize calls when supported for width and height tweens (good for Flash and Flex components) *
- complete, activate, init, and change events *
- configurable progress events indicate when specified points in the tween are reached *
- smart garbage collector interactions (prevents collection while active, allows collection if target is collected) *
- uses any standard ActionScript tween functions *
- support for tweening objects like colorTransform and matrix that need to be reassigned to a property *
- cloneable *
- easy to set up in a single line of code *
* Beta 2 updates (Sep 2, 2008):*
**/ public class @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween extends EventDispatcher { /** * Dispatched when a tween activates and first starts running. That is, when the tween exits the beginning or end state, and enters either the * delayPhase or tweenPhase state. **/ [Event(name="activate", type="flash.events.Event")] /** * Dispatched when a tween copies its initial properties and starts tweening. In tweens with a delay of 0, this event will * fire immediately after the activate event. In tweens with a delay set, this will fire when the delayPhase state is ended, and the tweenPhase state is entered. **/ [Event(name="init", type="flash.events.Event")] /** Dispatched when a tween ends (its position equals its duration). **/ [Event(name="complete", type="flash.events.Event")] /** This event is dispatched when the tween passes a progress point, and the lastProgressPoint property is updated. **/ [Event(name="progress", type="flash.events.Event")] /** * This event is dispatched each time the tween updates properties on its target. * It will be dispatched each "tick" while the tween is in the TWEEN_PHASE. **/ [Event(name="change", type="flash.events.Event")] // constants: /** Constant for the TIME timingMode. **/ public static const TIME:String = "time"; /** Constant for the FRAME timingMode. **/ public static const FRAME:String = "frame"; /** Constant for the HYBRID timingMode. **/ public static const HYBRID:String = "hybrid"; /** Constant for the BEGINNING state. **/ public static const BEGINNING:String = "beginning"; /** Constant for the DELAY_PHASE state. **/ public static const DELAY_PHASE:String = "delayPhase"; /** Constant for the TWEEN_PHASE state. **/ public static const TWEEN_PHASE:String = "tweenPhase"; /** Constant for the END state. **/ public static const END:String = "end"; /** Constant for the PROGRESS event type. **/ public static const PROGRESS:String = "progress"; // public static properties: /** Setting this to true pauses all tween instances. This does not affect individual tweens' .paused property. **/ public static var pauseAll:Boolean=false; /** * Indicates how @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween should deal with timing. This can be set to either @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.TIME, @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.FRAME, or @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.HYBRID. *- renamed .transitionFunction property to .ease (for consistency with other engines - thanks to Marcus Stade for the feedback) *
- renamed @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.paused static property to .pauseAll (for clarity, and to fix a problem with ASDoc) *
- default .timingMode changed to HYBRID (better default choice) *
- added .roundValues property (thanks to Vaclav Vancura for the feedback) *
- fixed a typing conflict for progress points (data was mistakenly typed as String instead of * - thanks to Thomas Rudin for the feedback) *
- changed .removeProgressPoint() to accept a position instead of data (thanks again to Thomas Rudin) *
- added .clone() method *
- added a CHANGE event (thanks to Elliot Geno for the feedback) *
- added support in setTweenProperties for setting up event listeners with the special eventListener properties (ex. progressListener). This also applies to the tweenProperties parameter of the constructor. (thanks to thienhaflash for the feedback) *
- added a .data property *
- added additional checking for bad values for delay, duration, and position *
- still under 5kb *
* In frame mode, @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween will update once every frame, and all positional values are specified in frames (duration, position, delay, and progress point positions). *
* In time mode, updates will occur at an interval specified by the timeInterval property, independent of the frame rate, and all positional values are * specified in seconds. *
* In hybrid mode, all updates occur on a frame, but all positional values are specified in seconds. Each frame the tween will calculate it's position based on the elapsed time. * This offers lower CPU usage, and a more familiar time based interface, but can result in choppy animations in high CPU situations. *
* The time mode will generally run more smoothly, as it is less dependent on the running frame rate of the movie. The frame mode will generally use less CPU, * and can be synched with timeline animations. You can change modes at any time, but existing tweens will continue to use the mode that was active when they were created. **/ public static function get timingMode():String { return _timingMode; } public static function set timingMode(value:String):void { value = (value == FRAME || value == TIME) ? value : HYBRID; if (value == _timingMode) { return; } _timingMode = value; if (_timingMode == TIME) { ticker = new TimeTicker(); (ticker as TimeTicker).interval = _timeInterval/1000; } else if (_timingMode == FRAME) { ticker = new FrameTicker(); } else { ticker = new HybridTicker(); } } /** * Sets the time in milliseconds between updates when timingMode is set to @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.TIME ("time"). Setting this to a lower number * will generally result in smoother animations but higher CPU usage. Defaults to 40ms (~25 updates per second). **/ public static function get timeInterval():uint { return _timeInterval; } public static function set timeInterval(value:uint):void { _timeInterval = value; if (ticker is TimeTicker) { (ticker as TimeTicker).interval = _timeInterval/1000; } } // private static properties: /** @private **/ protected static var activeTweens:Dictionary = new Dictionary(false); // keeps active tweens in memory /** @private **/ protected static var _timingMode:String; /** @private **/ protected static var _timeInterval:uint = 40; /** @private **/ protected static var ticker:ITicker; // public properties: /** * When true, the tween will always rotate in the shortest direction to reach the destination rotation. * For example, rotating from 355 degress to 5 degrees will rotate 10 degrees clockwise with useSmartRotation set to true. * It would rotate 350 degrees counter-clockwise with useSmartRotation set to false. **/ public var useSmartRotation:Boolean = true; /** * Indicates whether the tween should automatically play when a destination value is changed. **/ public var autoPlay:Boolean = true; /** * The transition function to use for calculating the tween. This can be any standard tween function, such as the tween functions in fl.motion.easing.* that come with Flash CS3. **/ public var ease:Function; /** * Specifies another @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance that will have .play() called on it when this tween completes. **/ public var nextTween:@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween; /** * Specifies whether the tween should automatically reverse its initial and destination property values when it reaches its end. * Example: this could be used to create a tween that automatically plays forward and in reverse continually with:
*myTween.autoReverse = true;
**/ public var autoReverse:Boolean = false; /** * Allows you to reassign the .target object back to a property specified by assignmentProperty of an object specified by assignmentTarget. * Useful for tweening elements like colorTransform that need to be reassigned to have an effect. *
* myTween.nextTween = myTween; // automatically play this tween again when it ends
* See setAssignment() for more information. * @see com.gskinner.motion.@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween#setAssignment() @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.setAssignment() **/ public var assignmentTarget:Object; /** * Allows you to reassign the .target object back to a property specified by assignmentProperty of an object specified by assignmentTarget. * Useful for tweening elements like colorTransform that need to be reassigned to have an effect. *
* See setAssignment() for more information. * @see com.gskinner.motion.@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween#setAssignment() @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.setAssignment() **/ public var assignmentProperty:String; /** * If set to true, all tweened values will be rounded before they are assigned to the target. **/ public var roundValues:Boolean = false; /** * Allows you to associate arbitrary data with your tween. For example, you might use this to reference specific data when handling events from tweens. **/ public var data:*; // private properties: /** @private **/ protected var _target:Object; /** @private **/ protected var _position:Number=0; /** @private **/ protected var _duration:Number=10; /** @private **/ protected var _lastProgressPoint:ProgressPoint; /** @private **/ protected var _autoHide:Boolean=true; /** @private **/ protected var _proxy:TargetProxy; /** @private **/ protected var _paused:Boolean=true; /** @private **/ protected var _state:String = BEGINNING; /** @private **/ protected var _delay:Number = 0; /** @private **/ protected var destProperties:Object; // stores the destination property values. /** @private **/ protected var initProperties:Object; // stores the initial property values of the target. /** @private **/ protected var invalid:Boolean=false; /** @private **/ protected var children:Dictionary; /** @private **/ protected var hasSetSize:Boolean = false; /** @private **/ protected var hasAlphaAndVisible:Boolean = true; /** @private **/ protected var progressPoints:Array; /** @private **/ protected var positionOffset:Number = NaN; // indicates this tween's offset from the ticker position /** @private **/ protected var ticker:ITicker; // maintains a local reference, in case the timingMode changes /** @private **/ protected var clearProperties:Boolean = true; // constructor: /** * Constructs a new @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance. * * @param target The object whose properties will be tweened. Defaults to null. * @param duration The length of the tween in frames or seconds depending on the timingMode. Defaults to 10. * @param props An object containing destination property values. For example, to tween to x=100, y=100, you could pass {x:100, y:100} as the props object. * @param tweenProperties An object containing properties to set on this tween. For example, you could pass {autoHide:true} to set the autoHide property of the new instance. This also provides a shortcut for setting up event listeners. See .setTweenProperties() for more information. **/ public function @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween(target:Object=null, duration:Number=10, properties:Object=null, tweenProperties:Object=null) { if (isNaN(duration)) { duration = 10; } if (_timingMode == null) { timingMode = HYBRID; } ticker = @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.ticker; progressPoints = []; children = new Dictionary(true); this.target = target; _duration = duration; setTweenProperties(tweenProperties); setProperties(properties); } // public getter/setters: /** * The proxy object allows you to work with the properties and methods of the target object directly through @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween. * Numeric property assignments will be used by @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween as destination values. The proxy will return @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween destination values * when they are set, or the target's property values if they are not. Delete operations on properties will result in a deleteProperty * call. All other property access and method execution through proxy will be passed directly to the target object. *
* Example 1: Equivalent to calling my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.setProperty("scaleY",2.5):
*my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.scaleY = 2.5;
*
* Example 2: Gets the current rotation value from the target object (because it hasn't been set yet on the @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween), adds 100 to it, and then * calls setProperty on the @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance with the appropriate value:
*my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.rotation += 100;
*
* Example 3: Sets a destination value (through setProperty) for scaleX, then retrieves it from @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween (because it will always return * destination values when available):
*trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.scaleX); // 1 (value from target, because no destination value is set)
*
* my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.scaleX = 2; // set a destination value
* trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.scaleX); // 2 (destination value from @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween)
* trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.target.scaleX); // 1 (current value from target)
* Example 4: Property deletions only affect destination properties on @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween, not the target object:
*my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.rotation = 50; // set a destination value
*
* trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.rotation); // 50 (destination value from @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween)
* delete(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.rotation); // delete the destination value
* trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.rotation); // 0 (current value from target)
* Example 5: Non-numeric property access is passed through to the target:
*my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.blendMode = "multiply"; // passes value assignment through to the target
*
* trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.target.blendMode); // "multiply" (value from target)
* trace(my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.blendMode); // "multiply" (value passed through from target)
* Example 6: Method calls are passed through to target:
*my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.proxy.gotoAndStop(30); // gotoAndStop(30) will be called on the target
**/ public function get proxy():Object { if (_proxy == null) { _proxy = new TargetProxy(this); } return _proxy; } /** * Gets and sets the position in the tween in frames or seconds (depending on the timingMode). The value will be between -delay and duration (beginning and end of tween respectively). *
* Note: Normally this value would be set and modified automatically by the tween, but is provided for advanced users. **/ public function get position():Number { return _position; } public function set position(value:Number):void { if (isNaN(value)) { return } value = (value > _duration) ? _duration : ((value < -_delay) ? -_delay : value); if (_position == value) { return; } positionOffset = ticker.position-(_position = value); update(); } /** * The length of the tween in frames or seconds (depending on the timingMode). Setting this will also update any child transitions * that have synchDuration set to true. **/ public function get duration():Number { return _duration; } public function set duration(value:Number):void { if (isNaN(value)) { return } _duration = value; for (var n:Object in children) { if (children[n]) { (n as @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween).duration = _duration; } } } /** * The length of the delay in frames or seconds (depending on the timingMode). The delay occurs before a tween reads initial values or starts playing. **/ public function get delay():Number { return _delay; } public function set delay(value:Number):void { if (isNaN(value)) { return } if (_state == BEGINNING || _position == -_delay) { positionOffset = ticker.position-(_position = -value); } _delay = value; } /** * The target object to tween. This can be any kind of object. **/ public function get target():Object { return _target; } public function set target(value:Object):void { _target = (value === null) ? {} : value; hasSetSize = "setSize" in _target; hasAlphaAndVisible = "alpha" in _target && "visible" in _target; reset(); } /** * Indicates whether the target's visible property should automatically be set to false when its alpha value is tweened to 0 or less. * Only affects objects with a visible property. **/ public function get autoHide():Boolean { return _autoHide; } public function set autoHide(value:Boolean):void { _autoHide = value; if (hasAlphaAndVisible) { _target.visible = (_target.alpha > 0); } } /** * Returns the name of the last progress point that was passed, or null if none. **/ public function get lastProgressPoint():* { return (_lastProgressPoint) ? _lastProgressPoint.data : null; } /** * Returns the current positional state of the tween. This does not indicate if the tween is paused - use the .paused property for this. Possible values are:* @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.BEGINNING, @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.DELAY_PHASE, @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.TWEEN_PHASE, @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.END
* The beginning state indicates the tween either has not been played. The tween's position will equal -delay.
* The delayPhase state indicates that the tween is active (running), but is currently delaying prior to initing. The tween's position is less than 0. Note that it may be paused.
* The tweenPhase state indicates that the tween has inited, and is tweening the property values. Note that it may be paused.
* The end state indicates that the tween has completed playing. Setting any new properties on the tween will reset it, and set its state to beginning. *
* New tweens with autoplay set to false start with a state of BEGINNING. When first played, a tween will have a state of either DELAY_PHASE (if delay > 0) or TWEEN_PHASE (if delay == 0). * When the delay ends, and tweening begins, the state will change to TWEEN_PHASE. When the tween reaches its end (position == duration), the state will be set to END. If you change any destination * properties on an ended tween, its state will be set back to BEGINNING. **/ public function get state():String { return _state; } /** * Indicates whether the tween is currently paused (including when it is at the beginning or end). See play() and pause() for more information. **/ public function get paused():Boolean { return _paused; } public function set paused(value:Boolean):void { if (_paused == value) { return; } _paused = value; if (value) { ticker.removeEventListener("tick",handleTick); // free this instance for collection: if (_target is IEventDispatcher) { _target.removeEventListener("GDS__NONEXISTENT_EVENT", nullListener); } delete(activeTweens[this]); } else { if (_state == BEGINNING || _state == END) { _position = -_delay; activate(); } positionOffset = ticker.position-_position; ticker.addEventListener("tick",handleTick); // lock the tween in memory while it's active: if (_target is IEventDispatcher) { _target.addEventListener("GDS__NONEXISTENT_EVENT", nullListener,false,0,false); } else { activeTweens[this] = true; } } } // public methods: /** * Invalidate forces the tween to repopulate all of the initial properties from the target object, and start playing if autoplay is set to true. * If the tween is currently playing, then it will also set the position to 0. For example, if you changed the x and y position of an object while * it was playing, you could call invalidate on it to force it to resume the tween with the new property values. **/ public function invalidate():void { invalid = true; if (_position > 0) { positionOffset = ticker.position-(_position = 0); } // ticker.interval if (autoPlay) { play(); } else if (_state == END) { _state = BEGINNING; } } /** * Reverses the tween by swapping its initial and destination properties. If the tween is playing (state = TWEEN_PHASE), it will also * reverse the tween position. *
* Note: calling reverse on a playing tween may result in unusual results with nonlinear tween functions. * * @param reverseChildren Indicates whether to call reverse on all child tweens. **/ public function reverse(reverseChildren:Boolean=true):void { var o:Object = destProperties; destProperties = initProperties; initProperties = o; invalid = false; if (_state == TWEEN_PHASE) { positionOffset = ticker.position-(_position = _duration-_position); } if (reverseChildren) { for (var n:Object in children) { (n as @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween).reverse(); } } if (autoPlay) { play(); } } /** * Shortcut method for setting multiple properties on the tween object quickly. This does not set destination values (ie. the value to tween to). * This method also provides you with a quick method for adding listeners to specific events, using the special properties: * activateListener, initListener, completeListener, progressListener, changeListener. *
* Example: This will set the duration, autoReverse, and nextTween properties of a tween, and add a listener for the complete event:
*myTween.setTweenProperties({duration:4, autoReverse:true, nextTween:anotherTween, completeListener:completeHandlerFunction});
**/ public function setTweenProperties(tweenProperties:Object):void { if (!tweenProperties) { return; } if ("duration" in tweenProperties) { // set duration first, because other properties (like position) may have dependencies. duration = tweenProperties.duration; delete(tweenProperties.duration); } if ("activateListener" in tweenProperties) { addEventListener(Event.ACTIVATE,tweenProperties.activateListener,false,0,true); delete(tweenProperties.activateListener); } if ("initListener" in tweenProperties) { addEventListener(Event.INIT,tweenProperties.initListener,false,0,true); delete(tweenProperties.initListener); } if ("completeListener" in tweenProperties) { addEventListener(Event.COMPLETE,tweenProperties.completeListener,false,0,true); delete(tweenProperties.completeListener); } if ("progressListener" in tweenProperties) { addEventListener(PROGRESS,tweenProperties.progressListener,false,0,true); delete(tweenProperties.progressListener); } if ("changeListener" in tweenProperties) { addEventListener(Event.CHANGE,tweenProperties.changeListener,false,0,true); delete(tweenProperties.changeListener); } for (var n:String in tweenProperties) { this[n] = tweenProperties[n]; } } /** * Allows you to tween objects that require re-assignment whenever they are modified by reassigning the target object to a specified property of another * object. For example, in order for changes to a colorTransform object to be visible, * it must be assigned back to the .transform.colorTransform property of a display object. To make this work, you would call * myTween.setAssignment(myDisplayObject.transform,"colorTransform"); * This will also cause @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween to retrieve the target each time it copies its initial values. *
* Note: this does not work with filters yet, as they must be assigned to an array first, and then to the filters property. Use @fileFilter instead. * * @param assignmentTarget The object to reassign the property on. * @param assignmentProperty The name of the property to reassign the target to. **/ public function setAssignment(assignmentTarget:Object=null, assignmentProperty:String=null):void { this.assignmentTarget = assignmentTarget; this.assignmentProperty = assignmentProperty; } /** * Sets the numeric destination value for a property on the target object that you would like to tween. * For example, if you wanted to tween to a new x position, you could use: my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.setProperty("x",400). Nonnumeric values are ignored. * * @param propertyName The name of the property to tween. * @param value The numeric destination value (the value to tween to). **/ public function setProperty(propertyName:String,value:Number):void { if (isNaN(value)) { return; } if (_state == END) { reset(); } destProperties[propertyName] = value; invalidate(); } /** * Returns the destination value for the specified property if one exists. * * @param propertyName The name of the property to return a destination value for. **/ public function getProperty(propertyName:String):Number { return destProperties[propertyName]; } /** * Removes a destination value from the tween. This prevents the @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance from tweening the property. * * @param propertyName The name of the destination property to delete. **/ public function deleteProperty(propertyName:String):Boolean { return delete(destProperties[propertyName]); } /** * Shorthand method for making multiple setProperty calls quickly. *
* Example: set x and y destination values:
*my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.setProperties({x:200, y:400});
* * @param props An object containing destination property values. **/ public function setProperties(properties:Object):void { if (!properties) { return; } for (var key:String in properties) { setProperty(key,properties[key]); } } /** * Adds a child tween. Child tweens are played in synch with their parent (ie. their position properties are synchronized). * By specifying true for synchDuration, you can also ensure that a child will keep its duration synchronized with its parent. * * @param child A @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance to add as a child tween. * @param synchDuration indicates whether the child tween's duration property should be kept in synch with the parent. Defaults to true. You may choose to set this to false if you have a shorter tween as a child, and want it to end sooner than its parent. **/ public function addChild(child:@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween,synchDuration:Boolean=true):void { if (!child) { return; } children[child] = synchDuration; child.paused = true; if (synchDuration) { child.duration = _duration; } } /** * Removes a child tween. * * @param child The child @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance to remove. **/ public function removeChild(child:@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween):void { delete(children[child]); } /** * Pauses the tween by stopping tick from being automatically called. This also releases the tween for garbage collection if * it is not referenced externally. **/ public function pause():void { paused = true; } /** * Plays a tween by incrementing the position property each frame. This also prevents the tween from being garbage collected while it is active. * This is achieved by way of two methods: * 1. If the target object is an IEventDispatcher, then the tween will subscribe to a dummy event using a hard reference. This allows * the tween to be garbage collected if its target is also collected, and there are no other external references to it. * 2. If the target object is not an IEventDispatcher, then the tween is placed in the activeTweens list, to prevent collection until it is paused or reaches the end of the transition). * Note that pausing all tweens via the @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.pauseAll static property will not free the tweens for collection. **/ public function play():void { paused = false; } /** * Jumps the tween to its beginning and pauses it. This sets all target properties to their init values, and sets the state to BEGINNING. **/ public function beginning():void { updateProperties(0); positionOffset = ticker.position-(_position = -_delay); for (var o:Object in children) { (o as @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween).beginning(); } _state = BEGINNING; pause(); } /** * Jumps the tween to its end. This is the same as setting position=duration, except it also provides you with the option to also end the nextTween (recursively). * This sets all target properties to their destination values, sets the state to END, and fires the COMPLETE event. **/ public function end(endNextTween:Boolean=true):void { position = _duration; if (endNextTween && nextTween) { nextTween.end(); } } /** * Resets the tween, pausing it, deleting all destination values, resetting the tween position to the beginning, and nulling the lastProgressPoint. * This will not change the target's current properties. **/ public function reset():void { _position = -_delay; _state = BEGINNING; pause(); initProperties = _lastProgressPoint = null; destProperties = {}; } /** * Adds a tween position at which to generate a progress event. You can use this to trigger other functionality at specific points in the tween. * The name is the string value that lastProgressPoint will be set to when the event is dispatched. *
* Example: This will generate a progress event and set the lastProgressPoint to "middle" half way through a 5 second tween: *my@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.addProgressPoint(2.5, "middle");
* * @param position The position at which to dispatch a progress event. * @param data The name that will be set to lastProgressPoint when this progress point is reached. **/ public function addProgressPoint(position:Number,data:*):void { removeProgressPoint(position); progressPoints.push(new ProgressPoint(position, data)); progressPoints.sortOn("position",Array.NUMERIC); } /** * Removes the progress point at the specified position. * * @param position The position of the progress point to remove. **/ public function removeProgressPoint(position:Number):void { for (var i:int=progressPoints.length-1; i>=0; i--) { if (progressPoints[i].position == position) { progressPoints.splice(i,1); break; } } } /** * Creates a clone of the @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween instance. You can optionally specify a different target for the tween, * and indicate whether to preserve the state (position and paused properties) of the tween. * * @param target The target property for the new tween. If null, it will use the target of the tween that is being cloned. * @param preserveChildren Indicates whether to copy this instance's children to the new instance. Defaults to false. * @param preserveState Indicates whether the position and paused properties should be cloned, or if the new tween should start at position 0, with paused dependent on autoPlay. Defaults to false. **/ public function clone(target:Object=null, preserveChildren:Boolean=false, preserveState:Boolean=false):@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween { if (target == null) { target = this.target; } var tween:@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween = new @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween(target, duration, destProperties, {assignmentProperty:assignmentProperty, assignmentTarget:assignmentTarget, autoHide:autoHide, autoPlay:autoPlay, autoReverse:autoReverse, delay:delay, nextTween:nextTween, ease:ease, useSmartRotation:useSmartRotation }); for (var o:Object in progressPoints) { tween.addProgressPoint(o.position, o.data); } if (preserveChildren) { for (o in children) { tween.addChild(o as @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween,children[o]); } } if (preserveState) { tween.position = position; tween.paused = paused; } return tween; } // overidden for optimization purposes. /** @private **/ override public function dispatchEvent(evt:Event):Boolean { // this is a lot more efficient for @files that don't have listeners for a particular event type. if (hasEventListener(evt.type)) { return super.dispatchEvent(evt); } return true; } // private methods: // tick event handler. /** @private **/ protected function handleTick(evt:Event):void { if (@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween.pauseAll) { positionOffset = ticker.position-_position; return; } position = ticker.position - positionOffset; } // called when the tween ends. /** @private **/ protected function endTransition():void { _state = END; paused = true; dispatchEvent(new Event(Event.COMPLETE)); if (autoReverse) { reverse(); } if (nextTween) { nextTween.play(); } } // called when the tween moves from the DELAY_PHASE state to TWEEN_PHASE /** @private **/ protected function init():void { _state = TWEEN_PHASE; copyInitProperties(); dispatchEvent(new Event(Event.INIT)); } // called when the tween first starts playing: /** @private **/ protected function activate():void { _state = (_position < 0) ? DELAY_PHASE : TWEEN_PHASE; dispatchEvent(new Event(Event.ACTIVATE)); if (_position >= 0) { init(); } } // logic that runs each frame. Calculates position, updates properties, synchs children, handles events, etc. /** @private **/ protected function update():void { if (_state == BEGINNING || _state == END) { activate(); } if (_position < 0) { return; } // handle state: if (_state == DELAY_PHASE) { init(); } else if (_state == TWEEN_PHASE && invalid) { copyInitProperties(); } var f:Function = (ease == null) ? linearEase : ease; var value:Number = f(_position/_duration, 0, 1, 1); updateProperties(value); if (hasAlphaAndVisible && _autoHide) { _target.visible = (_target.alpha > 0); } for (var o:Object in children) { (o as @ax-lib-flex-animation-code-10-com-gskinner-motion-GTween).position = _position; } dispatchEvent(new Event(Event.CHANGE)); checkProgressPoint(); if (_position >= _duration) { endTransition(); } } // iterates all of the active properties and updates their values on the target. /** @private **/ protected function updateProperties(value:Number):void { var sizeSet:Boolean = false; var round:Boolean = roundValues; for (var n:String in destProperties) { if (hasSetSize && !sizeSet && (n == "width" || n == "height")) { sizeSet = true; var w:Number = (destProperties["width"] == null) ? _target.width : initProperties["width"]+(destProperties["width"]-initProperties["width"])*value; var h:Number = (destProperties["height"] == null) ? _target.height : initProperties["height"]+(destProperties["height"]-initProperties["height"])*value; _target["setSize"]( round ? Math.round(w) : w , round ? Math.round(h) : h); } else { var val:Number = initProperties[n]+(destProperties[n]-initProperties[n])*value; _target[n] = round ? Math.round(val) : val; } } if (assignmentTarget && assignmentProperty) { assignmentTarget[assignmentProperty] = _target; } } // determines the current progress point and fires a progress event if it has changed. /** @private **/ protected function checkProgressPoint():void { var obj:ProgressPoint = null; for (var i:uint=0; i_position) { break; } obj = progressPoints[i] as ProgressPoint; } if (obj != null && obj != _lastProgressPoint) { _lastProgressPoint = obj; dispatchEvent(new Event(PROGRESS)); } } // copies the initial target properties into the local store. /** @private **/ protected function copyInitProperties():void { if (!invalid) { return; } if (assignmentTarget && assignmentProperty) { _target = assignmentTarget[assignmentProperty]; } initProperties = {}; for (var n:String in destProperties) { if (useSmartRotation && n == "rotation") { var tr:Number = destProperties["rotation"] %360; var r:Number = initProperties["rotation"] = _target[n] %360; tr += (Math.abs(tr-r) < 180) ? 0 : (tr>r) ? -360 : 360; destProperties[n] = tr; } else { initProperties[n] = _target[n]; } } invalid = false; } // default tween function. /** @private **/ protected function linearEase(value:Number, ...args:Array):Number { return value; } // this is used as a listener for GC reasons. /** @private **/ protected function nullListener(evt:Event):void { } } } import flash.utils.Proxy; import flash.utils.flash_proxy; import com.gskinner.motion.@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween; dynamic class TargetProxy extends Proxy { private var gTween:@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween; public function TargetProxy(gTween:@ax-lib-flex-animation-code-10-com-gskinner-motion-GTween):void { this.gTween = gTween; } // proxy methods: flash_proxy override function callProperty(methodName:*, ...args:Array):* { gTween.target[methodName].apply(null,args); } flash_proxy override function getProperty(prop:*):* { var value:Number = gTween.getProperty(prop); return (isNaN(value)) ? gTween.target[prop] : value; } flash_proxy override function setProperty(prop:*,value:*):void { if (isNaN(value)) { gTween.target[prop] = value; } else { gTween.setProperty(String(prop), Number(value)); } } flash_proxy override function deleteProperty(prop:*):Boolean { return gTween.deleteProperty(prop); } } class ProgressPoint { public var position:Number; public var data:*; public function ProgressPoint(position:Number, data:*):void { this.position = position; this.data = data; } } import flash.events.IEventDispatcher; interface ITicker extends IEventDispatcher { function get position():Number; function get interval():Number; } import flash.utils.getTimer; import flash.utils.Timer; import flash.events.EventDispatcher; import flash.events.Event; import flash.events.TimerEvent; class TimeTicker extends EventDispatcher implements ITicker { protected var timer:Timer; public function TimeTicker():void { timer = new Timer(20); timer.start(); timer.addEventListener(TimerEvent.TIMER,tick); } public function get position():Number { return getTimer()/1000; } public function get interval():Number { return timer.delay/1000; } public function set interval(value:Number):void { timer.delay = value*1000; } protected function tick(evt:TimerEvent):void { dispatchEvent(new Event("tick")); evt.updateAfterEvent(); } } import flash.display.Shape; class FrameTicker extends EventDispatcher implements ITicker { protected var shape:Shape; protected var _position:Number=0; public function FrameTicker():void { shape = new Shape() shape.addEventListener(Event.ENTER_FRAME,tick); } public function get interval():Number { return 1; } public function get position():Number { return _position; } protected function tick(evt:Event):void { _position++; dispatchEvent(new Event("tick")); } } class HybridTicker extends EventDispatcher implements ITicker { protected var shape:Shape; public function HybridTicker():void { shape = new Shape() shape.addEventListener(Event.ENTER_FRAME,tick); } public function get position():Number { return getTimer()/1000; } public function get interval():Number { return 1; } protected function tick(evt:Event):void { dispatchEvent(new Event("tick")); }}
[]readme course(s) prefaceI 1 2II 3 4III 5 6 7IV 8 9 10V 11 12 afterthought(s)appendix reference(s) example(s)resource(s) _![]()
(C) Æliens 18/6/2009
You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.