00001 import mx.utils.Delegate;
00002
00003 import flash.geom.Point;
00004 import flash.geom.Rectangle;
00005
00006 import gugga.animations.AnimationSubjectCacheAsBitmapPolicy;
00007 import gugga.animations.IAnimation;
00008 import gugga.animations.MaskAnimationTypes;
00009 import gugga.animations.MotionDirections;
00010 import gugga.animations.MotionTypes;
00011 import gugga.animations.PropertiesTweenAnimation;
00012 import gugga.animations.PropertiesTweenAnimationType;
00013 import gugga.events.EventDispatcher;
00014 import gugga.utils.DoLaterUtil;
00015 import gugga.utils.EventRethrower;
00016
00020 class gugga.animations.ScrollRectAnimation extends EventDispatcher implements IAnimation
00021 {
00022
00023
00024 private var mIsInterupting : Boolean = false;
00025
00026 private var mType : MaskAnimationTypes;
00027 private var mDirection : MotionDirections;
00028 private var mMotionType : MotionTypes;
00029
00030 private var mSubjectInitialVisible : Boolean;
00031 private var mSubjectInitialPosition : Point;
00032 private var mAnimationRect : Rectangle;
00033
00034 private var mScrollRect : Rectangle;
00035 private var mTweenAnimation : PropertiesTweenAnimation;
00036
00037 private var mSubject : MovieClip;
00038 public function get Subject() : MovieClip { return mSubject; }
00039 public function set Subject(aValue:MovieClip) : Void { mSubject = aValue; }
00040
00041 public function get EasingEquation() : Function
00042 {
00043 return mTweenAnimation.EasingEquation;
00044 }
00045 public function set EasingEquation(aValue:Function) : Void
00046 {
00047 mTweenAnimation.EasingEquation = aValue;
00048 }
00049
00050
00051 public function get TweenTime() : Number
00052 {
00053 return mTweenAnimation.TweenTime;
00054 }
00055 public function set TweenTime(aValue:Number) : Void
00056 {
00057 mTweenAnimation.TweenTime = aValue;
00058 }
00059
00060 public function get TweenType() : PropertiesTweenAnimationType
00061 {
00062 return mTweenAnimation.TweenType;
00063 }
00064 public function set TweenType(aValue:PropertiesTweenAnimationType) : Void
00065 {
00066 mTweenAnimation.TweenType = aValue;
00067 }
00068
00069 public function get SubjectCacheAsBitmapPolicy() : AnimationSubjectCacheAsBitmapPolicy
00070 {
00071 return mTweenAnimation.SubjectCacheAsBitmapPolicy;
00072 }
00073 public function set SubjectCacheAsBitmapPolicy(aValue:AnimationSubjectCacheAsBitmapPolicy) : Void
00074 {
00075 mTweenAnimation.SubjectCacheAsBitmapPolicy = aValue;
00076 }
00077
00078
00079 private function ScrollRectAnimation(aSubject : MovieClip, aType : MaskAnimationTypes,
00080 aDirection : MotionDirections, aMotionType : MotionTypes)
00081 {
00082 super();
00083
00084 mSubject = aSubject;
00085 mType = aType;
00086 mDirection = aDirection;
00087 mMotionType = aMotionType;
00088
00089 mTweenAnimation = new PropertiesTweenAnimation();
00090 mTweenAnimation.TweenUpdateDelegate = Delegate.create(this, onTweenUpdated);
00091 mTweenAnimation.addEventListener("completed", Delegate.create(this, onTweenAnimationCompleted));
00092
00093
00094 SubjectCacheAsBitmapPolicy = AnimationSubjectCacheAsBitmapPolicy.ForceTrueWhileAnimating;
00095 }
00096
00097 public function addCuePoint(aPosition : Number, aEventName : String) : Void
00098 {
00099 mTweenAnimation.addCuePoint(aPosition, aEventName);
00100 EventRethrower.create(this, mTweenAnimation, aEventName);
00101
00102 }
00103
00104 public function setBoundsAnimationRect() : Void
00105 {
00106 var subjectBounds : Object = mSubject.getBounds(mSubject);
00107 mAnimationRect = new Rectangle(
00108 subjectBounds["xMin"],
00109 subjectBounds["yMin"],
00110 subjectBounds["xMax"] - subjectBounds["xMin"],
00111 subjectBounds["yMax"] - subjectBounds["yMin"]
00112 );
00113 }
00114
00115 public function setNaturalAnimationRect() : Void
00116 {
00117 mAnimationRect = new Rectangle(
00118 0,
00119 0,
00120 mSubject._width,
00121 mSubject._height
00122 );
00123 }
00124
00125 public function setCustomAnimationRect(aRect : Rectangle) : Void
00126 {
00127 mAnimationRect = aRect.clone();
00128 }
00129
00130 public function start() : Void
00131 {
00132 mIsInterupting = false;
00133
00134 dispatchEvent({type: "start", target: this});
00135
00136 mSubjectInitialPosition = new Point(mSubject._x, mSubject._y);
00137
00138 if(!mAnimationRect)
00139 {
00140 setNaturalAnimationRect();
00141 }
00142
00143 mScrollRect = getStartingScrollRect();
00144 mTweenAnimation.Subject = mScrollRect;
00145 mSubject.scrollRect = mScrollRect;
00146
00147
00148 mSubject._visible = true;
00149
00150 mSubjectInitialVisible = mSubject._visible;
00151
00152 var targetScrollRect : Rectangle = getTargetScrollRect();
00153
00154 mTweenAnimation.TweeningProprties = ["x", "y", "width", "height"];
00155 mTweenAnimation.TweenToValues =
00156 [targetScrollRect.x, targetScrollRect.y, targetScrollRect.width, targetScrollRect.height];
00157
00158 mSubject._y = mSubjectInitialPosition.y + mAnimationRect.y;
00159 mSubject._x = mSubjectInitialPosition.x + mAnimationRect.x;
00160
00161 mTweenAnimation.start();
00162 }
00163
00164 private function getStartingScrollRect() : Rectangle
00165 {
00166 var result : Rectangle = mAnimationRect.clone();
00167
00168 if(mMotionType == MotionTypes.In)
00169 {
00170 result = transformRectByAnimationTypeAndDirection(result);
00171 }
00172
00173 return result;
00174 }
00175
00176 private function getTargetScrollRect() : Rectangle
00177 {
00178 var result : Rectangle = mAnimationRect.clone();
00179
00180 if(mMotionType == MotionTypes.Out)
00181 {
00182 result = transformRectByAnimationTypeAndDirection(result);
00183 }
00184
00185 return result;
00186 }
00187
00188 private function transformRectByAnimationTypeAndDirection(aRect : Rectangle) : Rectangle
00189 {
00190 var direction : MotionDirections;
00191
00192 if(mType == MaskAnimationTypes.Fly)
00193 {
00194 direction = mDirection;
00195 }
00196 else
00197 {
00198 direction = invertDirection(mDirection);
00199 }
00200
00201 if (direction != MotionDirections.Up &&
00202 direction != MotionDirections.Down)
00203 {
00204 aRect.width = 0;
00205 }
00206
00207 if (direction != MotionDirections.Left &&
00208 direction != MotionDirections.Right)
00209 {
00210 aRect.height = 0;
00211 }
00212
00213 if (direction == MotionDirections.Up ||
00214 direction == MotionDirections.UpLeft ||
00215 direction == MotionDirections.UpRight)
00216 {
00217 aRect.y = mAnimationRect.y + mAnimationRect.height;
00218 }
00219
00220 if (direction == MotionDirections.Left ||
00221 direction == MotionDirections.UpLeft ||
00222 direction == MotionDirections.DownLeft)
00223 {
00224 aRect.x = mAnimationRect.x + mAnimationRect.width;
00225 }
00226
00227 return aRect;
00228 }
00229
00230 private function invertDirection(aDirection : MotionDirections) : MotionDirections
00231 {
00232 switch(aDirection)
00233 {
00234 case MotionDirections.Left:
00235 return MotionDirections.Right;
00236 case MotionDirections.Right:
00237 return MotionDirections.Left;
00238 case MotionDirections.Down:
00239 return MotionDirections.Up;
00240 case MotionDirections.DownLeft:
00241 return MotionDirections.UpRight;
00242 case MotionDirections.DownRight:
00243 return MotionDirections.UpLeft;
00244 case MotionDirections.Up:
00245 return MotionDirections.Down;
00246 case MotionDirections.UpRight:
00247 return MotionDirections.DownLeft;
00248 case MotionDirections.UpLeft:
00249 return MotionDirections.DownRight;
00250 }
00251 }
00252
00253 public function isRunning() : Boolean
00254 {
00255 return mTweenAnimation.isRunning();
00256 }
00257
00258 public function isImmediatelyInterruptable() : Boolean
00259 {
00260 return true;
00261 }
00262
00263 public function interrupt() : Void
00264 {
00265 mIsInterupting = true;
00266
00267 mTweenAnimation.interrupt();
00268 dispose();
00269
00270
00271
00272
00273
00274
00275
00276 DoLaterUtil.doLater(this, interrupted, null, 1);
00277 }
00278
00279 private function interrupted() : Void
00280 {
00281
00282
00283
00284
00285
00286
00287 mIsInterupting = false;
00288 dispatchEvent({type: "interrupted", target: this});
00289 }
00290
00291 private function onTweenUpdated(ev) : Void
00292 {
00293 mScrollRect.x = Math.round(mScrollRect.x);
00294 mScrollRect.y = Math.round(mScrollRect.y);
00295 mScrollRect.width = Math.round(mScrollRect.width);
00296 mScrollRect.height = Math.round(mScrollRect.height);
00297
00298 mSubject.scrollRect = mScrollRect;
00299
00300 if (mDirection == MotionDirections.Down ||
00301 mDirection == MotionDirections.DownLeft ||
00302 mDirection == MotionDirections.DownRight)
00303 {
00304 if(mType == MaskAnimationTypes.Wipe)
00305 {
00306 mSubject._y = mSubjectInitialPosition.y + mScrollRect.y;
00307 }
00308 else
00309 {
00310 mSubject._y = mSubjectInitialPosition.y +
00311 mAnimationRect.y + mAnimationRect.height - mScrollRect.height;
00312 }
00313 }
00314
00315 if (mDirection == MotionDirections.Right ||
00316 mDirection == MotionDirections.UpRight ||
00317 mDirection == MotionDirections.DownRight)
00318 {
00319 if(mType == MaskAnimationTypes.Wipe)
00320 {
00321 mSubject._x = mSubjectInitialPosition.x + mScrollRect.x;
00322 }
00323 else
00324 {
00325 mSubject._x = mSubjectInitialPosition.x +
00326 mAnimationRect.x + mAnimationRect.width - mScrollRect.width;
00327 }
00328 }
00329 }
00330
00331 private function onTweenAnimationCompleted() : Void
00332 {
00333 dispose();
00334
00335 if(mMotionType == MotionTypes.Out)
00336 {
00337 mSubject._visible = false;
00338 DoLaterUtil.doLater(this, completed, null, 1);
00339 }
00340 else
00341 {
00342 completed();
00343 }
00344 }
00345
00346 private function completed() : Void
00347 {
00348 if(mMotionType == MotionTypes.Out)
00349 {
00350 mSubject._visible = mSubjectInitialVisible;
00351 }
00352
00353 dispatchEvent({type: "completed", target: this});
00354 }
00355
00356 private function dispose() : Void
00357 {
00358 mSubject._y = mSubjectInitialPosition.y;
00359 mSubject._x = mSubjectInitialPosition.x;
00360
00361
00362
00363 mSubject.scrollRect = null;
00364 }
00365
00366
00367
00368 public static function createWipeInFrameAnimation(aDirection : MotionDirections,
00369 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00370 {
00371 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Wipe,
00372 aDirection, MotionTypes.In);
00373
00374 result.TweenType = PropertiesTweenAnimationType.FrameTween;
00375 applyAdditionalProperties(result, aDuration, aEasingType);
00376
00377 return result;
00378 }
00379
00380 public static function createWipeOutFrameAnimation(aDirection : MotionDirections,
00381 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00382 {
00383 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Wipe,
00384 aDirection, MotionTypes.Out);
00385
00386 result.TweenType = PropertiesTweenAnimationType.FrameTween;
00387 applyAdditionalProperties(result, aDuration, aEasingType);
00388
00389 return result;
00390 }
00391
00392 public static function createFlyInFrameAnimation(aDirection : MotionDirections,
00393 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00394 {
00395 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Fly,
00396 aDirection, MotionTypes.In);
00397
00398 result.TweenType = PropertiesTweenAnimationType.FrameTween;
00399 applyAdditionalProperties(result, aDuration, aEasingType);
00400
00401 return result;
00402 }
00403
00404 public static function createFlyOutFrameAnimation(aDirection : MotionDirections,
00405 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00406 {
00407 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Fly,
00408 aDirection, MotionTypes.Out);
00409
00410 result.TweenType = PropertiesTweenAnimationType.FrameTween;
00411 applyAdditionalProperties(result, aDuration, aEasingType);
00412
00413 return result;
00414 }
00415
00416 public static function createWipeInTimeAnimation(aDirection : MotionDirections,
00417 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00418 {
00419 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Wipe,
00420 aDirection, MotionTypes.In);
00421
00422 result.TweenType = PropertiesTweenAnimationType.TimeTween;
00423 applyAdditionalProperties(result, aDuration, aEasingType);
00424
00425 return result;
00426 }
00427
00428 public static function createWipeOutTimeAnimation(aDirection : MotionDirections,
00429 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00430 {
00431 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Wipe,
00432 aDirection, MotionTypes.Out);
00433
00434 result.TweenType = PropertiesTweenAnimationType.TimeTween;
00435 applyAdditionalProperties(result, aDuration, aEasingType);
00436
00437 return result;
00438 }
00439
00440 public static function createFlyInTimeAnimation(aDirection : MotionDirections,
00441 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00442 {
00443 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Fly,
00444 aDirection, MotionTypes.In);
00445
00446 result.TweenType = PropertiesTweenAnimationType.TimeTween;
00447 applyAdditionalProperties(result, aDuration, aEasingType);
00448
00449 return result;
00450 }
00451
00452 public static function createFlyOutTimeAnimation(aDirection : MotionDirections,
00453 aTarget : MovieClip, aDuration : Number, aEasingType : Function) : ScrollRectAnimation
00454 {
00455 var result : ScrollRectAnimation = new ScrollRectAnimation(aTarget, MaskAnimationTypes.Fly,
00456 aDirection, MotionTypes.Out);
00457
00458 result.TweenType = PropertiesTweenAnimationType.TimeTween;
00459 applyAdditionalProperties(result, aDuration, aEasingType);
00460
00461 return result;
00462 }
00463
00464 private static function applyAdditionalProperties(aAnimation : ScrollRectAnimation, aDuration : Number,
00465 aEasingType : Function) : Void
00466 {
00467 if(aDuration)
00468 {
00469 aAnimation.TweenTime = aDuration;
00470 }
00471
00472 if(aEasingType)
00473 {
00474 aAnimation.EasingEquation = aEasingType;
00475 }
00476 }
00477 }