package main import ( "time" 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 startTime time.Time phase TransitionPhase direction TransitionDirection oldStep int newStep int outFadeScaleDuration time.Duration outSlideDuration time.Duration inFadeScaleDuration time.Duration } func NewTransitionManager() *TransitionManager { return &TransitionManager{ outFadeScaleDuration: 150 * time.Millisecond, outSlideDuration: 200 * time.Millisecond, inFadeScaleDuration: 150 * time.Millisecond, } } func (t *TransitionManager) Start(oldStep, newStep int) { t.active = true t.startTime = time.Now() t.phase = TransitionOutFadeScale t.oldStep = oldStep t.newStep = newStep if newStep > oldStep { t.direction = DirectionForward } else { t.direction = DirectionBackward } } 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 } elapsed := time.Since(t.startTime) total := t.outFadeScaleDuration + t.outSlideDuration + t.inFadeScaleDuration if elapsed >= total { return TransitionNone } else if elapsed < t.outFadeScaleDuration { return TransitionOutFadeScale } else if elapsed < t.outFadeScaleDuration+t.outSlideDuration { return TransitionOutSlide } else { return TransitionInFadeScale } } func (t *TransitionManager) Update() (oldAlpha float32, oldScale float32, oldOffsetX float32, newAlpha float32, newScale float32, newOffsetX float32) { if !t.active { return 1.0, 1.0, 0.0, 1.0, 1.0, 0.0 } elapsed := time.Since(t.startTime) totalDuration := t.outFadeScaleDuration + t.outSlideDuration + t.inFadeScaleDuration if elapsed >= totalDuration { // Transition done t.active = false return 1.0, 1.0, 0.0, 1.0, 1.0, 0.0 } oldAlpha = 1.0 oldScale = 1.0 oldOffsetX = 0.0 newAlpha = 1.0 newScale = 1.0 newOffsetX = 0.0 slideDirection := float32(-1) if t.direction == DirectionBackward { slideDirection = 1 } if elapsed < t.outFadeScaleDuration { // Phase 1: Out Fade/Scale progress := float32(elapsed.Milliseconds()) / float32(t.outFadeScaleDuration.Milliseconds()) oldAlpha = 1.0 - 0.2*progress oldScale = 1.0 - 0.1*progress // New tab not visible at all yet newAlpha = 0.0 newScale = 0.9 newOffsetX = float32(rl.GetScreenWidth()) * slideDirection } else if elapsed < t.outFadeScaleDuration+t.outSlideDuration { // Phase 2: Slide out old, slide in new phaseElapsed := elapsed - t.outFadeScaleDuration progress := float32(phaseElapsed.Milliseconds()) / float32(t.outSlideDuration.Milliseconds()) oldAlpha = 0.8 oldScale = 0.9 oldOffsetX = -float32(rl.GetScreenWidth()) * progress * slideDirection newAlpha = 0.8 newScale = 0.9 newOffsetX = float32(rl.GetScreenWidth()) * (1.0 - progress) * slideDirection } else { // Phase 3: In Fade/Scale phaseElapsed := elapsed - t.outFadeScaleDuration - t.outSlideDuration progress := float32(phaseElapsed.Milliseconds()) / float32(t.inFadeScaleDuration.Milliseconds()) oldAlpha = 0.0 oldScale = 0.9 oldOffsetX = -float32(rl.GetScreenWidth()) * slideDirection newAlpha = 0.8 + 0.2*progress newScale = 0.9 + 0.1*progress newOffsetX = 0.0 } return oldAlpha, oldScale, oldOffsetX, newAlpha, newScale, newOffsetX }