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  )