Page 1 of 1

Module - Animation & Motion tween FX

Posted: Sun Oct 18, 2015 4:55 pm
by eddy

Code: Select all

;:=============================================================================
;:- Tween.pbi
;:- Author          : Eddy
;:- Date            : October 11, 2015
;:- Compiler        : PureBasic 5.40 LTS
;:- Target OS       : Windows,Linux,Mac
;:- Source --------------------------------------------------------------------
;:- http://www.purebasic.fr/english/viewtopic.php?f=40&t=56092
;:- Credit --------------------------------------------------------------------
;:- Robert Penner - The easing equations we all know and love
;:- (http://robertpenner.com/easing/) [See License.txt for license info]
;:-
;:- Lee Brimelow - initial port of Penner's equations to WPF
;:- (http://thewpfblog.com/?p=12)
;:-
;:- Zeh Fernando - additional equations (out/in) from
;:- caurina.transitions.Tweener (http://code.google.com/p/tweener/)
;:- [See License.txt for license info]
;:-
;:- https://github.com/kikito/tween.lua/blob/master/tween.lua
;:=============================================================================

; *********************
; ANIMATION & MOTION TWEEN
; *********************

DeclareModule Tween
   Enumeration
      ;Tween FX list
      #FX_Linear=0
      
      #FX_ExpoEaseOut
      #FX_ExpoEaseIn
      #FX_ExpoEaseInOut
      #FX_ExpoEaseOutIn
      
      #FX_QuadEaseOut
      #FX_QuadEaseIn
      #FX_QuadEaseInOut
      #FX_QuadEaseOutIn
      
      #FX_CubicEaseOut
      #FX_CubicEaseIn
      #FX_CubicEaseInOut
      #FX_CubicEaseOutIn
      
      #FX_QuartEaseOut
      #FX_QuartEaseIn
      #FX_QuartEaseInOut
      #FX_QuartEaseOutIn
      
      #FX_QuintEaseOut
      #FX_QuintEaseIn
      #FX_QuintEaseInOut
      #FX_QuintEaseOutIn
      
      #FX_CircEaseOut
      #FX_CircEaseIn
      #FX_CircEaseInOut
      #FX_CircEaseOutIn
      
      #FX_SineEaseOut
      #FX_SineEaseIn
      #FX_SineEaseInOut
      #FX_SineEaseOutIn
      
      #FX_ElasticEaseOut
      #FX_ElasticEaseIn
      #FX_ElasticEaseInOut
      #FX_ElasticEaseOutIn
      
      #FX_BounceEaseOut
      #FX_BounceEaseIn
      #FX_BounceEaseInOut
      #FX_BounceEaseOutIn
      
      #FX_BackEaseOut
      #FX_BackEaseIn
      #FX_BackEaseInOut
      #FX_BackEaseOutIn      
      
      #TWEEN_CountFX=#PB_Compiler_EnumerationValue-1       ;Count Tween FXs
      #TWEEN_FastTweenValues=2048                          ;Determines FastTween Accuracy
   EndEnumeration
   EnumerationBinary
      #TWEEN_PingPong
      #TWEEN_AutoDestroy
   EndEnumeration
   
   Declare.f Linear(Fraction.f)
   
   Declare.f QuadEaseOut(Fraction.f)
   Declare.f QuadEaseIn(Fraction.f)
   Declare.f QuadEaseInOut(Fraction.f)
   Declare.f QuadEaseOutIn(Fraction.f)
   
   Declare.f ExpoEaseOut(Fraction.f)
   Declare.f ExpoEaseIn(Fraction.f)
   Declare.f ExpoEaseInOut(Fraction.f)
   Declare.f ExpoEaseOutIn(Fraction.f)
   
   Declare.f CubicEaseOut(Fraction.f)
   Declare.f CubicEaseIn(Fraction.f)
   Declare.f CubicEaseInOut(Fraction.f)
   Declare.f CubicEaseOutIn(Fraction.f)
   
   Declare.f QuartEaseOut(Fraction.f)
   Declare.f QuartEaseIn(Fraction.f)
   Declare.f QuartEaseInOut(Fraction.f)
   Declare.f QuartEaseOutIn(Fraction.f)
   
   Declare.f QuintEaseOut(Fraction.f)
   Declare.f QuintEaseIn(Fraction.f)
   Declare.f QuintEaseInOut(Fraction.f)
   Declare.f QuintEaseOutIn(Fraction.f)
   
   Declare.f CircEaseOut(Fraction.f)
   Declare.f CircEaseIn(Fraction.f)
   Declare.f CircEaseInOut(Fraction.f)
   Declare.f CircEaseOutIn(Fraction.f)
   
   Declare.f SineEaseOut(Fraction.f)
   Declare.f SineEaseIn(Fraction.f)
   Declare.f SineEaseInOut(Fraction.f)
   Declare.f SineEaseOutIn(Fraction.f)
   
   Declare.f ElasticEaseOut(Fraction.f)
   Declare.f ElasticEaseIn(Fraction.f)
   Declare.f ElasticEaseInOut(Fraction.f)
   Declare.f ElasticEaseOutIn(Fraction.f)
   
   Declare.f BounceEaseOut(Fraction.f)
   Declare.f BounceEaseIn(Fraction.f)
   Declare.f BounceEaseInOut(Fraction.f)
   Declare.f BounceEaseOutIn(Fraction.f)
   
   Declare.f BackEaseOut(Fraction.f)
   Declare.f BackEaseIn(Fraction.f)
   Declare.f BackEaseInOut(Fraction.f)
   Declare.f BackEaseOutIn(Fraction.f)
   
   Declare.f FractionTimer(ExecutionTime, IsPingPong=#False, Duration=1000, LoopDuration=0)
   
   Declare.f TweenRelativeValue(FX, Fraction.f)
   Macro TweenValue(FX, StartValue, ProgressValue, Fraction)
      (StartValue + ProgressValue * TweenRelativeValue(FX, Fraction))
   EndMacro
   Macro TweenValueFromTo(FX, FromValue, ToValue, Fraction)
      (FromValue + (ToValue-FromValue) * TweenRelativeValue(FX, Fraction))
   EndMacro
   Global Dim FastTweenRelativeValue.f(#TWEEN_CountFX, #TWEEN_FastTweenValues)
   Macro FastTweenValue(FX, StartValue, ProgressValue, Fraction)
      (StartValue + ProgressValue * FastTweenRelativeValue(FX, Int(#TWEEN_FastTweenValues * Fraction)))
   EndMacro
   Macro FastTweenValueFromTo(FX, FromValue, ToValue, Fraction)
      (FromValue + (ToValue-FromValue) * FastTweenRelativeValue(FX, Int(#TWEEN_FastTweenValues * Fraction)))
   EndMacro
   
   Declare.i InitTween()
   Declare.i CreateTween(FX, StartValue, ProgressValue, LoopCount=0, Duration=1000, Delay=0, Flags=0)
   Declare.i PauseTween(Tween, Paused=#True)
   Declare.i TweenFX(Tween)
   Declare.i TweenPauseTime(Tween)
   Declare.i TweenStartTime(Tween)
   Declare.i TweenEndTime(Tween)
   Declare.i TweenExecutionTime(Tween)
   Declare.i TweenDuration(Tween)
   Declare.i TweenLoopCount(Tween)
EndDeclareModule

Module Tween
   EnableExplicit
   
   ;{ FX Linear
   
   ; Easing equation function for a simple linear tweening, with no easing.
   Procedure.f Linear(Fraction.f)
      ProcedureReturn Fraction
   EndProcedure
   
   ;} endregion
   
   ;{ FX Expo
   
   ; Easing equation function for an exponential (2^t) easing out:
   ; decelerating from zero velocity.
   Procedure.f ExpoEaseOut(Fraction.f)
      If Fraction=1 : ProcedureReturn 1 : Else : ProcedureReturn (-Pow(2, -10 * Fraction) + 1) : EndIf
   EndProcedure
   
   ; Easing equation function for an exponential (2^t) easing in:
   ; accelerating from zero velocity.
   Procedure.f ExpoEaseIn(Fraction.f)
      If Fraction=0 : ProcedureReturn 0 : Else : ProcedureReturn Pow(2, 10 * (Fraction-1)) : EndIf
   EndProcedure
   
   ; Easing equation function for an exponential (2^t) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f ExpoEaseInOut(Fraction.f)
      If (Fraction=0)
         ProcedureReturn 0
      ElseIf (Fraction=1)
         ProcedureReturn 1
      EndIf
      
      Fraction * 2
      If (Fraction<1)
         ProcedureReturn 0.5 * Pow(2, 10 * (Fraction - 1))
      Else
         ProcedureReturn 0.5 * (-Pow(2, -10 * (Fraction - 1)) + 2)
      EndIf
   EndProcedure
   
   ; Easing equation function for an exponential (2^t) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f ExpoEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5 * ExpoEaseOut(2*Fraction)
      Else
         ProcedureReturn 0.5 + 0.5 * ExpoEaseIn(2*Fraction - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Quad
   
   ; Easing equation function for a quadratic (t^2) easing out:
   ; decelerating from zero velocity.
   Procedure.f QuadEaseOut(Fraction.f)
      ProcedureReturn -Fraction * (Fraction - 2)
   EndProcedure
   
   ; Easing equation function for a quadratic (t^2) easing in:
   ; accelerating from zero velocity.
   Procedure.f QuadEaseIn(Fraction.f)
      ProcedureReturn Fraction * Fraction
   EndProcedure
   
   ; Easing equation function for a quadratic (t^2) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f QuadEaseInOut(Fraction.f)
      Fraction * 2
      If (Fraction<1)
         ProcedureReturn 0.5 * Fraction * Fraction
      Else
         Fraction-1
         ProcedureReturn -0.5 * (Fraction * (Fraction - 2) - 1)
      EndIf
   EndProcedure
   
   ; Easing equation function for a quadratic (t^2) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f QuadEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5 * QuadEaseOut(Fraction * 2);
      Else
         ProcedureReturn 0.5 + 0.5 * QuadEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Cubic
   
   ; Easing equation function for a cubic (t^3) easing out:
   ; decelerating from zero velocity.
   Procedure.f CubicEaseOut(Fraction.f)
      Fraction - 1
      ProcedureReturn Fraction * Fraction * Fraction + 1
   EndProcedure
   
   ; Easing equation function for a cubic (t^3) easing in:
   ; accelerating from zero velocity.
   Procedure.f CubicEaseIn(Fraction.f)
      ProcedureReturn Fraction * Fraction * Fraction
   EndProcedure
   
   ; Easing equation function for a cubic (t^3) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f CubicEaseInOut(Fraction.f)
      Fraction * 2
      If (Fraction<1)
         ProcedureReturn 0.5 * Fraction * Fraction * Fraction
      Else
         Fraction - 2
         ProcedureReturn 0.5 * (Fraction * Fraction * Fraction + 2)
      EndIf
   EndProcedure
   
   ; Easing equation function for a cubic (t^3) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f CubicEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5 * CubicEaseOut(Fraction * 2)
      Else
         ProcedureReturn 0.5 + 0.5 * CubicEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Quartic
   
   ; Easing equation function for a quartic (t^4) easing out:
   ; decelerating from zero velocity.
   Procedure.f QuartEaseOut(Fraction.f)
      Fraction - 1
      ProcedureReturn -(Fraction * Fraction * Fraction * Fraction - 1)
   EndProcedure
   
   ; Easing equation function for a quartic (t^4) easing in:
   ; accelerating from zero velocity.
   Procedure.f QuartEaseIn(Fraction.f)
      ProcedureReturn Fraction * Fraction * Fraction * Fraction
   EndProcedure
   
   ; Easing equation function for a quartic (t^4) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f QuartEaseInOut(Fraction.f)
      Fraction * 2
      If (Fraction<1)
         ProcedureReturn 0.5 * Fraction * Fraction * Fraction * Fraction
      Else
         Fraction - 2
         ProcedureReturn -0.5 * (Fraction * Fraction * Fraction * Fraction - 2)
      EndIf
   EndProcedure
   
   ; Easing equation function for a quartic (t^4) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f QuartEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5 * QuartEaseOut(Fraction * 2)
      Else
         ProcedureReturn 0.5 + 0.5 * QuartEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Quintic
   
   ; Easing equation function for a quintic (t^5) easing out:
   ; decelerating from zero velocity.
   Procedure.f QuintEaseOut(Fraction.f)
      Fraction - 1
      ProcedureReturn (Fraction * Fraction * Fraction * Fraction * Fraction + 1)
   EndProcedure
   
   ; Easing equation function for a quintic (t^5) easing in:
   ; accelerating from zero velocity.
   Procedure.f QuintEaseIn(Fraction.f)
      ProcedureReturn Fraction * Fraction * Fraction * Fraction * Fraction
   EndProcedure
   
   ; Easing equation function for a quintic (t^5) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f QuintEaseInOut(Fraction.f)
      Fraction * 2
      If (Fraction<1)
         ProcedureReturn 0.5 * Fraction * Fraction * Fraction * Fraction * Fraction
      Else
         Fraction - 2
         ProcedureReturn 0.5 * (Fraction * Fraction * Fraction * Fraction * Fraction + 2)
      EndIf
   EndProcedure
   
   ; Easing equation function for a quintic (t^5) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f QuintEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*QuintEaseOut(Fraction * 2);
      Else
         ProcedureReturn 0.5 + 0.5*QuintEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Circular
   
   ; Easing equation function for a circular (sqrt(1-t^2)) easing out:
   ; decelerating from zero velocity.
   Procedure.f CircEaseOut(Fraction.f)
      Fraction - 1
      ProcedureReturn Sqr(1 - Fraction * Fraction)
   EndProcedure
   
   ; Easing equation function for a circular (sqrt(1-t^2)) easing in:
   ; accelerating from zero velocity.
   Procedure.f CircEaseIn(Fraction.f)
      ProcedureReturn - (Sqr(1 - Fraction * Fraction) - 1)
   EndProcedure
   
   ; Easing equation function for a circular (sqrt(1-t^2)) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f CircEaseInOut(Fraction.f)
      Fraction * 2
      If (Fraction<1)
         ProcedureReturn -0.5 * (Sqr(1 - Fraction * Fraction) - 1)
      Else
         Fraction - 2
         ProcedureReturn 0.5 * (Sqr(1 - Fraction * Fraction) + 1)
      EndIf
   EndProcedure
   
   ; Easing equation function for a circular (sqrt(1-t^2)) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f CircEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*CircEaseOut(Fraction * 2)
      Else
         ProcedureReturn 0.5 + 0.5*CircEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Sine
   
   ; Easing equation function for a sinusoidal (sin(t)) easing out:
   ; decelerating from zero velocity.
   Procedure.f SineEaseOut(Fraction.f)
      ProcedureReturn Sin(Fraction * (#PI / 2))
   EndProcedure
   
   ; Easing equation function for a sinusoidal (sin(t)) easing in:
   ; accelerating from zero velocity.
   Procedure.f SineEaseIn(Fraction.f)
      ProcedureReturn - Cos(Fraction * (#PI / 2)) + 1
   EndProcedure
   
   ; Easing equation function for a sinusoidal (sin(t)) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f SineEaseInOut(Fraction.f)
      ProcedureReturn -0.5 * (Cos(Fraction*#PI) - 1)
   EndProcedure
   
   ; Easing equation function for a sinusoidal (sin(t)) easing in/out:
   ; deceleration until halfway, then acceleration.
   Procedure.f SineEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*SineEaseOut(Fraction * 2)
      Else
         ProcedureReturn 0.5 + 0.5*SineEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Elastic
   
   ; Easing equation function for an elastic (exponentially decaying sine wave) easing out:
   ; decelerating from zero velocity.
   Procedure.f ElasticEaseOut(Fraction.f)
      If (Fraction=1)
         ProcedureReturn 1
      EndIf
      
      Protected p.f=0.3
      Protected s.f=p / 4
      ProcedureReturn Pow(2, -10 * Fraction) * Sin((Fraction - s) * (2 * #PI) / p) + 1
   EndProcedure
   
   ; Easing equation function for an elastic (exponentially decaying sine wave) easing in:
   ; accelerating from zero velocity.
   Procedure.f ElasticEaseIn(Fraction.f)
      If (Fraction=1)
         ProcedureReturn 1
      EndIf
      
      Protected p.f=0.3
      Protected s.f=p / 4
      Fraction - 1
      ProcedureReturn -Pow(2, 10 * Fraction) * Sin((Fraction - s) * (2 * #PI) / p)
   EndProcedure
   
   ; Easing equation function for an elastic (exponentially decaying sine wave) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f ElasticEaseInOut(Fraction.f)
      Fraction * 2
      If (Fraction=2)
         ProcedureReturn 1
      EndIf
      
      Protected p.f=(0.3 * 1.5)
      Protected s.f=p / 4
      If (Fraction<1)
         Fraction - 1
         ProcedureReturn -0.5 * (Pow(2, 10 * Fraction) * Sin((Fraction - s) * (2 * #PI) / p))
      Else
         Fraction - 1
         ProcedureReturn 0.5 * (Pow(2, -10 * Fraction) * Sin((Fraction - s) * (2 * #PI) / p)) + 1
      EndIf
   EndProcedure
   
   ; Easing equation function for an elastic (exponentially decaying sine wave) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f ElasticEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*ElasticEaseOut(Fraction * 2)
      Else
         ProcedureReturn 0.5 + 0.5*ElasticEaseIn((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ;} endregion
   
   ;{ FX Bounce
   
   ; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out:
   ; decelerating from zero velocity.
   Procedure.f BounceEaseOut(Fraction.f)
      If (Fraction<(1 / 2.75))
         ProcedureReturn (7.5625 * Fraction * Fraction)
      ElseIf (Fraction<(2 / 2.75))
         Fraction - (1.5 / 2.75)
         ProcedureReturn (7.5625 * Fraction * Fraction + 0.75)
      ElseIf (Fraction<(2.5 / 2.75))
         Fraction - (2.25 / 2.75)
         ProcedureReturn (7.5625 * Fraction * Fraction + 0.9375)
      Else
         Fraction - (2.625 / 2.75)
         ProcedureReturn (7.5625 * Fraction * Fraction + 0.984375)
      EndIf
   EndProcedure
   
   ; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in:
   ; accelerating from zero velocity.
   Procedure.f BounceEaseIn(Fraction.f)
      ProcedureReturn 1 - BounceEaseOut(1 - Fraction)
   EndProcedure
   
   ; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f BounceEaseInOut(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*BounceEaseIn(Fraction * 2)
      Else
         ProcedureReturn 0.5 + 0.5*BounceEaseOut((Fraction * 2) - 1)
      EndIf
   EndProcedure
   
   ; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f BounceEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*BounceEaseOut(Fraction * 2)
      EndIf
      
      ProcedureReturn 0.5 + 0.5*BounceEaseIn(Fraction * 2 - 1)
   EndProcedure
   
   ;} endregion
   
   ;{ FX Back
   
   ; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out:
   ; decelerating from zero velocity.
   Procedure.f BackEaseOut(Fraction.f)
      Fraction - 1
      ProcedureReturn Fraction * Fraction * ((1.70158 + 1) * Fraction + 1.70158) + 1
   EndProcedure
   
   ; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in:
   ; accelerating from zero velocity.
   Procedure.f BackEaseIn(Fraction.f)
      ProcedureReturn Fraction * Fraction * ((1.70158 + 1) * Fraction - 1.70158)
   EndProcedure
   
   ; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out:
   ; acceleration until halfway, then deceleration.
   Procedure.f BackEaseInOut(Fraction.f)
      Protected s.f=1.70158
      Fraction * 2
      If (Fraction<1)
         s * (1.525)
         ProcedureReturn 0.5 * (Fraction * Fraction * ((s + 1) * Fraction - s))
      Else
         Fraction - 2
         s * (1.525)
         ProcedureReturn 0.5 * (Fraction * Fraction * ((s + 1) * Fraction + s) + 2)
      EndIf
   EndProcedure
   
   ; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in:
   ; deceleration until halfway, then acceleration.
   Procedure.f BackEaseOutIn(Fraction.f)
      If (Fraction<0.5)
         ProcedureReturn 0.5*BackEaseOut(Fraction * 2)
      EndIf
      
      ProcedureReturn 0.5 + 0.5*BackEaseIn((Fraction * 2) - 1)
   EndProcedure
   
   ;} endregion
    
   Procedure.f FractionTimer(ExecutionTime, IsPingPong=#False, Duration=1000, LoopDuration=0)
      If ExecutionTime<0            ; Determines if timer has started
         ExecutionTime=0
      ElseIf ExecutionTime>Duration ; Determines if timer has ended
         ExecutionTime=Duration
      EndIf
      Protected Fraction.f
      ;Convert to Loop if necessary
      If LoopDuration
         Fraction=Mod(ExecutionTime, LoopDuration) / LoopDuration
      Else         
         Fraction=ExecutionTime / Duration
      EndIf      
      ;Convert to PingPong if necessary
      If IsPingPong
         Fraction=1-Abs(2*Fraction-1)
      EndIf
      ProcedureReturn Fraction
   EndProcedure         
   Procedure.f TweenRelativeValue(FX, Fraction.f)
      Select FX
         Case #FX_Linear : ProcedureReturn Linear(Fraction)
            
         Case #FX_ExpoEaseOut : ProcedureReturn ExpoEaseOut(Fraction)
         Case #FX_ExpoEaseIn : ProcedureReturn ExpoEaseIn(Fraction)
         Case #FX_ExpoEaseInOut : ProcedureReturn ExpoEaseInOut(Fraction)
         Case #FX_ExpoEaseOutIn : ProcedureReturn ExpoEaseOutIn(Fraction)
            
         Case #FX_QuadEaseOut : ProcedureReturn QuadEaseOut(Fraction)
         Case #FX_QuadEaseIn : ProcedureReturn QuadEaseIn(Fraction)
         Case #FX_QuadEaseInOut : ProcedureReturn QuadEaseInOut(Fraction)
         Case #FX_QuadEaseOutIn : ProcedureReturn QuadEaseOutIn(Fraction)
            
         Case #FX_CubicEaseOut : ProcedureReturn CubicEaseOut(Fraction)
         Case #FX_CubicEaseIn : ProcedureReturn CubicEaseIn(Fraction)
         Case #FX_CubicEaseInOut : ProcedureReturn CubicEaseInOut(Fraction)
         Case #FX_CubicEaseOutIn : ProcedureReturn CubicEaseOutIn(Fraction)
            
         Case #FX_QuartEaseOut : ProcedureReturn QuartEaseOut(Fraction)
         Case #FX_QuartEaseIn : ProcedureReturn QuartEaseIn(Fraction)
         Case #FX_QuartEaseInOut : ProcedureReturn QuartEaseInOut(Fraction)
         Case #FX_QuartEaseOutIn : ProcedureReturn QuartEaseOutIn(Fraction)
            
         Case #FX_QuintEaseOut : ProcedureReturn QuintEaseOut(Fraction)
         Case #FX_QuintEaseIn : ProcedureReturn QuintEaseIn(Fraction)
         Case #FX_QuintEaseInOut : ProcedureReturn QuintEaseInOut(Fraction)
         Case #FX_QuintEaseOutIn : ProcedureReturn QuintEaseOutIn(Fraction)
            
         Case #FX_CircEaseOut : ProcedureReturn CircEaseOut(Fraction)
         Case #FX_CircEaseIn : ProcedureReturn CircEaseIn(Fraction)
         Case #FX_CircEaseInOut : ProcedureReturn CircEaseInOut(Fraction)
         Case #FX_CircEaseOutIn : ProcedureReturn CircEaseOutIn(Fraction)
            
         Case #FX_SineEaseOut : ProcedureReturn SineEaseOut(Fraction)
         Case #FX_SineEaseIn : ProcedureReturn SineEaseIn(Fraction)
         Case #FX_SineEaseInOut : ProcedureReturn SineEaseInOut(Fraction)
         Case #FX_SineEaseOutIn : ProcedureReturn SineEaseOutIn(Fraction)
            
         Case #FX_ElasticEaseOut : ProcedureReturn ElasticEaseOut(Fraction)
         Case #FX_ElasticEaseIn : ProcedureReturn ElasticEaseIn(Fraction)
         Case #FX_ElasticEaseInOut : ProcedureReturn ElasticEaseInOut(Fraction)
         Case #FX_ElasticEaseOutIn : ProcedureReturn ElasticEaseOutIn(Fraction)
            
         Case #FX_BounceEaseOut : ProcedureReturn BounceEaseOut(Fraction)
         Case #FX_BounceEaseIn : ProcedureReturn BounceEaseIn(Fraction)
         Case #FX_BounceEaseInOut : ProcedureReturn BounceEaseInOut(Fraction)
         Case #FX_BounceEaseOutIn : ProcedureReturn BounceEaseOutIn(Fraction)
            
         Case #FX_BackEaseOut : ProcedureReturn BackEaseOut(Fraction)
         Case #FX_BackEaseIn : ProcedureReturn BackEaseIn(Fraction)
         Case #FX_BackEaseInOut : ProcedureReturn BackEaseInOut(Fraction)
         Case #FX_BackEaseOutIn : ProcedureReturn BackEaseOutIn(Fraction)
      EndSelect
   EndProcedure   
   
   Structure TWEEN
      FX.i
      StartValue.f
      ProgressValue.f
      LoopCount.i
      LoopDuration.i
      Duration.i
      StartTime.i
      EndTime.i
      PauseTime.i
      Flags.i
   EndStructure
   Global NewList Tweens.TWEEN()
   Procedure.i InitTween()
      Protected fx, t
      For fx=0 To #TWEEN_CountFX
         For t=0 To #TWEEN_FastTweenValues
            FastTweenRelativeValue(fx, t)=TweenRelativeValue(fx, t / #TWEEN_FastTweenValues)
         Next
      Next
      ProcedureReturn #True ; initialized successfully
   EndProcedure
   Procedure.i CreateTween(FX, StartValue, ProgressValue, LoopCount=0, Duration=1000, Delay=0, Flags=0)
      Protected *this.TWEEN=AddElement(Tweens())
      With *this
         \FX=FX
         \StartValue=StartValue
         \ProgressValue=ProgressValue
         \Duration=Duration
         If LoopCount
            \LoopCount=LoopCount
            \LoopDuration=Duration / LoopCount
         EndIf
         \StartTime=ElapsedMilliseconds() + Delay
         \EndTime=\StartTime + Duration
         \Flags=Flags
      EndWith
      ProcedureReturn *this
   EndProcedure
   Procedure.i PauseTween(*this.TWEEN, Paused=#True)
      With *this
         If Paused
            If \PauseTime=0
               \PauseTime=ElapsedMilliseconds()
               ProcedureReturn #True ; pause successfully
            EndIf
         Else
            If \PauseTime<>0
               \StartTime + (ElapsedMilliseconds()-\PauseTime)
               \PauseTime=0
               ProcedureReturn #True ; unpause successfully
            EndIf
         EndIf                  
      EndWith      
   EndProcedure
   Procedure.i TweenFX(*this.TWEEN)
      ProcedureReturn *this\FX
   EndProcedure
   Procedure.i TweenPauseTime(*this.TWEEN)
      ProcedureReturn *this\PauseTime
   EndProcedure
   Procedure.i TweenStartTime(*this.TWEEN)
      ProcedureReturn *this\StartTime
   EndProcedure
   Procedure.i TweenEndTime(*this.TWEEN)
      ProcedureReturn *this\EndTime
   EndProcedure
   Procedure.i TweenExecutionTime(*this.TWEEN)
      ProcedureReturn ElapsedMilliseconds()-*this\StartTime
   EndProcedure
   Procedure.i TweenDuration(*this.TWEEN)
      ProcedureReturn *this\Duration
   EndProcedure
   Procedure.i TweenLoopCount(*this.TWEEN)
      ProcedureReturn *this\LoopCount
   EndProcedure
   Procedure UpdateTweens()
      Protected t=ElapsedMilliseconds()
      ForEach Tweens()
         Protected Fraction.f, ExecutionTime, ExecutionEnded
         With Tweens()
            If t>\StartTime
               If \PauseTime
                  ExecutionTime=\PauseTime-\StartTime
               ElseIf t<\EndTime
                  ExecutionTime=t-\StartTime
               Else
                  ExecutionTime=\Duration
                  ExecutionEnded=#True
               EndIf               
               Fraction=FractionTimer(ExecutionTime, \Flags & #TWEEN_PingPong, \Duration, \LoopDuration)
               Protected a=FastTweenValue(\FX, \StartValue, \ProgressValue, Fraction)
               
               If \Flags & #TWEEN_AutoDestroy And ExecutionEnded : DeleteElement(Tweens()) : EndIf
            EndIf            
         EndWith         
      Next      
   EndProcedure
EndModule

Re: Module - Animation & Motion tween FX

Posted: Sun Oct 18, 2015 4:56 pm
by eddy
Image

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
   ; *******************************
   ; EXAMPLE 1 - MULTI GRAPH TRACER
   ; *******************************
   
   UseModule Tween
   InitTween()
   
   Enumeration
      #Window
      #Grapher
      #ListFX
   EndEnumeration
   If OpenWindow(#Window, 0, 0, 800, 410, "Tween Function Tester", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
      CanvasGadget(#Grapher, 5, 5, 400, 400)
      TextGadget(#PB_Any, 620, 5, 200, 20, "Use Tween function:")
      mode1=OptionGadget(#PB_Any, 630, 25, 200, 20, "TweenRelativeValue")
      mode2=OptionGadget(#PB_Any, 630, 45, 200, 20, "FastTweenRelativeValue")
      mode3=OptionGadget(#PB_Any, 630, 65, 200, 20, "TweenValue")
      mode4=OptionGadget(#PB_Any, 630, 85, 200, 20, "FastTweenValue")
      SetGadgetState(mode1, 1)
      ListViewGadget(#ListFX, 410, 5, 200, 400, #PB_ListView_MultiSelect | #PB_ListView_ClickSelect)
      ;{ LIST OF EFFECTS
      AddGadgetItem(#ListFX, -1, "#FX_Linear")
      
      AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_QuadEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_QuadEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_QuadEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_QuadEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_CubicEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_CubicEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_CubicEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_CubicEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_QuartEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_QuartEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_QuartEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_QuartEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_QuintEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_QuintEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_QuintEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_QuintEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_CircEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_CircEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_CircEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_CircEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_SineEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_SineEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_SineEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_SineEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_ElasticEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_ElasticEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_ElasticEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_ElasticEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_BounceEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_BounceEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_BounceEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_BounceEaseOutIn")
      
      AddGadgetItem(#ListFX, -1, "#FX_BackEaseOut")
      AddGadgetItem(#ListFX, -1, "#FX_BackEaseIn")
      AddGadgetItem(#ListFX, -1, "#FX_BackEaseInOut")
      AddGadgetItem(#ListFX, -1, "#FX_BackEaseOutIn")
      ;}
      
      Repeat
         Event=WaitWindowEvent()
         If Event=#PB_Event_Gadget 
            
            If StartDrawing(CanvasOutput(#Grapher))
               ;{ GRAPH BACKGROUND IMAGE
               w=OutputWidth()
               h=OutputHeight()
               Box(0, 0, w, h, #White)
               DrawingMode(#PB_2DDrawing_Transparent)
               Line(5, 5, w-10, 1, RGB(200, 200, 200))
               Line(5, h-5, w-10, 1, RGB(200, 200, 200))
               Line(5, 90, w-10, 1, RGB(200, 200, 200))
               Line(w-5, 5, 1, h-10, RGB(200, 200, 200))
               
               Line(5, 5, 1, h-10, #Gray)
               Line(5, 5, 5, 5, #Gray)
               Line(5, 5, -5, 5, #Gray)
               Line(5, h-5, 5, -5, #Gray)
               Line(5, h-5, -5, -5, #Gray)
               
               Line(5, h-90, w-10, 1, #Gray)
               Line(w-5, h-90, -5, 5, #Gray)
               Line(w-5, h-90, -5, -5, #Gray)
               
               DrawText(10, 5, "values", #Red, 0)
               DrawText(10, 90, "+1", #Red, 0)
               DrawText(10, h-90-20, "0", #Red, 0)
               DrawText(10, h-90 + 5, "0%", #Blue, 0)
               DrawText(w-10-30, h-90 + 5, "100%", #Blue, 0)
               DrawText(w-10-50, h-90 + 20, "Fraction", #Blue, 0)
               ;}
               
               Define t, color, x.f, y.f
               Define startX.f, startY.f
               Define finalX.f, finalY.f
               Define moveX.f, moveY.f, prevX.f, prevY.f
               
               startX=5
               startY=h-90
               finalX=w-5
               finalY=90
               moveX=finalX-startX-1
               moveY=finalY-startY
               
               For fx=0 To #TWEEN_CountFX
                  If GetGadgetItemState(#ListFX, fx)
                     ;{ TRACE COLORED GRAPHS
                     prevX=startX
                     prevY=startY
                     color=RGB(50 + Random(150), 50 + Random(150), 50 + Random(150))
                     For t=0 To 400
                        fraction.f=t / 400
                        If GetGadgetState(mode1)
                           x.f=startX + moveX*TweenRelativeValue(#FX_Linear, fraction)
                           y.f=startY + moveY*TweenRelativeValue(fx, fraction)
                        ElseIf GetGadgetState(mode2)
                           x.f=startX + moveX*FastTweenRelativeValue(#FX_Linear, Int(#TWEEN_FastTweenValues * fraction))
                           y.f=startY + moveY*FastTweenRelativeValue(fx, Int(#TWEEN_FastTweenValues * fraction))
                        ElseIf GetGadgetState(mode3)
                           x.f=TweenValue(#FX_Linear, startX, moveX, fraction)
                           y.f=TweenValue(fx, startY, moveY, fraction)
                        ElseIf GetGadgetState(mode4)
                           x.f=FastTweenValue(#FX_Linear, startX, moveX, fraction)
                           y.f=FastTweenValue(fx, startY, moveY, fraction)
                        EndIf
                        LineXY(prevX, prevY, x, y, color)
                        prevX=x
                        prevY=y
                     Next
                     ;}
                  EndIf
               Next
               StopDrawing()
            EndIf
         EndIf
      Until Event=#PB_Event_CloseWindow
   EndIf
CompilerEndIf

Re: Module - Animation & Motion tween FX

Posted: Sun Oct 18, 2015 5:58 pm
by eddy
Image

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
   ; *******************************
   ; EXAMPLE 2 - FLARE WAVE
   ; *******************************
   
   UseModule Tween
   InitSprite()
   InitTween()
   
   Structure FLARE
      x.i
      y.i
      dx.i
      dy.i      
      offset.f
      moveEffect.i
      movingDuration.i
      sizeEffect.i
      sizingDuration.i
      size1.i
      size2.i
   EndStructure
   Global NewList flares.FLARE()
   Procedure.i FlipBuffersAndRetrieveFPS()
      Static fpsCounter
      Static fpsStartTime
      Static fpsValue
      
      If FlipBuffers()
         fpsCounter + 1
      EndIf
      
      If (ElapsedMilliseconds()-fpsStartTime)>=1000
         fpsValue=fpsCounter
         fpsCounter=0
         fpsStartTime=ElapsedMilliseconds()
      EndIf
      
      ProcedureReturn fpsValue
   EndProcedure
   
   win=OpenWindow(#PB_Any, 0, 0, 600, 480, "Tween Sprite Animation", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   OpenWindowedScreen(WindowID(win), 0, 0, WindowWidth(win), WindowHeight(win), 0, 0, 0, #PB_Screen_NoSynchronization)
   
   ;CREATE "FLARE" SPRITE 
   flare=CreateSprite(#PB_Any, 200, 200, #PB_Sprite_AlphaBlending)
   StartDrawing(SpriteOutput(flare))
   DrawingMode(#PB_2DDrawing_AlphaChannel)
   Box(0, 0, OutputWidth(), OutputHeight(), 0)
   DrawingMode(#PB_2DDrawing_Gradient | #PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
   BackColor(RGBA(255, 255, 255, 255))
   GradientColor(0.3, RGBA(255, 100, 0, 100))
   FrontColor(RGBA(255, 0, 0, 0))
   CircularGradient(OutputWidth() / 2, OutputHeight() / 2, OutputHeight() / 2)
   Circle(OutputWidth() / 2, OutputHeight() / 2, OutputHeight() / 2)
   StopDrawing()
   
   For i=0 To 1000
      AddElement(flares())
      With flares()
         ;RANDOM POSITION, MOVES & ANIMATIONS
         \x=Int(77*i*i*Cos(i*0.3))% WindowWidth(win)
         \y=Int(66*i*i*Sin(i*0.2))% WindowHeight(win)
         r.f=Sqr(Pow(\x-WindowWidth(win) / 2, 2) + Pow(\y-WindowHeight(win) / 2, 2))
         a.f=ATan2(\x-WindowWidth(win) / 2, \y-WindowHeight(win) / 2)
         \offset=Mod(r + 400, 800) / 800
         \sizeEffect=(i + 3)%(#TWEEN_CountFX + 1)
         \sizingDuration=1000 + Mod(i*i*y* 200, 2000)
         \size1=50* (350 - r) / 350
         \size2=size1 / 2
         \moveEffect=(i + 7)%(#TWEEN_CountFX + 1)
         \movingDuration=1000 + Abs(Mod(\x*\y*i, 2000))
         If (r>150) : r / 2 : Else : r*2 : EndIf
         \dx=r*Cos(a)
         \dy=r*Sin(a)         
      EndWith
   Next
   
   st=ElapsedMilliseconds()
   Repeat
      ClearScreen(#Black)
      nt=ElapsedMilliseconds()
      dt=nt-st : st=nt
      executionTime + dt
      ForEach flares()
         With flares()
            x=FastTweenValue(\moveEffect, \x, \dx, FractionTimer(executionTime, #True, \movingDuration * 5, \movingDuration))
            y=FastTweenValue(\moveEffect, \y, \dy, FractionTimer(executionTime, #True, \movingDuration * 3, \movingDuration))
            z=FastTweenValueFromTo(\sizeEffect, \size1, \size2, FractionTimer(executionTime, #True, \sizingDuration * 9, \sizingDuration))
            TransformSprite(flare, -z, -z, z, -z, z, z, -z, z)
            DisplayTransparentSprite(flare, x, y)
         EndWith
      Next
      
      fps=FlipBuffersAndRetrieveFPS()
      SetWindowTitle(win, "Frame Rate = " + Str(fps))
   Until WindowEvent()=#PB_Event_CloseWindow

CompilerEndIf

Re: Module - Animation & Motion tween FX

Posted: Mon Oct 19, 2015 12:55 pm
by DK_PETER
Very good work, Eddy.
I like it. Thanks. :wink: