Skip to content

Commit

Permalink
Breaking change: move EasingAlgorithm to Animator
Browse files Browse the repository at this point in the history
CHANGES
EasingAlgorithm has been moved directly to AnimatorWidget so that it chould be used for any animation
not only for MoveAnimation.
Sadly, it breaks compatibility with v1.2.

This commit also adds a globally-available Ease method that could be used to calculate eased percentage value
  • Loading branch information
gucio321 committed Feb 12, 2023
1 parent 48a5a94 commit a6e4c6f
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 52 deletions.
3 changes: 1 addition & 2 deletions _examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ func loop() {
}),
).Size(200, 80)
}, imgui.Vec2{X: 20, Y: 100}).
Algorithm(easingAlg).
StartPos(imgui.Vec2{X: 5, Y: 80}).
Bezier(imgui.Vec2{X: 20, Y: 20}, imgui.Vec2{X: 90}),
).Duration(time.Second*3).FPS(120),
).Duration(time.Second*3).FPS(120).EasingAlgorithm(easingAlg),
)
},
func(starter func()) {
Expand Down
17 changes: 13 additions & 4 deletions animation.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,17 @@ type Animation interface {
// starter is a link to Animator.Start
BuildNormal(starter func())
// BuildAnimation is called when running an animation.
// It receives the current animation progress as a float, where
// 0 >= animationPercentage <= 1
// starter is a link to Animator.Start
BuildAnimation(animationPercentage float32, starter func())
// It receives two values:
// - first one is animationPercentage after applying specified by Animator
// easing algorithm.
// ATTENTION: this value may be less than 0 or larger than 1
// - second value is arbitrary percentage progress before applying
// easing algorithm.
// it is always in range <0, 1> (0 <= arbitraryPercentage <= 1)
// NOTE: this value should NOT be used in most cases, because it will
// disable user from specifying Easing Algorithm and most use-cases
// does not want this. Exceptions, I see for now may be:
// - your animation does not accept negative (or larger than 1) progress values
// starter is a link to (*Animator).Start() method.
BuildAnimation(animationPercentage, arbitraryPercentage float32, starter func())
}
24 changes: 17 additions & 7 deletions animator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ const (
type AnimatorWidget struct {
id string

duration time.Duration
fps int
duration time.Duration
fps int
easingAlgorithm EasingAlgorithmType

a Animation
}

// Animator creates a new AnimatorWidget.
func Animator(a Animation) *AnimatorWidget {
result := &AnimatorWidget{
id: giu.GenAutoID("Animation"),
a: a,
duration: DefaultDuration,
fps: DefaultFPS,
id: giu.GenAutoID("Animation"),
a: a,
duration: DefaultDuration,
fps: DefaultFPS,
easingAlgorithm: EasingAlgNone,
}

return result
Expand All @@ -50,6 +52,13 @@ func (a *AnimatorWidget) Duration(duration time.Duration) *AnimatorWidget {
return a
}

// EasingAlgorithm allows to specify easing algorithm
func (a *AnimatorWidget) EasingAlgorithm(alg EasingAlgorithmType) *AnimatorWidget {
a.easingAlgorithm = alg

return a
}

// Start starts the animation.
func (a *AnimatorWidget) Start() {
a.a.Reset()
Expand Down Expand Up @@ -92,7 +101,8 @@ func (a *AnimatorWidget) Build() {
}

if a.IsRunning() {
a.a.BuildAnimation(a.CurrentPercentageProgress(), a.Start)
p := a.CurrentPercentageProgress()
a.a.BuildAnimation(Ease(a.easingAlgorithm, p), p, a.Start)

return
}
Expand Down
42 changes: 41 additions & 1 deletion easing_algorithm.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package animations

import "math"
import (
"log"
"math"
)

type EasingAlgorithm func(plainPercentage float32) (percentage float32)

Expand All @@ -25,6 +28,43 @@ const (
EasingAlgMax
)

// Ease takes EasingAlgorithmType and plain percentage value t and returns eased value.
// The following condition is expected to be met, however they are not restricted anyhow:
// 0 <= t <= 1
func Ease(alg EasingAlgorithmType, t float32) float32 {
switch alg {
case EasingAlgNone:
return t
case EasingAlgInSine:
return easingAlgInSine(t)
case EasingAlgOutSine:
return easingAlgOutSine(t)
case EasingAlgInOutSine:
return easingAlgInOutSine(t)
case EasingAlgInBack:
return easingAlgInBack(t)
case EasingAlgOutBack:
return easingAlgOutBack(t)
case EasingAlgInOutBack:
return easingAlgInOutBack(t)
case EasingAlgInElastic:
return easingAlgInElastic(t)
case EasingAlgOutElastic:
return easingAlgOutElastic(t)
case EasingAlgInOutElastic:
return easingAlgInOutElastic(t)
case EasingAlgInBounce:
return easingAlgInBounce(t)
case EasingAlgOutBounce:
return easingAlgOutBounce(t)
case EasingAlgInOutBounce:
return easingAlgInOutBounce(t)
}

log.Panicf("Unknown easing type %v", alg)
return -1 // unreachable
}

func easingAlgInSine(plainPercentage float32) float32 {
return 1 - float32(math.Cos((float64(plainPercentage)*math.Pi)/2))
}
Expand Down
2 changes: 1 addition & 1 deletion hover_color.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (h *HoverColorAnimation) BuildNormal(starter func()) {
data.m.Unlock()
}

func (h *HoverColorAnimation) BuildAnimation(percentage float32, _ func()) {
func (h *HoverColorAnimation) BuildAnimation(percentage, _ float32, _ func()) {
data := h.getState()
normalColor := giu.ToVec4Color(h.normalColor())
hoverColor := giu.ToVec4Color(h.hoveredColor())
Expand Down
37 changes: 1 addition & 36 deletions move.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ type MoveAnimation struct {
widget func(starter func()) giu.Widget
posDelta imgui.Vec2

alg EasingAlgorithmType
useBezier bool
bezier []imgui.Vec2
}
Expand Down Expand Up @@ -80,11 +79,6 @@ func (m *MoveAnimation) Reset() {
state.state = !state.state
}

func (m *MoveAnimation) Algorithm(algorithm EasingAlgorithmType) *MoveAnimation {
m.alg = algorithm
return m
}

func (m *MoveAnimation) BuildNormal(starter func()) {
state := m.getState()
if state.state {
Expand All @@ -100,38 +94,9 @@ func (m *MoveAnimation) BuildNormal(starter func()) {
m.widget(starter).Build()
}

func (m *MoveAnimation) BuildAnimation(animationPercentage float32, starter func()) {
func (m *MoveAnimation) BuildAnimation(animationPercentage, _ float32, starter func()) {
state := m.getState()

switch m.alg {
case EasingAlgNone:
// noop
case EasingAlgInSine:
animationPercentage = easingAlgInSine(animationPercentage)
case EasingAlgOutSine:
animationPercentage = easingAlgOutSine(animationPercentage)
case EasingAlgInOutSine:
animationPercentage = easingAlgInOutSine(animationPercentage)
case EasingAlgInBack:
animationPercentage = easingAlgInBack(animationPercentage)
case EasingAlgOutBack:
animationPercentage = easingAlgOutBack(animationPercentage)
case EasingAlgInOutBack:
animationPercentage = easingAlgInOutBack(animationPercentage)
case EasingAlgInElastic:
animationPercentage = easingAlgInElastic(animationPercentage)
case EasingAlgOutElastic:
animationPercentage = easingAlgOutElastic(animationPercentage)
case EasingAlgInOutElastic:
animationPercentage = easingAlgInOutElastic(animationPercentage)
case EasingAlgInBounce:
animationPercentage = easingAlgInBounce(animationPercentage)
case EasingAlgOutBounce:
animationPercentage = easingAlgOutBounce(animationPercentage)
case EasingAlgInOutBounce:
animationPercentage = easingAlgInOutBounce(animationPercentage)
}

if !state.state {
animationPercentage = 1 - animationPercentage
}
Expand Down
2 changes: 1 addition & 1 deletion transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func Transition(renderer1, renderer2 func(starter func())) *TransitionAnimation
}
}

func (t *TransitionAnimation) BuildAnimation(percentage float32, starter func()) {
func (t *TransitionAnimation) BuildAnimation(percentage, _ float32, starter func()) {
state := t.getState()
// it means the current layout is layout1, so increasing percentage
if state.layout == 1 {
Expand Down

0 comments on commit a6e4c6f

Please sign in to comment.