From 00d61decf434d1688aa041641c062d96039f4923 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 10 Feb 2022 15:53:36 -0500 Subject: [PATCH] Add minimum percent change needed to trigger an animation in progress --- progress/progress.go | 48 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/progress/progress.go b/progress/progress.go index 8f9e25c..60de488 100644 --- a/progress/progress.go +++ b/progress/progress.go @@ -31,10 +31,11 @@ func nextID() int { } const ( - fps = 60 - defaultWidth = 40 - defaultFrequency = 18.0 - defaultDamping = 1.0 + fps = 60 + defaultWidth = 40 + defaultFrequency = 18.0 + defaultDamping = 1.0 + defaultAnimThreshold = 0.08 ) var color func(string) termenv.Color = termenv.ColorProfile().Color @@ -110,6 +111,14 @@ func WithSpringOptions(frequency, damping float64) Option { } } +// WithAnimationThreshold sets the percent chagne threshold necessary to +// trigger an animated transition. +func WithAnimationThreshold(ratio float64) Option { + return func(m *Model) { + m.SetAnimationThreshold(ratio) + } +} + // FrameMsg indicates that an animation step should occur. type FrameMsg struct { id int @@ -141,13 +150,17 @@ type Model struct { PercentFormat string // a fmt string for a float PercentageStyle lipgloss.Style - // Members for animated transitions. + // Settings for animated transitions. spring harmonica.Spring springCustomized bool percentShown float64 // percent currently displaying targetPercent float64 // percent to which we're animating velocity float64 + // The amount of change required to trigger an animated transition. Should + // be a float between 0 and 1. + animThreshold float64 + // Gradient settings useRamp bool rampColorA colorful.Color @@ -237,7 +250,14 @@ func (m Model) Percent() float64 { // // If you're rendering with ViewAs you won't need this. func (m *Model) SetPercent(p float64) tea.Cmd { - m.targetPercent = math.Max(0, math.Min(1, p)) + // If the value is at or below the animation threshold, don't animate + if math.Abs(p-m.percent) <= m.animThreshold { + m.percent = asRatio(p) + m.targetPercent = asRatio(p) + return nil + } + + m.targetPercent = asRatio(p) m.tag++ return m.nextFrame() } @@ -258,6 +278,18 @@ func (m *Model) DecrPercent(v float64) tea.Cmd { return m.SetPercent(m.Percent() - v) } +// SetAnimationThreshold sets the percent chagne threshold necessary to trigger +// an animated transition. +func (m *Model) SetAnimationThreshold(v float64) { + m.animThreshold = asRatio(v) +} + +// AnimationThreshold returns the percent change necessary to trigger an +// animated transition. +func (m *Model) AnimationThreshold() float64 { + return m.animThreshold +} + // View renders the an animated progress bar in its current state. To render // a static progress bar based on your own calculations use ViewAs instead. func (m Model) View() string { @@ -351,3 +383,7 @@ func min(a, b int) int { } return b } + +func asRatio(v float64) float64 { + return math.Max(math.Min(v, 1), 0) +}