Page 1 of 1

Animation & Motion tween FX

Posted: Mon Aug 19, 2013 6:59 pm
by eddy

Code: Select all

;:=============================================================================
;:- Tween.pbi 
;:- Author          : Eddy
;:- Date            : August 19, 2013
;:- Compiler        : PureBasic 5.20 beta 11 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] 
;:=============================================================================

EnableExplicit

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

;{ region Linear

; <summary>
; Easing equation function for a simple linear tweening, with no easing.
; </summary>
Procedure.f Tween_Linear( t.f, b.f, c.f, d.f )
  
  ProcedureReturn c * t / d + b
EndProcedure

;} endregion

;{ region Expo

; <summary>
; Easing equation function for an exponential (2^t) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_ExpoEaseOut( t.f, b.f, c.f, d.f )
  
  If ( t = d ) : ProcedureReturn  b + c : Else : ProcedureReturn  c * ( -Pow( 2, -10 * t / d ) + 1 ) + b : EndIf
EndProcedure

; <summary>
; Easing equation function for an exponential (2^t) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_ExpoEaseIn( t.f, b.f, c.f, d.f )
  
  If ( t = 0 ) : ProcedureReturn  b : Else : ProcedureReturn  c * Pow( 2, 10 * ( t / d - 1 ) ) + b : EndIf
EndProcedure

; <summary>
; Easing equation function for an exponential (2^t) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_ExpoEaseInOut( t.f, b.f, c.f, d.f )
  
  If ( t = 0 )
    ProcedureReturn b;
  EndIf
  
  If ( t = d )
    ProcedureReturn b + c;
  EndIf
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn c / 2 * Pow( 2, 10 * ( t - 1 ) ) + b;
  EndIf
  
  t-1
  ProcedureReturn c / 2 * ( -Pow( 2, -10 * t ) + 2 ) + b
EndProcedure

; <summary>
; Easing equation function for an exponential (2^t) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_ExpoEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_ExpoEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_ExpoEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Circular

; <summary>
; Easing equation function for a circular (sqrt(1-t^2)) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_CircEaseOut( t.f, b.f, c.f, d.f )
  
  t = t / d - 1
  ProcedureReturn c * Sqr( 1 - t * t ) + b
EndProcedure

; <summary>
; Easing equation function for a circular (sqrt(1-t^2)) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_CircEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn -c * ( Sqr( 1 - t * t ) - 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a circular (sqrt(1-t^2)) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_CircEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn -c / 2 * ( Sqr( 1 - t * t ) - 1 ) + b;
  EndIf
  
  t - 2
  ProcedureReturn c / 2 * ( Sqr( 1 - t * t ) + 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a circular (sqrt(1-t^2)) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_CircEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_CircEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_CircEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Quad

; <summary>
; Easing equation function for a quadratic (t^2) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_QuadEaseOut( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn -c * t * ( t - 2 ) + b
EndProcedure

; <summary>
; Easing equation function for a quadratic (t^2) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_QuadEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn c * t * t + b
EndProcedure

; <summary>
; Easing equation function for a quadratic (t^2) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_QuadEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn c / 2 * t * t + b;
  EndIf
  
  t-1
  ProcedureReturn -c / 2 * ( t * ( t - 2 ) - 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a quadratic (t^2) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_QuadEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_QuadEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_QuadEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Sine

; <summary>
; Easing equation function for a sinusoidal (sin(t)) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_SineEaseOut( t.f, b.f, c.f, d.f )
  
  ProcedureReturn c * Sin( t / d * ( #PI / 2 ) ) + b
EndProcedure

; <summary>
; Easing equation function for a sinusoidal (sin(t)) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_SineEaseIn( t.f, b.f, c.f, d.f )
  
  ProcedureReturn -c * Cos( t / d * ( #PI / 2 ) ) + c + b
EndProcedure

; <summary>
; Easing equation function for a sinusoidal (sin(t)) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_SineEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn c / 2 * ( Sin( #PI * t / 2 ) ) + b;
  EndIf
  
  t-1
  ProcedureReturn -c / 2 * ( Cos( #PI * t / 2 ) - 2 ) + b
EndProcedure

; <summary>
; Easing equation function for a sinusoidal (sin(t)) easing in/out: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_SineEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_SineEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_SineEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Cubic

; <summary>
; Easing equation function for a cubic (t^3) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_CubicEaseOut( t.f, b.f, c.f, d.f )
  
  t = t / d - 1
  ProcedureReturn c * ( t * t * t + 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a cubic (t^3) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_CubicEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn c * t * t * t + b
EndProcedure

; <summary>
; Easing equation function for a cubic (t^3) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_CubicEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn c / 2 * t * t * t + b;
  EndIf
  
  t - 2
  ProcedureReturn c / 2 * ( t * t * t + 2 ) + b
EndProcedure

; <summary>
; Easing equation function for a cubic (t^3) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_CubicEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_CubicEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_CubicEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Quartic

; <summary>
; Easing equation function for a quartic (t^4) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_QuartEaseOut( t.f, b.f, c.f, d.f )
  
  t = t / d - 1
  ProcedureReturn -c * ( t * t * t * t - 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a quartic (t^4) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_QuartEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn c * t * t * t * t + b
EndProcedure

; <summary>
; Easing equation function for a quartic (t^4) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_QuartEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn c / 2 * t * t * t * t + b;
  EndIf
  
  t - 2
  ProcedureReturn -c / 2 * ( t * t * t * t - 2 ) + b
EndProcedure

; <summary>
; Easing equation function for a quartic (t^4) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_QuartEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_QuartEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_QuartEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Quintic

; <summary>
; Easing equation function for a quintic (t^5) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_QuintEaseOut( t.f, b.f, c.f, d.f )
  
  t = t / d - 1
  ProcedureReturn c * ( t * t * t * t * t + 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a quintic (t^5) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_QuintEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn c * t * t * t * t * t + b
EndProcedure

; <summary>
; Easing equation function for a quintic (t^5) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_QuintEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t < 1 )
    ProcedureReturn c / 2 * t * t * t * t * t + b;
  EndIf
  
  t - 2
  ProcedureReturn c / 2 * ( t * t * t * t * t + 2 ) + b
EndProcedure

; <summary>
; Easing equation function for a quintic (t^5) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_QuintEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_QuintEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_QuintEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Elastic

; <summary>
; Easing equation function for an elastic (exponentially decaying sine wave) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_ElasticEaseOut( t.f, b.f, c.f, d.f )
  
  t / d
  If ( t = 1 )
    ProcedureReturn b + c;
  EndIf
  
  Protected p.f = d * 0.3
  Protected s.f = p / 4
  
  ProcedureReturn ( c * Pow( 2, -10 * t ) * Sin( ( t * d - s ) * ( 2 * #PI ) / p ) + c + b )
EndProcedure

; <summary>
; Easing equation function for an elastic (exponentially decaying sine wave) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_ElasticEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  If ( t = 1 )
    ProcedureReturn b + c;
  EndIf
  
  Protected p.f = d * 0.3
  Protected s.f = p / 4
  
  t - 1
  ProcedureReturn -( c * Pow( 2, 10 * t ) * Sin( ( t * d - s ) * ( 2 * #PI ) / p ) ) + b
EndProcedure

; <summary>
; Easing equation function for an elastic (exponentially decaying sine wave) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_ElasticEaseInOut( t.f, b.f, c.f, d.f )
  
  t / (d / 2)
  If ( t = 2 )
    ProcedureReturn b + c;
  EndIf
  
  Protected p.f = d * ( 0.3 * 1.5 )
  Protected s.f = p / 4
  
  If ( t < 1 )
    t - 1
    ProcedureReturn -0.5 * ( c * Pow( 2, 10 * t ) * Sin( ( t * d - s ) * ( 2 * #PI ) / p ) ) + b;
  EndIf
  
  t - 1
  ProcedureReturn c * Pow( 2, -10 * t ) * Sin( ( t * d - s ) * ( 2 * #PI ) / p ) * 0.5 + c + b
EndProcedure

; <summary>
; Easing equation function for an elastic (exponentially decaying sine wave) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_ElasticEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_ElasticEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_ElasticEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Bounce

; <summary>
; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_BounceEaseOut( t.f, b.f, c.f, d.f )
  
  t / d
  If ( t < ( 1 / 2.75 ) )
    ProcedureReturn c * ( 7.5625 * t * t ) + b;
  ElseIf ( t < ( 2 / 2.75 ) )
    t - ( 1.5 / 2.75 )                
    ProcedureReturn c * ( 7.5625 * t * t + 0.75 ) + b;
  ElseIf ( t < ( 2.5 / 2.75 ) )
    t - ( 2.25 / 2.75 )
    ProcedureReturn c * ( 7.5625 * t * t + 0.9375 ) + b;
  Else
    t - ( 2.625 / 2.75 )
    ProcedureReturn c * ( 7.5625 * t * t + 0.984375 ) + b
  EndIf 
EndProcedure

; <summary>
; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_BounceEaseIn( t.f, b.f, c.f, d.f )
  
  ProcedureReturn c - Tween_BounceEaseOut( d - t, 0, c, d ) + b
EndProcedure

; <summary>
; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_BounceEaseInOut( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_BounceEaseIn( t * 2, 0, c, d ) * 0.5 + b;
  Else
    ProcedureReturn Tween_BounceEaseOut( t * 2 - d, 0, c, d ) * 0.5 + c * 0.5 + b
  EndIf 
EndProcedure

; <summary>
; Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_BounceEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_BounceEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_BounceEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

;{ region Back

; <summary>
; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: 
; decelerating from zero velocity.
; </summary>
Procedure.f Tween_BackEaseOut( t.f, b.f, c.f, d.f )
  
  t = t / d - 1
  ProcedureReturn c * ( t * t * ( ( 1.70158 + 1 ) * t + 1.70158 ) + 1 ) + b
EndProcedure

; <summary>
; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in: 
; accelerating from zero velocity.
; </summary>
Procedure.f Tween_BackEaseIn( t.f, b.f, c.f, d.f )
  
  t / d
  ProcedureReturn c * t * t * ( ( 1.70158 + 1 ) * t - 1.70158 ) + b
EndProcedure

; <summary>
; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out: 
; acceleration until halfway, then deceleration.
; </summary>
Procedure.f Tween_BackEaseInOut( t.f, b.f, c.f, d.f )
  
  Protected s.f = 1.70158
  
  t / (d / 2)
  If ( t < 1 )
    s * ( 1.525 )
    ProcedureReturn c / 2 * ( t * t * ( ( s + 1 ) * t - s ) ) + b;
  EndIf
  
  t - 2
  s * ( 1.525 )
  ProcedureReturn c / 2 * ( t * t * ( ( s + 1 ) * t + s ) + 2 ) + b
EndProcedure

; <summary>
; Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: 
; deceleration until halfway, then acceleration.
; </summary>
Procedure.f Tween_BackEaseOutIn( t.f, b.f, c.f, d.f )
  
  If ( t < d / 2 )
    ProcedureReturn Tween_BackEaseOut( t * 2, b, c / 2, d );
  EndIf
  
  ProcedureReturn Tween_BackEaseIn( ( t * 2 ) - d, b + c / 2, c / 2, d )
EndProcedure

;} endregion

Enumeration    
  ;Tween FX list
  #FX_Linear=0
  
  #FX_QuadEaseOut
  #FX_QuadEaseIn
  #FX_QuadEaseInOut
  #FX_QuadEaseOutIn
  
  #FX_ExpoEaseOut
  #FX_ExpoEaseIn
  #FX_ExpoEaseInOut
  #FX_ExpoEaseOutIn
  
  #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
  
  ;Helpers to select all FX in FOR...NEXT loops
  #FX_FirstValue=#FX_Linear
  #FX_LastValue=#FX_BackEaseOutIn
  
  ;Looping mode
  #FX_Loop_Cycle=0
  #FX_Loop_PingPong
  
  ;Looping count max
  #FX_Loop_MaxCount=$FFFF
  
  ;Helpers to change FastTween Accuracy
  #FX_FastTweenResolution=2048
  #FX_FastTweenPingPong=#FX_FastTweenResolution*2
EndEnumeration

Global Dim FastTweenValues.f(#FX_LastValue,#FX_FastTweenResolution)
Global Dim FastTweenCycles.u(#FX_FastTweenPingPong)

Procedure.f Tween(fx, timer.f, start.f, delta.f, duration.f) 
  Select fx
    Case #FX_Linear: ProcedureReturn Tween_Linear(timer, start, delta, duration)
      
    Case #FX_QuadEaseOut: ProcedureReturn Tween_QuadEaseOut(timer, start, delta, duration)
    Case #FX_QuadEaseIn: ProcedureReturn Tween_QuadEaseIn(timer, start, delta, duration)
    Case #FX_QuadEaseInOut: ProcedureReturn Tween_QuadEaseInOut(timer, start, delta, duration)
    Case #FX_QuadEaseOutIn: ProcedureReturn Tween_QuadEaseOutIn(timer, start, delta, duration)
      
    Case #FX_ExpoEaseOut: ProcedureReturn Tween_ExpoEaseOut(timer, start, delta, duration)
    Case #FX_ExpoEaseIn: ProcedureReturn Tween_ExpoEaseIn(timer, start, delta, duration)
    Case #FX_ExpoEaseInOut: ProcedureReturn Tween_ExpoEaseInOut(timer, start, delta, duration)
    Case #FX_ExpoEaseOutIn: ProcedureReturn Tween_ExpoEaseOutIn(timer, start, delta, duration)
      
    Case #FX_CubicEaseOut: ProcedureReturn Tween_CubicEaseOut(timer, start, delta, duration)
    Case #FX_CubicEaseIn: ProcedureReturn Tween_CubicEaseIn(timer, start, delta, duration)
    Case #FX_CubicEaseInOut: ProcedureReturn Tween_CubicEaseInOut(timer, start, delta, duration)
    Case #FX_CubicEaseOutIn: ProcedureReturn Tween_CubicEaseOutIn(timer, start, delta, duration)
      
    Case #FX_QuartEaseOut: ProcedureReturn Tween_QuartEaseOut(timer, start, delta, duration)
    Case #FX_QuartEaseIn: ProcedureReturn Tween_QuartEaseIn(timer, start, delta, duration)
    Case #FX_QuartEaseInOut: ProcedureReturn Tween_QuartEaseInOut(timer, start, delta, duration)
    Case #FX_QuartEaseOutIn: ProcedureReturn Tween_QuartEaseOutIn(timer, start, delta, duration)
      
    Case #FX_QuintEaseOut: ProcedureReturn Tween_QuintEaseOut(timer, start, delta, duration)
    Case #FX_QuintEaseIn: ProcedureReturn Tween_QuintEaseIn(timer, start, delta, duration)
    Case #FX_QuintEaseInOut: ProcedureReturn Tween_QuintEaseInOut(timer, start, delta, duration)
    Case #FX_QuintEaseOutIn: ProcedureReturn Tween_QuintEaseOutIn(timer, start, delta, duration)
      
    Case #FX_CircEaseOut: ProcedureReturn Tween_CircEaseOut(timer, start, delta, duration)
    Case #FX_CircEaseIn: ProcedureReturn Tween_CircEaseIn(timer, start, delta, duration)
    Case #FX_CircEaseInOut: ProcedureReturn Tween_CircEaseInOut(timer, start, delta, duration)
    Case #FX_CircEaseOutIn: ProcedureReturn Tween_CircEaseOutIn(timer, start, delta, duration)
      
    Case #FX_SineEaseOut: ProcedureReturn Tween_SineEaseOut(timer, start, delta, duration)
    Case #FX_SineEaseIn: ProcedureReturn Tween_SineEaseIn(timer, start, delta, duration)
    Case #FX_SineEaseInOut: ProcedureReturn Tween_SineEaseInOut(timer, start, delta, duration)
    Case #FX_SineEaseOutIn: ProcedureReturn Tween_SineEaseOutIn(timer, start, delta, duration)
      
    Case #FX_ElasticEaseOut: ProcedureReturn Tween_ElasticEaseOut(timer, start, delta, duration)
    Case #FX_ElasticEaseIn: ProcedureReturn Tween_ElasticEaseIn(timer, start, delta, duration)
    Case #FX_ElasticEaseInOut: ProcedureReturn Tween_ElasticEaseInOut(timer, start, delta, duration)
    Case #FX_ElasticEaseOutIn: ProcedureReturn Tween_ElasticEaseOutIn(timer, start, delta, duration)
      
    Case #FX_BounceEaseOut: ProcedureReturn Tween_BounceEaseOut(timer, start, delta, duration)
    Case #FX_BounceEaseIn: ProcedureReturn Tween_BounceEaseIn(timer, start, delta, duration)
    Case #FX_BounceEaseInOut: ProcedureReturn Tween_BounceEaseInOut(timer, start, delta, duration)
    Case #FX_BounceEaseOutIn: ProcedureReturn Tween_BounceEaseOutIn(timer, start, delta, duration)
      
    Case #FX_BackEaseOut: ProcedureReturn Tween_BackEaseOut(timer, start, delta, duration)
    Case #FX_BackEaseIn: ProcedureReturn Tween_BackEaseIn(timer, start, delta, duration)
    Case #FX_BackEaseInOut: ProcedureReturn Tween_BackEaseInOut(timer, start, delta, duration)
    Case #FX_BackEaseOutIn: ProcedureReturn Tween_BackEaseOutIn(timer, start, delta, duration)
  EndSelect 
EndProcedure

Procedure.f FastTween(fx, timer.f, start.f, delta.f, duration.f)    
  Protected tweenIndex=Int(#FX_FastTweenResolution*timer/duration)
  If tweenIndex>#FX_FastTweenResolution
    ProcedureReturn delta+start
  EndIf 
  ProcedureReturn FastTweenValues(fx,tweenIndex)*delta+start
EndProcedure

Procedure.f FastTweenLoop(fx, timer.f, start.f, delta.f, duration.f, loopMode, loopCount.f=#FX_Loop_MaxCount)    
  Protected tweenIndex=Int(#FX_FastTweenResolution*timer/duration)
  Select loopMode
    Case #FX_Loop_Cycle
      If timer>#FX_FastTweenResolution*loopCount
        tweenIndex=#FX_FastTweenResolution*loopCount
      EndIf 
      tweenIndex % (#FX_FastTweenResolution+1)
    Case #FX_Loop_PingPong
      If timer>#FX_FastTweenResolution*loopCount*2
        tweenIndex=#FX_FastTweenResolution*loopCount*2
      EndIf 
      tweenIndex=FastTweenCycles(tweenIndex % (#FX_FastTweenPingPong+1))
  EndSelect
  
  ProcedureReturn FastTweenValues(fx,tweenIndex)*delta+start
EndProcedure

Procedure InitFastTween()
  Protected fx,t
  For fx=#FX_FirstValue To #FX_LastValue
    For t=0 To #FX_FastTweenResolution
      FastTweenValues(fx,t)=Tween(fx,t,0,1,#FX_FastTweenResolution)
    Next 
  Next 
  
  For t=0 To #FX_FastTweenResolution
    FastTweenCycles(t)=t
    FastTweenCycles(#FX_FastTweenPingPong-t)=t
  Next      
EndProcedure 

Procedure.i DeltaMilliseconds()
  Static lastTime.i, previousTime.i, deltaTime.f
  lastTime=ElapsedMilliseconds()
  deltaTime=(lastTime-previousTime)
  previousTime=lastTime  
  ProcedureReturn deltaTime  
EndProcedure 

Procedure.f DeltaSeconds()
  Static lastTime.i, previousTime.i, deltaTime.f
  lastTime=ElapsedMilliseconds()
  deltaTime=(lastTime-previousTime)
  previousTime=lastTime  
  ProcedureReturn deltaTime/1000.0 
EndProcedure
Image

Code: Select all

; *******************************
; EXAMPLE 1 - SPRITE TWEEN ANIMATION
; *******************************

DisableExplicit

UsePNGImageEncoder() ;<--- used by EncodeImage
UsePNGImageDecoder() ;<--- used by CatchSprite

InitSprite()
InitFastTween()


Structure FLARE
   x.i
   y.i
   z.i
   dx.i
   dy.i
   dz.i
   effectX.i
   effectY.i
   effectZ.i
   t.i
   durationXY.i
   durationZ.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, 610, 410, "Tween Sprite Animation",
               #PB_Window_SystemMenu |
               #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(win), 5, 5, 600, 400, 0, 0, 0, #PB_Screen_NoSynchronization)

;// CREATE "FLARE" SPRITE 3D
img=CreateImage(#PB_Any, 200, 200, 32,  #PB_Image_Transparent)
If StartDrawing(ImageOutput(img))
   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(100, 100, 100)
   Circle(100, 100, 100)
   StopDrawing()
   
   *imgMemory=EncodeImage(img, #PB_ImagePlugin_PNG, 10, 32)
   If *imgMemory
      flare=CatchSprite(#PB_Any, *imgMemory, #PB_Sprite_AlphaBlending)
   EndIf
EndIf

For i=0 To 1000
   AddElement(flares())
   With flares()
      ;// RANDOM POSITION, MOVES & ANIMATIONS
      \x=Int(77*i*i*Cos(i*0.3))% 600
      \y=Int(66*i*i*Sin(i*0.2))% 400
      \z=\x % 5
      \dx=300+Cos(\x)*300
      \dy=200+Sin(\x)*200
      \dz=\y % 50
      \effectX=(i+7)%(#FX_LastValue+1)
      \effectY=(i+9)%(#FX_LastValue+1)
      \effectZ=(i+3)%(#FX_LastValue+1)
      \t=0
      \durationXY=((\x*\y*i)% 5000)+ 5000
      \durationZ=\durationXY/3
   EndWith
Next

DeltaMilliseconds()
Repeat
   dt=DeltaMilliseconds()
   
   ClearScreen(#Black)
   ForEach flares()
      With flares()
         \t+dt
         x=FastTweenLoop(\effectX, \t, \x, \dx, \durationXY, #FX_Loop_PingPong)
         y=FastTweenLoop(\effectY, \t, \y, \dy, \durationXY, #FX_Loop_PingPong, 2)
         z=FastTweenLoop(\effectZ, \t, \z, \dz, \durationZ, #FX_Loop_PingPong, 10)
         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 
Image

Code: Select all

; *******************************
; EXAMPLE 2 - BOILING BUBBLES
; *******************************

DisableExplicit
UsePNGImageEncoder()
UsePNGImageDecoder()

InitSprite()
InitFastTween()

Structure BUBBLE
   x.i
   y.i
   z.i
   a.i
   dx.i
   dy.i
   dz.i
   da.i
   t.i
   durationX.i
   durationY.i
   durationZ.i
EndStructure
Global NewList Bubbles.BUBBLE()

win=OpenWindow(#PB_Any, 0, 0, 600, 400, "Bubble Sprites", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(win), 0, 0, 600, 400)

;// CREATE "BUBBLE" SPRITE 3D
img=CreateImage(#PB_Any, 200, 200, 32,  #PB_Image_Transparent)
If StartDrawing(ImageOutput(img))
   DrawingMode(#PB_2DDrawing_Gradient|
               #PB_2DDrawing_AlphaBlend|
               #PB_2DDrawing_Transparent)
   BackColor(RGBA(26, 96, 186, 255))
   GradientColor(0.8, RGBA(35, 108, 203, 255))
   FrontColor(RGBA(84, 155, 246, 255))
   CircularGradient(90, 90, 100)
   Circle(100, 100, 100)
   
   DrawingMode(#PB_2DDrawing_AlphaChannel)
   FrontColor(RGBA(255, 255, 255, 240))
   Circle(95, 95, 90)
   FrontColor(RGBA(255, 255, 255, 200))
   Circle(75, 75, 60)
   
   StopDrawing()
   
   *imgMemory=EncodeImage(img, #PB_ImagePlugin_PNG, 10, 32)
   If *imgMemory
      bubble=CatchSprite(#PB_Any, *imgMemory, #PB_Sprite_AlphaBlending)
   EndIf
EndIf

For i=0 To 100
   AddElement(Bubbles())
   With Bubbles()
      ;// RANDOM POSITION, MOVES & ANIMATIONS
      \x=Random(580)+10
      \dx=Random(580)+10-\x
      \y=Random(50)+400
      \dy=-Random(50)-\y
      \z=Random(5, 2)
      \dz=Random(20)
      \a=10
      \da=245
      \durationX=Random(15000)+5000
      \durationY=\durationX+1000
      \durationZ=\durationY
      \t=Random(10000)
   EndWith
Next

t1=ElapsedMilliseconds()
Repeat
   t2=ElapsedMilliseconds()
   dt=t2-t1
   t1=t2
   
   ClearScreen(RGB(44, 82, 131))
   ForEach Bubbles()
      With Bubbles()
         \t+dt
         x.f=FastTweenLoop(#FX_CubicEaseIn, \t, \x, \dx, \durationX, #FX_Loop_PingPong)
         y.f=FastTweenLoop(#FX_CircEaseOut, \t, \y, \dy, \durationY, #FX_Loop_Cycle)
         z.f=FastTweenLoop(#FX_ExpoEaseOut, \t, \z, \dz, \durationZ, #FX_Loop_Cycle)
         a.i=FastTweenLoop(#FX_Linear, \t, \a, \da, 3000, #FX_Loop_PingPong)
         TransformSprite(bubble, -z, -z, z, -z, z, z, -z, z)
         DisplayTransparentSprite(bubble, x, y, a)
      EndWith
   Next
   FlipBuffers()
Until WindowEvent()=#PB_Event_CloseWindow

Re: Animation & Motion tween FX

Posted: Mon Aug 19, 2013 7:18 pm
by eddy
here is a tiny tool to preview Tween FX graph

Image

Code: Select all

; *******************************
; EXAMPLE 3 - MULTI GRAPH TRACER
; *******************************

DisableExplicit
Enumeration
   #Window
   #Grapher
   #ListFX
EndEnumeration
If OpenWindow(#Window, 0, 0, 620, 410, "Tween Function Tester", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   CanvasGadget(#Grapher, 5, 5, 400, 400)
   ListViewGadget(#ListFX, 410, 5, 200, 400, #PB_ListView_MultiSelect |#PB_ListView_ClickSelect)
   ;{ LIST OF EFFECTS
   AddGadgetItem(#ListFX, -1, "#FX_Linear")
   
   AddGadgetItem(#ListFX, -1, "#FX_QuadEaseOut")
   AddGadgetItem(#ListFX, -1, "#FX_QuadEaseIn")
   AddGadgetItem(#ListFX, -1, "#FX_QuadEaseInOut")
   AddGadgetItem(#ListFX, -1, "#FX_QuadEaseOutIn")
   
   AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseOut")
   AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseIn")
   AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseInOut")
   AddGadgetItem(#ListFX, -1, "#FX_ExpoEaseOutIn")
   
   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")
   ;}
   countFX=CountGadgetItems(#ListFX)
   
   Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_Gadget And EventGadget()= #ListFX And EventType()= #PB_EventType_LeftClick
         
         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(w-5, 5, 1, h-10, RGB(200, 200, 200))
            
            Line(5, 5, 1, h-10, #Gray)
            Line(5, h/2, w-10, 1, #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(w-5, h/2, -5, 5, #Gray)
            Line(w-5, h/2, -5, -5, #Gray)
            
            DrawText(12, 5, "+1", #Red, 0)
            DrawText(12, h-18, "-1", #Red, 0)
            DrawText(12, h/2-20, "0", #Red, 0)
            DrawText(w-10, h/2-20, "d", #Red, 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/2
            finalX=h-5
            finalY=5
            moveX=finalX-startX-1
            moveY=finalY-startY
            
            For fx=#FX_FirstValue To #FX_LastValue
               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
                     x.f=Tween(#FX_Linear, t, startX, moveX, 400)
                     y.f=Tween(fx, t, startY, moveY, 400)
                     LineXY(prevX, prevY, x, y, color)
                     prevX=x
                     prevY=y
                  Next
                  ;}
               EndIf
            Next
            StopDrawing()
         EndIf
      EndIf
      
   Until Event = #PB_Event_CloseWindow
EndIf

Re: Animation & Motion tween FX

Posted: Mon Aug 26, 2013 2:10 am
by em_uk
Wow! Great work!

Re: Animation & Motion tween FX

Posted: Mon Aug 26, 2013 8:31 am
by DK_PETER
Very, VERY nice! :-)
Thank you for sharing, Eddy.

Re: Animation & Motion tween FX

Posted: Mon Aug 26, 2013 3:03 pm
by LuCiFeR[SD]
Eddy, this is really nice. Thanks very much :)

Re: Animation & Motion tween FX

Posted: Mon Sep 07, 2015 4:02 pm
by juankprada
I know this is an old thread, but I would like to ask permission to host this code in a github or bitbucket repository. I would like to make use of it and improve/add featues when possible.

Of course this would be if eddy accepts.

Pls let me know.

Re: Animation & Motion tween FX

Posted: Mon Sep 07, 2015 4:21 pm
by eddy
I've no objection to that. I'm not the original author.

I'm not sure about the licence type of this code (BSD or MIT)

Re: Animation & Motion tween FX

Posted: Mon Sep 07, 2015 4:54 pm
by juankprada
eddy, do you know who is the original author? I would not like to break any license here.

Thanks

Re: Animation & Motion tween FX

Posted: Mon Sep 07, 2015 7:37 pm
by Poshu
juankprada wrote:eddy, do you know who is the original author? I would not like to break any license here.
It's from http://robertpenner.com/easing/, under BSD Licence :
TERMS OF USE - EASING EQUATIONS

Open source under the BSD License.

Copyright © 2001 Robert Penner
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Re: Animation & Motion tween FX

Posted: Tue Sep 08, 2015 1:09 pm
by Kwai chang caine
Waooouhh !!! what words can i use !!! :shock:
Thanks for sharing 8)