[BMX] Image Fade In - Pause - Fade Out

Started by Filax, April 07, 2025, 16:14:58

Previous topic - Next topic

Filax

Code: BASIC
Function FadeImage(image:TImage, x:Float, y:Float, fadeInTime:Float, pauseTime:Float, fadeOutTime:Float)
    ' Paramètres :
    ' image : l'image à afficher
    ' x, y : position de l'image
    ' fadeInTime : durée du fondu d'entrée en secondes
    ' pauseTime : durée de la pause en secondes
    ' fadeOutTime : durée du fondu de sortie en secondes
    
    Local startTime:Int = MilliSecs()
    Local alpha:Float = 0.0
    Local state:Int = 0 ' 0 = fade in, 1 = pause, 2 = fade out
    
    ' Sauvegarde l'état actuel du canal alpha
    Local oldAlpha:Float = GetAlpha()
    SetBlend (ALPHABLEND)
	
    While True
        Cls
        
        ' Calcul du temps écoulé
        Local elapsed:Float = (MilliSecs() - startTime) / 1000.0
        
        Select state
            Case 0 ' Fade In
                alpha = elapsed / fadeInTime
                If alpha >= 1.0 Then
                    alpha = 1.0
                    state = 1
                    startTime = MilliSecs()
                End If
            
            Case 1 ' Pause
                alpha = 1.0
                If elapsed >= pauseTime Then
                    state = 2
                    startTime = MilliSecs()
                End If
            
            Case 2 ' Fade Out
                alpha = 1.0 - (elapsed / fadeOutTime)
                If alpha <= 0.0 Then
                    alpha = 0.0
                    Exit
                End If
        End Select
        
        ' Applique la transparence
        SetAlpha(alpha)
        
        ' Dessine l'image
        DrawImageRect(image, x, y, ImageWidth(image), ImageHeight(image))
        
        ' Restaure l'alpha par défaut pour d'autres dessins éventuels
        SetAlpha(oldAlpha)
        
        Flip
        If KeyHit(KEY_ESCAPE) Then Exit ' Sortie avec Échap
    Wend
    
    ' Restaure l'alpha initial
    SetAlpha(oldAlpha)
End Function

' Exemple d'utilisation :
Graphics 800, 600
Local img:TImage = LoadImage("G:\_GameArt Softs\Programmations\BlitzMax\Sources\DrawNodalNetWork\_Work\Logo_A.jpg") ' Remplace par ton image

' Appel de la fonction avec :
' - 2 secondes de fade in
' - 3 secondes de pause
' - 2 secondes de fade out
FadeImage(img, 100, 100, 2.0, 3.0, 2.0)

End

Filax

The same with a class:

Code: BASIC
SuperStrict
Type GuiCrossFade
    Field image:TImage
    Field x:Float, y:Float
    Field width:Float, height:Float
    Field alpha:Float
    Field state:Int         ' 0 = fade in, 1 = pause, 2 = fade out
    Field fadeInTime:Float
    Field pauseTime:Float
    Field fadeOutTime:Float
    Field currentTime:Float
    Field isFinished:Int
    
    Const STATE_FADEIN:Int = 0
    Const STATE_PAUSE:Int = 1
    Const STATE_FADEOUT:Int = 2
    ' Constructor
    Function Create:GuiCrossFade(image:TImage, x:Float, y:Float, Width:Float, Height:Float, fadeInDuration:Float, pauseDuration:Float, fadeOutDuration:Float)
        Local fade:GuiCrossFade = New GuiCrossFade
        fade.image = image
        fade.x = x
        fade.y = y
        fade.width = width
        fade.height = height
        fade.fadeInTime = fadeInDuration
        Fade.pauseTime = pauseDuration
        fade.fadeOutTime = fadeOutDuration
        fade.alpha = 0
        fade.state = STATE_FADEIN
        fade.currentTime = 0
        fade.isFinished = False
        Return fade
    End Function
    
    ' Method to update the state
    Method Update(deltaTime:Float)
        If isFinished Then Return
        currentTime :+ deltaTime
        
        Select state
            Case STATE_FADEIN
                alpha = currentTime / fadeInTime
                If currentTime >= fadeInTime Then
                    alpha = 1.0
                    state = STATE_PAUSE
                    currentTime = 0
                End If
                
            Case STATE_PAUSE
                If currentTime >= pauseTime Then
                    state = STATE_FADEOUT
                    currentTime = 0
                End If
                
            Case STATE_FADEOUT
                alpha = 1.0 - (currentTime / fadeOutTime)
                If CurrentTime >= fadeOutTime Then
                    alpha = 0
                    isFinished = True
                End If
        End Select
        
        Alpha = Max(0.0, Min(1.0, Alpha)) ' Clamp between 0 and 1
        
        Draw()
    End Method
    
    ' Method to draw
    Method Draw()
        If Not isFinished Then
            SetAlpha(Alpha)
                    
            SetBlend (ALPHABLEND)
            DrawImageRect(image, x, y, width, height)
            SetAlpha(1.0) ' Reset alpha to avoid affecting the rest
        End If
    End Method
    
    ' Checks if the animation is complete
    Method IsComplete:Int()
        Return isFinished
    End Method
End Type
' Example usage in a main program
Graphics 1920, 1080
Local img:TImage = LoadImage("G:\_GameArt Softs\Programmations\BlitzMax\Sources\DrawNodalNetWork\Opaline UI\Graphics\App_Logo.png") ' Replace with your image
Local Fade:GuiCrossFade = GuiCrossFade.Create(img, 100, 100, 1280, 400, 2.0, 3.0, 2.0) ' 2s fade in, 3s pause, 2s fade out
WaitKey()
While Not KeyHit(KEY_ESCAPE)
    Cls
    
    ' Update and draw the image with fade
    fade.Update(1.0/60.0) ' Assumes 60 FPS

    
    ' Your main code here
    DrawText "FPS: " + GetFPS(), 10, 10
    
    Flip
Wend
Function GetFPS:Int()
    Global frameCount:Int, lastTime:Int, fps:Int
    frameCount :+ 1
    Local currentTime:Int = MilliSecs()
    If currentTime - lastTime >= 1000 Then
        fps = frameCount
        frameCount = 0
        lastTime = currentTime
    End If
    Return fps
End Function


Derron

Just a hint:
If you set the alpha in a class (or the tint color or the rotation or ...) then you should reset it to the _original_ value, not a fixed one. The "outside" does not know what you do "inside" - so better leave the area as you found it when entering.

Local oldA:Float = GetAlpha()
Local oldCol:SColor8; GetColor(oldCol)
...mystuff
SetAlpha(oldA)
SetColor(oldCol)


Then another benefit is, that you can take into consideration existing "other fade outs" (just imagine your "parent" is also fading out or using a tint...)
SetAlpha oldA * myAlpha


bye
Ron