Package github.com/matjam/bunyip/tween
tween
Package tween animates values over time. A Tween moves a number from one value to another with an easing curve, and Sequence chains them.
To make a tween, call New with a start, an end, a duration in seconds and an Ease. The usual easing curves are provided, and any func(t float32) float32 works. Call Update each step to advance a tween, then read Value, or set OnDone to be called when it finishes. Use tweens for menus sliding in, health bars draining, cameras easing to a target and damage numbers floating up. NewSequence runs several in order. For keyframed curves over vectors, colours and component fields, see the anim package. Tweens and sequences are not safe for concurrent use; advance them with finite, nonnegative steps on the game loop goroutine.
Index
- type Ease
- type Of
func NewOf[V any](from, to V, seconds float32, ease Ease, lerp func(a, b V, t float32) V) *Of[V]func NewVec2(from, to lin.Vec2, seconds float32, ease Ease) *Of[lin.Vec2]func NewVec3(from, to lin.Vec3, seconds float32, ease Ease) *Of[lin.Vec3]func (o *Of[V]) OnDone(f func()) *Of[V]func (o *Of[V]) Update(dt float32) Vfunc (o *Of[V]) Value() V
- type Sequence
- type Tween
Types
type Ease source
type Ease func(t float32) float32
Ease maps progress t in [0,1] to eased progress.
var (
Linear Ease = func(t float32) float32 { return t }
InQuad Ease = func(t float32) float32 { return t * t }
OutQuad Ease = func(t float32) float32 { return t * (2 - t) }
InOutQuad Ease = func(t float32) float32 { return inOut(t, InQuad, OutQuad) }
InCubic Ease = func(t float32) float32 { return t * t * t }
OutCubic Ease = func(t float32) float32 { u := 1 - t; return 1 - u*u*u }
InOutCubic Ease = func(t float32) float32 { return inOut(t, InCubic, OutCubic) }
InSine Ease = func(t float32) float32 { return 1 - cos(t*math.Pi/2) }
OutSine Ease = func(t float32) float32 { return sin(t * math.Pi / 2) }
InOutSine Ease = func(t float32) float32 { return (1 - cos(t*math.Pi)) / 2 }
Smoothstep Ease = func(t float32) float32 { return t * t * (3 - 2*t) }
OutBack Ease = func(t float32) float32 {
const c1, c3 = 1.70158, 2.70158
u := t - 1
return 1 + c3*u*u*u + c1*u*u
}
OutElastic Ease = func(t float32) float32 {
if t <= 0 || t >= 1 {
return clamp01(t)
}
const c4 = 2 * math.Pi / 3
return pow2(-10*t)*sin((t*10-0.75)*c4) + 1
}
OutBounce Ease = func(t float32) float32 {
const n1, d1 = 7.5625, 2.75
switch {
case t < 1/d1:
return n1 * t * t
case t < 2/d1:
t -= 1.5 / d1
return n1*t*t + 0.75
case t < 2.5/d1:
t -= 2.25 / d1
return n1*t*t + 0.9375
default:
t -= 2.625 / d1
return n1*t*t + 0.984375
}
}
)
Easing curves. In* start slowly, Out* end slowly, InOut* do both.
type Of source
type Of[V any] struct {
*Tween
From, To V // blend endpoints
Lerp func(a, b V, t float32) V // required blend function, called with eased progress
}
Of animates any value that can be blended: a position, a colour, a size. It wraps a Tween for the timing (delay, repeats, yo-yo, easing) and a Lerp function for the blend, so gfx.Color.Lerp, lin.Vec3.Lerp or a game's own mix all work:
fade := tween.NewOf(gfx.Transparent, gfx.White, 0.5, tween.OutQuad, gfx.Color.Lerp) tint := fade.Update(dt)
NewOf source
func NewOf[V any](from, to V, seconds float32, ease Ease, lerp func(a, b V, t float32) V) *Of[V]
NewOf makes a tween over any value with a blend function; a nil ease is linear. The blend function must be non-nil. Delay, Repeat and YoYo have the same behavior as on a scalar Tween.
NewVec2 source
func NewVec2(from, to lin.Vec2, seconds float32, ease Ease) *Of[lin.Vec2]
NewVec2 tweens a 2D vector.
NewVec3 source
func NewVec3(from, to lin.Vec3, seconds float32, ease Ease) *Of[lin.Vec3]
NewVec3 tweens a 3D vector.
OnDone source
func (o *Of[V]) OnDone(f func()) *Of[V]
OnDone replaces the completion callback and returns the same typed
tween for chaining. It follows Tween.OnDone's callback timing.
Example
package main
import (
"fmt"
"github.com/matjam/bunyip/lin"
"github.com/matjam/bunyip/tween"
)
func main() {
done := false
move := tween.NewVec2(lin.V2(0, 0), lin.V2(10, 20), 1, nil).
OnDone(func() { done = true })
move.Repeat, move.YoYo = 1, true
fmt.Println(move.Update(1), done)
fmt.Println(move.Update(1), done)
}
{10 20} false
{0 0} true
type Sequence source
type Sequence struct {
// contains filtered or unexported fields
}
Sequence plays tweens one after another.
Example
package main
import (
"fmt"
"github.com/matjam/bunyip/tween"
)
func main() {
// Fade in, hold, fade out: each step starts when the previous ends.
fade := tween.NewSequence(
tween.New(0, 1, 0.5, nil),
tween.New(1, 1, 1, nil),
tween.New(1, 0, 0.5, nil),
)
for !fade.Done() {
fade.Update(0.5)
}
fmt.Println(fade.Update(0))
}
0
type Tween source
type Tween struct {
From, To float32 // endpoints of the forward play
Duration float32 // seconds per play; nonpositive completes after Delay
Ease Ease // progress mapping; nil means linear
Delay float32 // seconds before movement starts
Repeat int // extra plays after the first; -1 forever
YoYo bool // alternate direction on repeats
// contains filtered or unexported fields
}
Tween moves a value from From to To over Duration seconds.
Example
package main
import (
"fmt"
"github.com/matjam/bunyip/tween"
)
func main() {
// Slide a value from 0 to 100 over one second with an ease-out curve.
slide := tween.New(0, 100, 1, tween.OutQuad)
for range 4 {
fmt.Printf("%.0f ", slide.Update(0.25))
}
fmt.Println(slide.Done())
}
44 75 94 100 true
New source
func New(from, to, seconds float32, ease Ease) *Tween
New makes a tween; a nil ease is linear.
OnDone source
func (tw *Tween) OnDone(f func()) *Tween
OnDone replaces the callback called synchronously by the Update that finishes the tween. Registration after completion does not invoke it; Reset permits it to run again on the next completed playthrough.
Progress source
func (tw *Tween) Progress() float32
Progress is eased progress. The input to Ease is clamped to [0,1], but curves such as OutBack and OutElastic may overshoot that range. A nonpositive Duration reports 1, including while Delay is pending.
Source files
example_test.go of.go of_test.go review_test.go tween.go tween_test.go