go-simple-ui/internal/utils/animation.go

79 lines
1.3 KiB
Go

package utils
import (
"math"
"time"
"gioui.org/layout"
"gioui.org/op"
)
type Animation struct {
start float32
end float32
current float32
startTime time.Time
duration time.Duration
active bool
Easing Easing
}
type Easing int
const (
None Easing = iota
EasingIn
EasingOut
EasingOutSine
EasingInOutSine
)
func (a *Animation) Current() float32 {
return a.current
}
func applyEasing(easing Easing, t float32) float32 {
switch easing {
case EasingIn:
return t * t
case EasingOut:
return t * (2 - t)
case EasingOutSine:
return float32(math.Sin(float64(t) * math.Pi / 2))
case EasingInOutSine:
return float32(-0.5 * (math.Cos(math.Pi*float64(t)) - 1))
default:
return t
}
}
func (a *Animation) Start(start, end float32, duration time.Duration, easing Easing) {
a.start = start
a.end = end
a.current = start
a.startTime = time.Now()
a.duration = duration
a.Easing = easing
a.active = true
}
func (a *Animation) Update(gtx layout.Context) float32 {
if !a.active {
return a.current
}
elapsed := time.Since(a.startTime)
if elapsed >= a.duration {
a.current = a.end
a.active = false
} else {
progress := float32(elapsed) / float32(a.duration)
eased := applyEasing(a.Easing, progress)
a.current = a.start + (a.end-a.start)*eased
}
gtx.Execute(&op.InvalidateCmd{})
return a.current
}