79 lines
1.3 KiB
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
|
|
}
|