Documentation
¶
Overview ¶
Package anim is a backend-agnostic timeline driver for the go-widgets toolkit. It turns the host's existing per-frame tick (a tui EventTick, a wasm requestAnimationFrame callback, …) into wall-clock-eased animations, and suppresses idle frames once nothing is animating so the host can stop scheduling work (saving battery and CPU).
The driver owns no goroutine and no timer: the host owns the loop, exactly like the rest of the toolkit, whose widgets already expose a manual Tick(dt). The host calls Driver.Tick with the current wall-clock time each frame; when it returns busy=false the active set is empty and the host may stop scheduling frames until the next interaction starts a new animation.
Animations reuse the toolkit's existing toolkit.Easing curves, so the package makes easing.go load-bearing.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Animation ¶
type Animation struct {
// Dur is the wall-clock duration of the animation. A Dur <= 0 completes
// the animation on its very first tick (progress jumps straight to 1).
Dur time.Duration
// Ease shapes the linear 0..1 progress into the eased value handed to
// Apply. A nil Ease behaves as [toolkit.Linear].
Ease toolkit.Easing
// Apply pushes the eased progress (0..1) to the target each tick. A nil
// Apply makes the animation a pure timer (only OnEnd matters).
Apply func(progress float64)
// OnEnd, if non-nil, is called once when the animation completes.
OnEnd func()
}
Animation describes a single time-bounded animation. Its progress runs from 0 at the first tick after it starts to 1 at Dur, shaped by Ease, and is pushed to the target via Apply. OnEnd fires once, on the tick that reaches progress 1, right after the final Apply.
type Driver ¶
type Driver struct {
// contains filtered or unexported fields
}
Driver advances a set of active animations from the host's frame loop. It holds no goroutine and no timer; the zero value is ready to use, though NewDriver reads more clearly at call sites.
Example (Spinner) ¶
ExampleDriver_spinner drives a toolkit.Spinner's Phase from the anim Driver instead of the widget's manual Tick(dt). The host loop advances the driver with wall-clock time each frame and stops scheduling frames once Tick reports busy=false. This is the load-bearing consumer: the Spinner's cadence now comes from an eased anim.Animation over the toolkit's Easing curves.
package main
import (
"fmt"
"time"
"github.com/go-widgets/toolkit"
"github.com/go-widgets/toolkit/anim"
)
func main() {
sp := toolkit.NewSpinner()
sp.Active = true
d := anim.NewDriver()
// One full 0..1 phase sweep over 1s, linear so the spin is steady.
d.Start(&anim.Animation{
Dur: time.Second,
Ease: toolkit.Linear,
Apply: func(p float64) { sp.Phase = p },
})
// A fake host loop: step 250ms per frame, quit when the driver goes idle.
origin := time.Unix(0, 0)
for frame := 0; ; frame++ {
busy := d.Tick(origin.Add(time.Duration(frame) * 250 * time.Millisecond))
fmt.Printf("frame %d phase=%.2f busy=%v\n", frame, sp.Phase, busy)
if !busy {
break
}
}
}
Output: frame 0 phase=0.00 busy=true frame 1 phase=0.25 busy=true frame 2 phase=0.50 busy=true frame 3 phase=0.75 busy=true frame 4 phase=1.00 busy=false
func (*Driver) Start ¶
Start registers a to run and returns a Handle for cancelling it. The animation begins on the next Driver.Tick (that tick is progress 0). Start may grow the active set, but Driver.Tick itself never allocates.
func (*Driver) Tick ¶
Tick advances every active animation by the wall-clock delta since it started, calls each animation's Apply with the eased progress, fires OnEnd and removes any animation that has reached progress 1 (or was cancelled), and reports whether any animation remains active. When busy is false the active set is empty and the host may stop scheduling frames.
Tick performs no allocation: finished and cancelled entries are filtered in place, reusing the backing array.
func (*Driver) Tween ¶
func (d *Driver) Tween(tw *toolkit.Tween, dur time.Duration, set func(v float64), onEnd func()) *Handle
Tween is a convenience over Driver.Start that animates a scalar from the tween's From to its To over dur, shaped by the tween's Ease, invoking set with each interpolated value and onEnd (if non-nil) once at the end. It reuses the toolkit's toolkit.Tween fields, making easing.go's Tween load-bearing here too. The integer Tween.Duration (tick-based) is ignored in favour of the wall-clock dur.
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle refers to a running animation so the caller can cancel it. It is returned by Driver.Start; a zero Handle is not useful on its own.
func (*Handle) Cancel ¶
func (h *Handle) Cancel()
Cancel stops the animation before it completes. The next Driver.Tick drops it without a further Apply and without firing OnEnd. Cancelling an already-finished (or already-cancelled) animation is a harmless no-op.