Transition_CubicBezier

Syntax

Value.d = Transition_CubicBezier(t.d, b.d, c.d, d.d, P1x.d, P1y.d, P2x.d, P2y.d)

Description

Calculates an intermediate value using a custom cubic Bezier curve defined by two control points (P1x, P1y) and (P2x, P2y). This allows for highly customizable easing curves, matching the functionality of CSS `cubic-bezier()`.

The function solves the Bezier equation for the time parameter `t` based on the horizontal control points (P1x, P2x) and then uses that time to calculate the vertical position (output value) based on the vertical control points (P1y, P2y).

Parameters

t.d
The current elapsed time of the animation in milliseconds.

b.d
The starting value of the property being animated.

c.d
The total change in value (target value - starting value).

d.d
The total duration of the animation in milliseconds.

P1x.d, P1y.d
The coordinates of the first control point. Values should typically be between 0.0 and 1.0.

P2x.d, P2y.d
The coordinates of the second control point. Values should typically be between 0.0 and 1.0.

Return Value

Returns the interpolated value (Double) at the current time `t` according to the specified cubic Bezier curve.

Remarks

This is the most flexible transition function, allowing replication of standard CSS easing functions (like `ease`, `ease-in`, `ease-out`, `ease-in-out`) and creation of unique curves. The predefined Transition_Ease* functions are implemented using this function internally with specific control point values.

Example control point values for standard CSS easings:

Example

IncludeFile "ProGUI_PB.pbi"

Structure MyAnimData
  TargetValue.d
  StartValue.d
  x.d
EndStructure

Procedure DrawHandler(Window, EventType, *EventData.PG_EventDraw, *UserData.MyAnimData)
  
    DrawClear(RGB(200, 200, 200), 1) ; Grey background

    ; Draw a box whose X position is animated
    DrawBox(*UserData\x, (*EventData\height / 2) - 25, 50, 50, RGB(0, 0, 255))
    
EndProcedure

Procedure AnimateHandler(Window, EventType, *EventData.PG_EventAnimate, *UserData.MyAnimData)
  
  Select *EventData\state
  
    Case #PG_Event_Animate_Start

      Debug "Cubic Bezier animation started."
      
    Case #PG_Event_Animate_Update

      ; Calculate intermediate value using a custom cubic-bezier curve
      ; Example: A curve that overshoots slightly then settles (similar to an ease-out-back effect)
      *UserData\x = Transition_CubicBezier(*EventData\currentTime, *UserData\StartValue, *UserData\TargetValue - *UserData\StartValue, *EventData\duration, 0.34, 1.56, 0.64, 1) 
      
      WindowRedraw(Window)

      ; Debug "Animation Update: Time=" + *EventData\currentTime + "ms, Value=" + StrD(*UserData\x)
      
    Case #PG_Event_Animate_End

      Debug "Animation ended"
      ; Ensure final value is set exactly
      *UserData\x = *UserData\TargetValue
      WindowRedraw(Window)
      ; Optional: Restart animation or clean up
      ; FreeStructure(*UserData)

  EndSelect

EndProcedure

StartProGUI()

MyWindow = CreateWindow(0, 0, 300, 200, "Transition_CubicBezier Example")

If MyWindow
    
  ; Setup data for animation
  *AnimData.MyAnimData = AllocateStructure(MyAnimData)
  *AnimData\StartValue = 10
  *AnimData\TargetValue = 200
    
  AddEventHandler(MyWindow, #PG_Event_Draw, @DrawHandler(), *AnimData)
  AddEventHandler(MyWindow, #PG_Event_Animate, @AnimateHandler(), *AnimData)

  ; Start a 2-second animation
  AnimID = StartAnimation(MyWindow, #PG_Any, 2000)
  Debug "Started animation with ID: " + AnimID

  WindowShow(MyWindow, #True, #PG_Window_ScreenCentered)
  Repeat : Event = WaitWindowEvent() : Until Event = #PB_Event_CloseWindow
  
  StopAnimation(MyWindow, AnimID) ; Stop if still running
  FreeStructure(*AnimData)
  
EndIf 

StopProGUI()

See Also

Transition_Ease, Transition_EaseIn, Transition_EaseOut, Transition_EaseInOut, StartAnimation

Supported OS

Windows, Linux