Installer/transition.go

185 lines
3.9 KiB
Go
Raw Normal View History

2024-12-20 18:58:53 +01:00
package main
import (
rl "github.com/gen2brain/raylib-go/raylib"
)
type TransitionPhase int
const (
TransitionNone TransitionPhase = iota
TransitionOutFadeScale
TransitionOutSlide
TransitionInFadeScale
)
type TransitionDirection int
const (
DirectionForward TransitionDirection = iota
DirectionBackward
)
type TransitionManager struct {
active bool
direction TransitionDirection
2024-12-21 09:33:30 +01:00
oldStep int
newStep int
// Single total transition duration (seconds)
totalSec float32
// Sub-phase fractions (must sum to 1.0)
fadeFrac float32
slideFrac float32
inFrac float32
// Where we store the linear boundary of the sub-phase in [0..1]
fadeEnd float32
slideEnd float32
// Accumulated time in seconds
accumSec float32
2024-12-20 18:58:53 +01:00
}
2024-12-21 09:33:30 +01:00
// NewTransitionManager with one total duration, e.g. 0.5 seconds total
// Sub-phase fractions: fade=0.3, slide=0.4, fadeIn=0.3 (they sum to 1.0)
2024-12-20 18:58:53 +01:00
func NewTransitionManager() *TransitionManager {
return &TransitionManager{
2024-12-21 09:33:30 +01:00
totalSec: 0.6, // e.g., entire transition 600ms
fadeFrac: 0.3, // 30% of total time for fade out scale
slideFrac: 0.4, // 40% of total time for slide
inFrac: 0.3, // 30% of total time for fade in scale
2024-12-20 18:58:53 +01:00
}
}
func (t *TransitionManager) Start(oldStep, newStep int) {
t.active = true
2024-12-21 09:33:30 +01:00
t.accumSec = 0
2024-12-20 18:58:53 +01:00
t.oldStep = oldStep
t.newStep = newStep
2024-12-21 09:33:30 +01:00
2024-12-20 18:58:53 +01:00
if newStep > oldStep {
t.direction = DirectionForward
} else {
t.direction = DirectionBackward
}
2024-12-21 09:33:30 +01:00
// Precompute sub-phase boundaries in [0..1]
t.fadeEnd = t.fadeFrac
t.slideEnd = t.fadeFrac + t.slideFrac
// Final inFrac ends at 1.0
2024-12-20 18:58:53 +01:00
}
func (t *TransitionManager) IsActive() bool {
return t.active
}
// GetPhase returns which phase the transition is currently in.
func (t *TransitionManager) GetPhase() TransitionPhase {
if !t.active {
return TransitionNone
}
2024-12-21 09:33:30 +01:00
// Determine the linear progress
p := t.accumSec / t.totalSec
if p < t.fadeEnd {
2024-12-20 18:58:53 +01:00
return TransitionOutFadeScale
2024-12-21 09:33:30 +01:00
} else if p < t.slideEnd {
2024-12-20 18:58:53 +01:00
return TransitionOutSlide
} else {
return TransitionInFadeScale
}
}
2024-12-21 09:33:30 +01:00
// Easing function: "easeInOutCubic" => pronounced slow start, fast middle, slow end
func easeInOutCubic(p float32) float32 {
if p < 0.5 {
return 4 * p * p * p
}
f := (2 * p) - 2
return 0.5*f*f*f + 1
}
// Update returns alpha/scale/offset for old/new steps
func (t *TransitionManager) Update() (
oldAlpha, oldScale, oldOffsetX float32,
newAlpha, newScale, newOffsetX float32,
) {
2024-12-20 18:58:53 +01:00
if !t.active {
2024-12-21 09:33:30 +01:00
return 1, 1, 0, 1, 1, 0
2024-12-20 18:58:53 +01:00
}
2024-12-21 09:33:30 +01:00
// Accumulate variable time
dt := rl.GetFrameTime() // in seconds
t.accumSec += dt
if t.accumSec >= t.totalSec {
2024-12-20 18:58:53 +01:00
t.active = false
2024-12-21 09:33:30 +01:00
return 1, 1, 0, 1, 1, 0
2024-12-20 18:58:53 +01:00
}
2024-12-21 09:33:30 +01:00
oldAlpha, oldScale, oldOffsetX = 1, 1, 0
newAlpha, newScale, newOffsetX = 1, 1, 0
2024-12-20 18:58:53 +01:00
2024-12-22 19:55:20 +01:00
slideDir := float32(1)
2024-12-20 18:58:53 +01:00
if t.direction == DirectionBackward {
2024-12-22 19:55:20 +01:00
slideDir = -1
2024-12-21 09:33:30 +01:00
}
p := t.accumSec / t.totalSec
if p > 1 {
p = 1
2024-12-20 18:58:53 +01:00
}
2024-12-21 09:33:30 +01:00
globalP := easeInOutCubic(p)
2024-12-20 18:58:53 +01:00
2024-12-21 09:33:30 +01:00
if p < t.fadeEnd {
gEnd := easeInOutCubic(t.fadeEnd)
subE := float32(0)
if gEnd > 0 {
subE = globalP / gEnd
}
oldAlpha = 1 - 0.2*subE
oldScale = 1 - 0.1*subE
newAlpha = 0
2024-12-20 18:58:53 +01:00
newScale = 0.9
2024-12-21 09:33:30 +01:00
newOffsetX = float32(rl.GetScreenWidth()) * slideDir
} else if p < t.slideEnd {
gStart := easeInOutCubic(t.fadeEnd)
gEnd := easeInOutCubic(t.slideEnd)
gRange := gEnd - gStart
subE := float32(0)
if gRange > 0 {
subE = (globalP - gStart) / gRange
}
2024-12-20 18:58:53 +01:00
oldAlpha = 0.8
oldScale = 0.9
2024-12-21 09:33:30 +01:00
oldOffsetX = -float32(rl.GetScreenWidth()) * subE * slideDir
2024-12-20 18:58:53 +01:00
newAlpha = 0.8
newScale = 0.9
2024-12-21 09:33:30 +01:00
newOffsetX = float32(rl.GetScreenWidth()) * (1 - subE) * slideDir
2024-12-20 18:58:53 +01:00
2024-12-21 09:33:30 +01:00
} else {
gStart := easeInOutCubic(t.slideEnd)
gEnd := easeInOutCubic(1)
gRange := gEnd - gStart
subE := float32(0)
if gRange > 0 {
subE = (globalP - gStart) / gRange
}
oldAlpha = 0
2024-12-20 18:58:53 +01:00
oldScale = 0.9
2024-12-21 09:33:30 +01:00
oldOffsetX = -float32(rl.GetScreenWidth()) * slideDir
newAlpha = 0.8 + 0.2*subE
newScale = 0.9 + 0.1*subE
newOffsetX = 0
2024-12-20 18:58:53 +01:00
}
return oldAlpha, oldScale, oldOffsetX, newAlpha, newScale, newOffsetX
}