github.com/wolfi-dev/wolfictl@v0.16.11/pkg/cli/components/breather/breather.go (about) 1 package breather 2 3 import ( 4 "math" 5 "time" 6 7 tea "github.com/charmbracelet/bubbletea" 8 "github.com/charmbracelet/lipgloss" 9 "github.com/lucasb-eyer/go-colorful" 10 ) 11 12 type Model struct { 13 Text string 14 15 colorVal float64 16 style lipgloss.Style 17 } 18 19 func New(char string) Model { 20 return Model{ 21 Text: char, 22 colorVal: 0.5, 23 style: lipgloss.NewStyle(), 24 } 25 } 26 27 func (m Model) Init() tea.Cmd { 28 return doTick() 29 } 30 31 func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { 32 if t, ok := msg.(TickMsg); ok { 33 m.colorVal = t.sineValue() 34 } 35 36 return m, doTick() 37 } 38 39 func (m Model) View() string { 40 c := colorful.Hsl(0, 0, m.colorVal) 41 color := lipgloss.Color(c.Hex()) 42 43 return m.style.Foreground(color).Render(m.Text) 44 } 45 46 // ViewStatic returns the view without any animations. 47 func (m Model) ViewStatic() string { 48 return m.style.Render(m.Text) 49 } 50 51 type TickMsg time.Time 52 53 func (t TickMsg) sineValue() float64 { 54 unix := float64(time.Time(t).UnixNano()) / 1e9 // Convert to seconds 55 56 return cycleAmplitude*math.Sin(unix*math.Pi*2/cycleLengthInSeconds) + cycleMidpoint 57 } 58 59 func doTick() tea.Cmd { 60 return tea.Tick(tickLength, func(t time.Time) tea.Msg { 61 return TickMsg(t) 62 }) 63 } 64 65 const ( 66 tickLength = 33 * time.Millisecond 67 68 cycleLengthInSeconds = 2.3 69 cycleMidpoint = 0.55 70 cycleAmplitude = 0.2 71 )