/** * VERSION: 1.03 * DATE: 2011-10-05 * AS2 * UPDATES AND DOCS AT: http://www.greensock.com **/ import com.greensock.TweenLite; import com.greensock.core.SimpleTimeline; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.helpers.PhysicsProp; /** * Sometimes you want to tween a property (or several) but you don't have a specific end value in mind - instead, * you'd rather describe the movement in terms of physics concepts, like velocity, acceleration, * and/or friction. PhysicsPropsPlugin allows you to tween any numeric property of any object based * on these concepts. Keep in mind that any easing equation you define for your tween will be completely * ignored for these properties. Instead, the physics parameters will determine the movement/easing. * These parameters, by the way, are not intended to be dynamically updateable, but one unique convenience * is that everything is reverseable. So if you create several physics-based tweens, for example, and * throw them into a TimelineLite, you could simply call reverse() on the timeline to watch the objects * retrace their steps right back to the beginning. Here are the parameters you can define (note that * friction and acceleration are both completely optional): *
* * * USAGE:

* * import com.greensock.TweenLite;
* import com.greensock.plugins.TweenPlugin;
* import com.greensock.plugins.PhysicsPropsPlugin;
* TweenPlugin.activate([PhysicsPropsPlugin]); //activation is permanent in the SWF, so this line only needs to be run once.

* * TweenLite.to(mc, 2, {physicsProps:{
* _x:{velocity:100, acceleration:200},
* _y:{velocity:-200, friction:0.1}
* }
* });

*
* * PhysicsPropsPlugin is a Club GreenSock membership benefit. You must have a valid membership to use this class * without violating the terms of use. Visit http://blog.greensock.com/club/ to sign up or get more details.

* * Copyright 2011, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. * * @author Jack Doyle, jack@greensock.com */ class com.greensock.plugins.PhysicsPropsPlugin extends TweenPlugin { /** @private **/ public static var API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility /** @private **/ private var _tween:TweenLite; /** @private **/ private var _target:Object; /** @private **/ private var _props:Array; /** @private **/ private var _hasFriction:Boolean; /** @private **/ private var _runBackwards:Boolean; /** @private **/ private var _step:Number; /** @private for tweens with friction, we need to iterate through steps. frames-based tweens will iterate once per frame, and seconds-based tweens will iterate 30 times per second. **/ private var _stepsPerTimeUnit:Number; /** @private **/ public function PhysicsPropsPlugin() { super(); this.propName = "physicsProps"; //name of the special property that the plugin should intercept/manage this.overwriteProps = []; _stepsPerTimeUnit = 30; //default } /** @private **/ public function onInitTween(target:Object, value:Object, tween:TweenLite):Boolean { _target = target; _tween = tween; _runBackwards = Boolean(_tween.vars.runBackwards == true); _step = 0; var tl:SimpleTimeline = _tween.timeline; while (tl.timeline) { tl = tl.timeline; } if (tl == TweenLite.rootFramesTimeline) { //indicates the tween uses frames instead of seconds. _stepsPerTimeUnit = 1; } _props = []; var p:String, curProp:Object, cnt:Number = 0; for (p in value) { curProp = value[p]; if (curProp.velocity || curProp.acceleration) { _props[cnt++] = new PhysicsProp(p, Number(target[p]), curProp.velocity, curProp.acceleration, curProp.friction, _stepsPerTimeUnit); this.overwriteProps[cnt] = p; if (curProp.friction) { _hasFriction = true; } } } return true; } /** @private **/ public function killProps(lookup:Object):Void { var i:Number = _props.length; while (i--) { if (lookup[_props[i].property] != undefined) { _props.splice(i, 1); } } super.killProps(lookup); } /** @private **/ public function set changeFactor(n:Number):Void { var i:Number = _props.length, time:Number = _tween.cachedTime, values:Array = [], curProp:PhysicsProp; if (_runBackwards == true) { time = _tween.cachedDuration - time; } if (_hasFriction) { var steps:Number = Math.floor(time * _stepsPerTimeUnit) - _step; var remainder:Number = ((time * _stepsPerTimeUnit) % 1); var j:Number; if (steps >= 0) { //going forward while (i--) { curProp = _props[i]; j = steps; while (j--) { curProp.v += curProp.a; curProp.v *= curProp.friction; curProp.value += curProp.v; } values[i] = curProp.value + (curProp.v * remainder); } } else { //going backwards while (i--) { curProp = _props[i]; j = -steps; while (j--) { curProp.value -= curProp.v; curProp.v /= curProp.friction; curProp.v -= curProp.a; } values[i] = curProp.value + (curProp.v * remainder); } } _step += steps; } else { var tt:Number = time * time * 0.5; while (i--) { curProp = _props[i]; values[i] = curProp.start + ((curProp.velocity * time) + (curProp.acceleration * tt)); } } i = _props.length; if (!this.round) { while (i--) { _target[PhysicsProp(_props[i]).property] = Number(values[i]); } } else { while (i--) { _target[_props[i].property] = Math.round(values[i]); } } } }