Skip to content

Commit

Permalink
feat: anim color cycling
Browse files Browse the repository at this point in the history
  • Loading branch information
meowgorithm authored and toby committed Jun 5, 2023
1 parent 65cf1b3 commit ee65378
Showing 1 changed file with 29 additions and 4 deletions.
33 changes: 29 additions & 4 deletions anim.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

const (
charCyclingFPS = time.Second / 22
colorCycleFPS = time.Second / 5
maxCyclingChars = 120
)

Expand Down Expand Up @@ -60,11 +61,19 @@ func (c cyclingChar) state(start time.Time) charState {
type stepCharsMsg struct{}

func stepChars() tea.Cmd {
return tea.Tick(charCyclingFPS, func(_ time.Time) tea.Msg {
return tea.Tick(charCyclingFPS, func(time.Time) tea.Msg {
return stepCharsMsg{}
})
}

type colorCycleMsg struct{}

func cycleColors() tea.Cmd {
return tea.Tick(colorCycleFPS, func(time.Time) tea.Msg {
return colorCycleMsg{}
})
}

// anim is the model that manages the animation that displays while the
// output is being generated.
type anim struct {
Expand Down Expand Up @@ -100,11 +109,12 @@ func newAnim(cyclingCharsSize uint, label string, r *lipgloss.Renderer, s styles
// color the cycling characters with a gradient ramp.
const minRampSize = 3
if n >= minRampSize && r.ColorProfile() == termenv.TrueColor {
c.ramp = make([]lipgloss.Style, n)
c.ramp = make([]lipgloss.Style, n, n*2) // double capacity for color cycling
ramp := makeGradientRamp(n)
for i, color := range ramp {
c.ramp[i] = r.NewStyle().Foreground(color)
}
c.ramp = append(c.ramp, reverse(c.ramp)...) // reverse and append for color cycling
}

makeDelay := func(a int32, b time.Duration) time.Duration {
Expand Down Expand Up @@ -141,7 +151,7 @@ func newAnim(cyclingCharsSize uint, label string, r *lipgloss.Renderer, s styles

// Init initializes the animation.
func (anim) Init() tea.Cmd {
return stepChars()
return tea.Batch(stepChars(), cycleColors())
}

// Update handles messages.
Expand All @@ -163,13 +173,19 @@ func (a anim) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// If our entire label has reached end of life, start the
// ellipsis "spinner" after a short pause.
a.ellipsisStarted = true
cmd = tea.Tick(time.Millisecond*220, func(_ time.Time) tea.Msg { //nolint:gomnd
cmd = tea.Tick(time.Millisecond*220, func(time.Time) tea.Msg { //nolint:gomnd
return a.ellipsis.Tick()
})
}
}

return a, tea.Batch(stepChars(), cmd)
case colorCycleMsg:
if len(a.ramp) < 2 {
return a, nil
}
a.ramp = append(a.ramp[1:], a.ramp[0])
return a, cycleColors()
case spinner.TickMsg:
var cmd tea.Cmd
a.ellipsis, cmd = a.ellipsis.Update(msg)
Expand Down Expand Up @@ -238,3 +254,12 @@ func makeGradientText(baseStyle lipgloss.Style, str string) string {
}
return b.String()
}

func reverse[T any](in []T) []T {
out := make([]T, len(in))
copy(out, in[:])
for i, j := 0, len(out)-1; i < j; i, j = i+1, j-1 {
out[i], out[j] = out[j], out[i]
}
return out
}

0 comments on commit ee65378

Please sign in to comment.