Module - Animation & Motion tween FX

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Module - Animation & Motion tween FX

Post 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
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Module - Animation & Motion tween FX

Post 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
Last edited by eddy on Sun Oct 18, 2015 6:44 pm, edited 2 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Module - Animation & Motion tween FX

Post 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
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Module - Animation & Motion tween FX

Post by DK_PETER »

Very good work, Eddy.
I like it. Thanks. :wink:
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Post Reply