Page 1 of 1

Tweening engine

Posted: Fri Dec 14, 2018 2:03 pm
by Papala
Hi ! Here is a module (EZEase) for a reaaaaly easy use of tweening based on this list of easeing.
Have fun !!

Code: Select all

DeclareModule EZEase
  ;{ Ease list
  #EZEase_easeLinear = "easeLinear"
  #EZEase_easeInQuad = "easeInQuad"
  #EZEase_easeOutQuad = "easeOutQuad"
  #EZEase_easeInOutQuad = "easeInOutQuad"
  #EZEase_easeInCubic = "easeInCubic"
  #EZEase_easeOutCubic = "easeOutCubic"
  #EZEase_easeInOutCubic = "easeInOutCubic"
  #EZEase_easeInQuart = "easeInQuart"
  #EZEase_easeOutQuart = "easeOutQuart"
  #EZEase_easeInOutQuart = "easeInOutQuart"
  #EZEase_easeInQuint = "easeInQuint"
  #EZEase_easeOutQuint = "easeOutQuint"
  #EZEase_easeInOutQuint = "easeInOutQuint"
  #EZEase_easeInSine = "easeInSine"
  #EZEase_easeOutSine = "easeOutSine"
  #EZEase_easeInOutSine = "easeInOutSine"
  #EZEase_easeInExpo = "easeInExpo"
  #EZEase_easeOutExpo = "easeOutExpo"
  #EZEase_easeInOutExpo = "easeInOutExpo"
  #EZEase_easeInCirc = "easeInCirc"
  #EZEase_easeOutCirc = "easeOutCirc"
  #EZEase_easeInOutCirc = "easeInOutCirc"
  #EZEase_easeInElastic = "easeInElastic"
  #EZEase_easeOutElastic = "easeOutElastic"
  #EZEase_easeInOutElastic = "easeInOutElastic"
  #EZEase_easeInBack = "easeInBack"
  #EZEase_easeOutBack = "easeOutBack"
  #EZEase_easeInOutBack = "easeInOutBack"
  #EZEase_easeInBounce = "easeInBounce"
  #EZEase_easeOutBounce = "easeOutBounce"
  #EZEase_easeInOutBounce = "easeInOutBounce"
  Enumeration #PB_EventType_FirstCustomValue
    #EZEase_EndEase
  EndEnumeration ;}
  Declare CreateEase(EaseType.s,StartValue.f,ChangeInValue.f,Duration.f)
  Declare FreeEase(*Ease)
  Declare InitEase(*Ease)
  Declare.f EaseResult(*Ease)
  Declare EditeEase(*Ease,StartValue.f,ChangeInValue.f,Duration.f)
EndDeclareModule

Module EZEase
  ;{ Declaration
  Structure Ease
    Type.s
    t.f
    b.f
    c.f
    d.f
  EndStructure
  Global NewList Ease.Ease()
  
  Prototype.f EaseName(t.f,b.f,c.f,d.f)
  
  Declare.f EaseLinear(t.f,b.f,c.f,d.f)
  Declare.f easeInQuad(t.f,b.f,c.f,d.f)
  Declare.f easeOutQuad(t.f,b.f,c.f,d.f)
  Declare.f easeInOutQuad(t.f,b.f,c.f,d.f)
  Declare.f easeInCubic(t.f,b.f,c.f,d.f)
  Declare.f easeOutCubic(t.f,b.f,c.f,d.f)
  Declare.f easeInOutCubic(t.f,b.f,c.f,d.f)
  Declare.f easeInQuart(t.f,b.f,c.f,d.f)
  Declare.f easeOutQuart(t.f,b.f,c.f,d.f)
  Declare.f easeInOutQuart(t.f,b.f,c.f,d.f)
  Declare.f easeInQuint(t.f,b.f,c.f,d.f)
  Declare.f easeOutQuint(t.f,b.f,c.f,d.f)
  Declare.f easeInOutQuint(t.f,b.f,c.f,d.f)
  Declare.f easeInSine(t.f,b.f,c.f,d.f)
  Declare.f easeOutSine(t.f,b.f,c.f,d.f)
  Declare.f easeInOutSine(t.f,b.f,c.f,d.f)
  Declare.f easeInExpo(t.f,b.f,c.f,d.f)
  Declare.f easeOutExpo(t.f,b.f,c.f,d.f)
  Declare.f easeInOutExpo(t.f,b.f,c.f,d.f)
  Declare.f easeInCirc(t.f,b.f,c.f,d.f)
  Declare.f easeOutCirc(t.f,b.f,c.f,d.f)
  Declare.f easeInOutCirc(t.f,b.f,c.f,d.f)
  Declare.f easeInElastic(t.f,b.f,c.f,d.f)
  Declare.f easeOutElastic(t.f,b.f,c.f,d.f)
  Declare.f easeInOutElastic(t.f,b.f,c.f,d.f)
  Declare.f easeInBack(t.f,b.f,c.f,d.f)
  Declare.f easeOutBack(t.f,b.f,c.f,d.f)
  Declare.f easeInOutBack(t.f,b.f,c.f,d.f)
  Declare.f easeInBounce(t.f,b.f,c.f,d.f)
  Declare.f easeOutBounce(t.f,b.f,c.f,d.f)
  Declare.f easeInOutBounce(t.f,b.f,c.f,d.f)
  ;}
  ; Public procedure
  Procedure CreateEase(EaseType.s,StartValue.f,ChangeInValue.f,Duration.f)
    AddElement(Ease())
    Ease()\Type  = EaseType
    Ease()\b = StartValue
    Ease()\c = ChangeInValue
    Ease()\d = Duration
    Ease()\t = ElapsedMilliseconds()
    ProcedureReturn @Ease()
  EndProcedure
 
  Procedure FreeEase(*Ease)
    ChangeCurrentElement(Ease(),*Ease)
    DeleteElement(Ease())
  EndProcedure
 
  Procedure InitEase(*Ease.Ease)
    *Ease\t = ElapsedMilliseconds()
  EndProcedure
 
  Procedure.f EaseResult(*Ease.Ease)
    Protected t.f = ElapsedMilliseconds() - *Ease\t, CallEase.EaseName = GetRuntimeInteger("EZEase::"+*Ease\Type + "()")
    If t > *Ease\d
      PostEvent(#EZEase_EndEase,0,0,0,*Ease)
      ProcedureReturn *Ease\c
    EndIf
    ProcedureReturn CallEase(t,*Ease\b,*Ease\c,*Ease\d)
  EndProcedure

  Procedure EditeEase(*Ease.Ease,StartValue.f,ChangeInValue.f,Duration.f)
    *Ease\b = StartValue
    *Ease\c = ChangeInValue
    *Ease\d = Duration
    *Ease\t = ElapsedMilliseconds()
  EndProcedure
  ; Private procedure
 
  Runtime Procedure.f easeLinear(t.f,b.f,c.f,d.f)
    ProcedureReturn c*t/d + b
  EndProcedure

  Runtime Procedure.f easeInQuad(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn c*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutQuad(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn -c *t*(t-2) + b
  EndProcedure

  Runtime Procedure.f easeInOutQuad(t.f,b.f,c.f,d.f)
    t = t/(d/2)
    If t < 1
      ProcedureReturn c/2*t*t+b
    EndIf
    t - 1
    ProcedureReturn -c/2 * (t*(t-2)-1) +b
  EndProcedure

  Runtime Procedure.f easeInCubic(t.f,b.f,c.f,d.f)
    t / d
    ProcedureReturn c*t*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutCubic(t.f,b.f,c.f,d.f)
    t = t / d - 1
    ProcedureReturn c*(t*t*t+1) + b
  EndProcedure

  Runtime Procedure.f easeInOutCubic(t.f,b.f,c.f,d.f)
    t= 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

  Runtime Procedure.f easeInQuart(t.f,b.f,c.f,d.f)
    t / d
    ProcedureReturn c*t*t*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutQuart(t.f,b.f,c.f,d.f)
    t = t / d - 1
    ProcedureReturn -c * (t*t*t*t - 1) + b
  EndProcedure

  Runtime Procedure.f easeInOutQuart(t.f,b.f,c.f,d.f)
    t = 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

  Runtime Procedure.f easeInQuint(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn c*t*t*t*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutQuint(t.f,b.f,c.f,d.f)
    t = t/d - 1
    ProcedureReturn c*(t*t*t*t*t+1) + b
  EndProcedure

  Runtime Procedure.f easeInOutQuint(t.f,b.f,c.f,d.f)
    t = 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

  Runtime Procedure.f easeInSine(t.f,b.f,c.f,d.f)
    ProcedureReturn -c * Cos(t/d * (#PI/2)) + c + b
  EndProcedure

  Runtime Procedure.f easeOutSine(t.f,b.f,c.f,d.f)
    ProcedureReturn c * Sin(t/d * (#PI/2)) + b
  EndProcedure

  Runtime Procedure.f easeInOutSine(t.f,b.f,c.f,d.f)
    ProcedureReturn -c/2 * Cos((#PI*t/d)-1) + b
  EndProcedure

  Runtime Procedure.f easeInExpo(t.f,b.f,c.f,d.f)
    If t = 0
      ProcedureReturn b
    EndIf
    ProcedureReturn c * Pow(2,10 * (t/d-1)) +b
  EndProcedure

  Runtime Procedure.f easeOutExpo(t.f,b.f,c.f,d.f)
    If t = d
      ProcedureReturn b+c
    EndIf
    ProcedureReturn c * (-Pow(2,-10*t/d)+1) + b
  EndProcedure

  Runtime Procedure.f easeInOutExpo(t.f,b.f,c.f,d.f)
    If t = 0 : ProcedureReturn b : EndIf
    If t = d : ProcedureReturn b+c : EndIf
    t = 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

  Runtime Procedure.f easeInCirc(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn -c * Sqr(1- (t*t-1)) + b
  EndProcedure

  Runtime Procedure.f easeOutCirc(t.f,b.f,c.f,d.f)
    t = t/d-1
    ProcedureReturn c * Sqr(1-t*t) + b
  EndProcedure

  Runtime Procedure.f easeInOutCirc(t.f,b.f,c.f,d.f)
    t = 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

  Runtime Procedure.f easeInElastic(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158, p.f = d * 0.3, a.f = c
    If t = 0 : ProcedureReturn b : EndIf
    t/d
    If t = 1 : ProcedureReturn b+c : EndIf
    If a < Abs(c)
      s = p/4
    Else
      s = p/(2*#PI) * ASin(c/a)
    EndIf
    t-1
    ProcedureReturn -(a*Pow(2,10*t) * Sin( (t*d-s)*(2*#PI)/p)) + b
  EndProcedure

  Runtime Procedure.f easeOutElastic(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158, p.f = d*0.3, a.f = c
    If t = 0 : ProcedureReturn b : EndIf
    t/d
    If t = 1 : ProcedureReturn b+c : EndIf
    If a < Abs(c)
      s = p/4
    Else
      s = p/(2*#PI) * ASin(c/a)
    EndIf
    ProcedureReturn a*Pow(2,-10*t)* Sin((t*d-s)*(2*#PI)/p) + c + b
  EndProcedure

  Runtime Procedure.f easeInOutElastic(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158, p.f = d*(0.3*1.5), a.f = c
    If a < Abs(c)
      s = p/4
    Else
      s = p/(2*#PI) * ASin(c/a)
    EndIf
    t-1
    If t < 1
      ProcedureReturn -0.5*(a*Pow(2,10*t)) * Sin((t*d-s)*(2*#PI)/p) + b
    EndIf
    ProcedureReturn a*Pow(2,-10*t) * Sin((t*d-s)*(2*#PI)/p )* 0.5 + c+b
  EndProcedure

  Runtime Procedure.f easeInBack(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158
    t/d
    ProcedureReturn c*t*t*((s+1)*t -s ) + b
  EndProcedure

  Runtime Procedure.f easeOutBack(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158
    t = t/d-1
    ProcedureReturn c*(t*t*((s+1)*t+s)+1)+b
  EndProcedure

  Runtime Procedure.f easeInOutBack(t.f,b.f,c.f,d.f)
    Protected s.f = 1.525
    t = t/(d/2)
    If t < 1
      ProcedureReturn c/2*(t*t*((s+1)*t-s))+b
    EndIf
    t-2
    ProcedureReturn c/2*(t*t*((s+1)*t+s)+2)+b
  EndProcedure

  Runtime Procedure.f easeInBounce(t.f,b.f,c.f,d.f)
    ProcedureReturn c- easeOutBounce(d-t,0,c,d)+b
  EndProcedure

  Runtime Procedure.f easeOutBounce(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 = t - 1.5/2.75
      ProcedureReturn c*(7.5626*t*t + 0.75)+b
    ElseIf t < 2.5/2.75
      t = t-2.25/2.75
      ProcedureReturn c*(7.5625*t*t+0.9375)+b
    Else
      t = t- 2.625/2.75
      ProcedureReturn c*(7.5625*t*t+0.984375) + b
    EndIf
  EndProcedure

  Runtime Procedure.f easeInOutBounce(t.f,b.f,c.f,d.f)
    If t < d/2
      ProcedureReturn easeInBounce(t*2,0,c,d)*0.5+b
    EndIf
    ProcedureReturn easeOutBounce(t*2-d,0,c,d) * 0.5+c*0.5+b
  EndProcedure


EndModule


CompilerIf #PB_Compiler_IsMainFile
  Procedure resetEase()
    EZEase::InitEase(EventData())
  EndProcedure
 
  OpenWindow(0,0,0,500,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  InitSprite()
  OpenWindowedScreen(WindowID(0),0,0,500,500)
  SetFrameRate(60)
  BindEvent(EZEase::#EZEase_EndEase,@resetEase())
  spr = CreateSprite(#PB_Any,20,20)
  StartDrawing(SpriteOutput(spr))
  Box(0,0,20,20,$1122FF)
  StopDrawing()
  Elastic = EZEase::CreateEase(EZEase::#EZEase_easeOutElastic,0,400,2000)
  Bounce = EZEase::CreateEase(EZEase::#EZEase_easeOutBounce,0,400,1000)
  Circ = EZEase::CreateEase(EZEase::#EZEase_easeOutCirc,0,400,1500)
  Back = EZEase::CreateEase(EZEase::#EZEase_easeOutBack,0,400,1800)
  Expo = EZEase::CreateEase(EZEase::#EZEase_easeInExpo,0,400,3000)
  time = ElapsedMilliseconds()
  Repeat
    ClearScreen($000000)
    DisplaySprite(spr,EZEase::EaseResult(Elastic),10)
    DisplaySprite(spr,EZEase::EaseResult(Bounce),40)
    DisplaySprite(spr,EZEase::EaseResult(Circ),70)
    DisplaySprite(spr,EZEase::EaseResult(Back),100)
    DisplaySprite(spr,EZEase::EaseResult(Expo),130)
    FlipBuffers()
  Until WindowEvent() = #PB_Event_CloseWindow
CompilerEndIf

Re: Tweening engine

Posted: Fri Dec 14, 2018 3:22 pm
by #NULL
Very nice :) Thank you.
I put the word easing here so I'll find this thread next time I need it.

Re: Tweening engine

Posted: Fri Dec 14, 2018 6:10 pm
by Papala
Thank #NULL ^^
Just a little update for some little bug fix and remove the huge Select I used.

Re: Tweening engine

Posted: Mon Dec 17, 2018 8:55 am
by dige
Cool! :D Thx for sharing!

Re: Tweening engine

Posted: Mon Dec 17, 2018 10:48 am
by Fred
Very cool module !

Re: Tweening engine

Posted: Mon Dec 17, 2018 4:10 pm
by skywalk
Wow, so eezy! 8)

Re: Tweening engine

Posted: Thu Feb 21, 2019 10:19 am
by Papala
Edit : little fix with the InOut, i'd forget some ()