Results 1 to 5 of 5

Thread: How do I interpolate 2 animations

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Question How do I interpolate 2 animations

    Hello!

    I am dealing with the transitions between 2 states.

    I am trying to mimick a Unity transition.

    I am experiencing weird color flashes while I expect gradual transitions.
    This makes me wonder if I am not aware of a problem.

    Thank you for having a look at my code.

    This is the code of a cTransition class:

    Code:
    Public Sub UpdateTransition()
    
        If Not Me.IsActive Then
            Exit Sub
        End If
        
        Dim lNow&
        lNow = GetTickCount
    
        Dim lTaken&
        lTaken = lNow - m_lStartTime
    
        Me.Progress = lTaken / GetEffectiveDuration(Me.Duration)
        
        Debug.Print "----------"
        m_s = "Progress: " & Me.Progress & vbNewLine
        
        Clamp Me.Progress, 0, 1
    
        ' Update animations
        modAnim.UpdateAnimation m_StartAnimationConfig, lNow
        modAnim.UpdateAnimation m_TargetAnimationConfig, lNow
        
        If lTaken >= GetEffectiveDuration(Me.Duration) Then
            ' Transition is complete
            m_bIsTransitionComplete = True
            Me.IsActive = False
            Exit Sub
        End If
    
        ' Calculate current size using weighted interpolation
        Dim currentSizeStart As Double
        Dim currentSizeTarget As Double
        currentSizeStart = m_StartAnimationConfig.StartSizeFactor + _
                           (m_StartAnimationConfig.TargetSizeFactor - m_StartAnimationConfig.StartSizeFactor) * _
                           Ease(Me.Progress, m_StartAnimationConfig.FunctionType, m_StartAnimationConfig.ModeType)
    
        currentSizeTarget = m_TargetAnimationConfig.StartSizeFactor + _
                            (m_TargetAnimationConfig.TargetSizeFactor - m_TargetAnimationConfig.StartSizeFactor) * _
                            Ease(Me.Progress, m_TargetAnimationConfig.FunctionType, m_TargetAnimationConfig.ModeType)
    
        Me.CurrentSize = (currentSizeTarget * Me.Progress) + (currentSizeStart * (1 - Me.Progress))
    
        ' Calculate current alpha using weighted interpolation
        Dim currentAlphaStart As Double
        Dim currentAlphaTarget As Double
        currentAlphaStart = m_StartAnimationConfig.StartAlpha + _
                            (m_StartAnimationConfig.TargetAlpha - m_StartAnimationConfig.StartAlpha) * _
                            Ease(Me.Progress, m_StartAnimationConfig.FunctionType, m_StartAnimationConfig.ModeType)
    
        currentAlphaTarget = m_TargetAnimationConfig.StartAlpha + _
                             (m_TargetAnimationConfig.TargetAlpha - m_TargetAnimationConfig.StartAlpha) * _
                             Ease(Me.Progress, m_TargetAnimationConfig.FunctionType, m_TargetAnimationConfig.ModeType)
    
        Me.CurrentAlpha = (currentAlphaTarget * Me.Progress) + (currentAlphaStart * (1 - Me.Progress))
    
        ' Calculate current color using BlendColors
        Me.CurrentColor = BlendColors(m_TargetAnimationConfig.TargetColor, m_StartAnimationConfig.StartColor, Me.Progress)
    And this is sub to apply the current progress to the size and color of the objects that I want to animate:

    Code:
    Public Function GetEffectiveDuration(ByVal u As Double) As Double
    
        If g_Slowmo = 0 Then
            g_Slowmo = 1
        End If
        
        GetEffectiveDuration = u * g_Slowmo
    
    End Function
    
    Public Sub UpdateAnimation(ByRef u As cAnimationConfig, ByVal uCurrentTime As Long)
    
        Dim lDur&
        lDur = uCurrentTime - u.StartTime
    
        u.DontUseThisForEndResult_Progress = lDur / GetEffectiveDuration(u.Duration) 'GetEffectiveDuration is a helper function to make Duration bigger to slow down the animation for inspecting
        
        'clamp
        Clamp u.DontUseThisForEndResult_Progress, 0, 1
    
        If u.DontUseThisForEndResult_Progress > 1 Then
            u.DontUseThisForEndResult_Progress = 1
        ElseIf u.DontUseThisForEndResult_Progress < 0 Then
            u.DontUseThisForEndResult_Progress = 0
        End If
    
        If lDur >= GetEffectiveDuration(u.Duration) Then
        
            u.IsActive = False
    
            If u.IsOneShot Then
                'can not repeat
                Exit Sub
            Else
                u.IsActive = True 'start again
                u.StartTime = GetTickCount
                'reset and make it play again
                If u.PlayMirroredIfLooped Then
                    u.IsPlayingMirrored = Not u.IsPlayingMirrored
                End If
                u.DontUseThisForEndResult_Progress = 0
            End If
        End If
        
        u.EffectiveProgress = modAnim.GetAnimationProgress(u.DontUseThisForEndResult_Progress, u.IsPlayingMirrored)
        u.EasedEffectiveProgress = Ease(u.EffectiveProgress, u.FunctionType, u.ModeType)
        u.CurrentSize = u.SizeFactorAtStart + ((u.SizeFactorAtEnd - u.SizeFactorAtStart) * u.EasedEffectiveProgress)
        u.CurrentColor = BlendColors(u.StartColor, u.TargetColor, 1 - u.EffectiveProgress) 'dont use easing for color, instead use linear
        
    End Sub
    Last edited by tmighty2; Sep 30th, 2024 at 03:40 AM.

  2. #2

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: How do I interpolate 2 animations

    I can describe the problem now:

    I need to transition from one animation to another.

    Each animation has a StartColor and a TargetColor and a StartAlpha and a TargetAlpha.

    So I need to interpolate between these 4 RGB values and 4 Alpha values in respect to the progress of the transition.
    Additionally, I must fade the Start Animation out, and I must fade the Target Animation out during the transition.

    I don't know if I should use yet another Alpha value for that.

    But that is what my head is currently spinning around and which won't work as I get crazy colors.

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: How do I interpolate 2 animations

    Could somebody tell me (reliably) how to do this? This would help me really much.

    Already knowing how to fade color 1 out and color 2 in using alpha would be helpful.

  4. #4
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: How do I interpolate 2 animations

    Quote Originally Posted by tmighty2 View Post
    Could somebody tell me (reliably) how to do this?
    As far as "blending between 2 colors" is the problem -
    I don't see "two animations" - but only one instead:

    Below is a demo for an empty Form (Project needs an RC6-reference) -
    ...a Form_Click starts an animation from Blue(0.7) to Red(0.7)...
    Code:
    Option Explicit
    
    Private WithEvents E As cEasing, CC As cCairoContext
    Private C1 As Long, A1 As Double, C2 As Long, A2 As Double
    
    Private Sub Form_Load()
      Set E = New_c.Easing
      Set CC = Cairo.CreateSurface(256, 256).CreateContext
    End Sub
     
    Private Sub Form_Click()
      C1 = vbBlue: A1 = 0.7 'start-color and start-alpha
      C2 = vbRed:  A2 = 0.7 'end-color and end-alpha
      
      'now we use the Animate-HelperMethod in "non-Ctl-bound mode" with 1.5sec duration...
      E.Animate Nothing, 0, 0, 0, 0, 0, 0, 0, 0, _
                1.5, easeCubic, easeIn '...meaning, the above line contains all Zero-Params
    End Sub
    
    Private Sub E_AnimationProgress(ByVal DurationPerc As Double, ByVal EaseRes As Double)
      Caption = Format$(DurationPerc, "0%")
      RedrawWith EaseRes
    End Sub
    Private Sub E_AnimationFinished()
      Caption = Format$(1, "0%")
      RedrawWith 1
    End Sub
    
    Sub RedrawWith(ByVal EaseRes As Double)
      CC.Paint 1, Cairo.CreateCheckerPattern
      
      CC.Arc CC.Surface.Width / 2, CC.Surface.Height / 2, 100
      CC.Fill True, Cairo.CreateSolidPatternLng(C1, A1 * (1 - EaseRes)) 'use the Alpha-Param "multiplicative"
      CC.Fill False, Cairo.CreateSolidPatternLng(C2, A2 * EaseRes) 'use the Alpha-Param "multiplicative"
      
      Set Picture = CC.Surface.Picture
    End Sub
    Olaf

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: How do I interpolate 2 animations

    Thank you. This demo is very nice.

    I was however trying to get to know what would be a legitimate way to really get a new color instead of drawing 2 colors over each other.

    Here is what I came up with:

    Code:
    Public Sub CombineTransitionColorsWithAlpha(ByVal uStartColor As Long, ByVal uStartAlpha As Double, ByVal uTargetColor As Long, ByVal uTargetAlpha As Double, ByVal uProgress As Double, ByRef uResultRGB As Long, ByRef uResultAlpha As Double)
        Dim r1 As Integer, g1 As Integer, b1 As Integer
        Dim r2 As Integer, g2 As Integer, b2 As Integer
        Dim rBlend As Integer, gBlend As Integer, bBlend As Integer
        Dim effectiveStartAlpha As Double, effectiveTargetAlpha As Double
        Dim combinedAlpha As Double
    
        If uProgress < 0 Or uProgress > 1 Then
            Debug.Assert False
            Exit Sub
        End If
        
        ' Extract RGB components from uStartColor
        r1 = uStartColor And &HFF
        g1 = (uStartColor \ &H100) And &HFF
        b1 = (uStartColor \ &H10000) And &HFF
        
        ' Extract RGB components from uTargetColor
        r2 = uTargetColor And &HFF
        g2 = (uTargetColor \ &H100) And &HFF
        b2 = (uTargetColor \ &H10000) And &HFF
        
        ' Calculate effective alpha for each color based on progress
        effectiveStartAlpha = uStartAlpha * (1 - uProgress) ' Fade out the start color
        effectiveTargetAlpha = uTargetAlpha * uProgress      ' Fade in the target color
    
        ' Calculate combined alpha (final alpha for the blended color)
        combinedAlpha = effectiveStartAlpha + effectiveTargetAlpha
    
        ' Blend RGB components based on the effective alpha of each color
        If combinedAlpha > 0 Then
            rBlend = (r1 * effectiveStartAlpha + r2 * effectiveTargetAlpha) / combinedAlpha
            gBlend = (g1 * effectiveStartAlpha + g2 * effectiveTargetAlpha) / combinedAlpha
            bBlend = (b1 * effectiveStartAlpha + b2 * effectiveTargetAlpha) / combinedAlpha
        Else
            rBlend = 0
            gBlend = 0
            bBlend = 0
        End If
    
        ' Ensure RGB values are within valid range [0, 255]
        rBlend = IIf(rBlend > 255, 255, IIf(rBlend < 0, 0, rBlend))
        gBlend = IIf(gBlend > 255, 255, IIf(gBlend < 0, 0, gBlend))
        bBlend = IIf(bBlend > 255, 255, IIf(bBlend < 0, 0, bBlend))
    
        ' Return the blended RGB and alpha results
        uResultRGB = RGB(CLng(rBlend), CLng(gBlend), CLng(bBlend))
        uResultAlpha = combinedAlpha
    
    End Sub

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width