package main import ( rl "github.com/gen2brain/raylib-go/raylib" ) // CircleAnimator manages both the position/radius alpha (0..1) // and the displayed progress which eases toward the actual SPM progress. type CircleAnimator struct { PosAlpha float32 // 0 => top-right, 1 => center DisplayProgress float32 // The "smooth" progress shown on screen targetStep int // The step controlling circle's final position (0..2 => top-right, 3 => center) // For smoothing the circle position alpha with "easeInOutCubic" accumSec float32 duration float32 startAlpha float32 endAlpha float32 // For smoothing the displayed progress // We'll do a simple exponential approach each frame. // Alternatively, you could do a time-based tween. smoothingFactor float32 // e.g. 0.1 => about 10% approach per frame } // NewCircleAnimator sets initial defaults func NewCircleAnimator() *CircleAnimator { return &CircleAnimator{ PosAlpha: 0.0, // start at top-right DisplayProgress: 0.0, duration: 1.0, // 1 second total for position tween smoothingFactor: 0.07, // how fast progress approaches real } } // SetStep sets whether we want circle in top-right (step<3 => alpha=0) or center (step=3 => alpha=1). // This starts a new positional tween from current alpha to the new alpha. func (c *CircleAnimator) SetStep(step int) { c.targetStep = step var newEnd float32 = 0.0 if step == 3 { newEnd = 1.0 } // Start new tween from current alpha to newEnd c.startAlpha = c.PosAlpha c.endAlpha = newEnd c.accumSec = 0 } // Update updates both the position alpha (with easeInOutCubic) and the displayed progress. func (c *CircleAnimator) Update(realProgress int) { dt := rl.GetFrameTime() // seconds // 1) Update position alpha if c.accumSec < c.duration { c.accumSec += dt if c.accumSec > c.duration { c.accumSec = c.duration } p := c.accumSec / c.duration eased := easeInOutCubic(p) // Lerp from startAlpha to endAlpha with eased fraction c.PosAlpha = c.startAlpha + (c.endAlpha-c.startAlpha)*eased } else { // no active tween, just keep the final alpha c.PosAlpha = c.endAlpha } // 2) Smoothly approach the real progress // (exponential approach: new = old + factor*(target - old)) target := float32(realProgress) c.DisplayProgress += c.smoothingFactor * (target - c.DisplayProgress) }