From 8a8e8df4636ae1126ecf3578c2dec3624afbc144 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Fri, 6 Aug 2021 23:43:02 -0400 Subject: [PATCH] improvements? --- main.go | 2 +- pkg/confetty/confetty.go | 41 ++++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 443d728..7ae0788 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,7 @@ import ( ) func main() { - p := tea.NewProgram(confetty.InitialModel()) + p := tea.NewProgram(confetty.InitialModel(), tea.WithAltScreen()) if err := p.Start(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/pkg/confetty/confetty.go b/pkg/confetty/confetty.go index 7173db3..948f7d5 100644 --- a/pkg/confetty/confetty.go +++ b/pkg/confetty/confetty.go @@ -15,17 +15,20 @@ import ( "golang.org/x/term" ) -const fps = 60.0 +const ( + framesPerSecond = 60.0 + numParticles = 75 +) var ( colors = []string{"#a864fd", "#29cdff", "#78ff44", "#ff718d", "#fdff6a"} - characters = []string{"▄", "▀", "█"} // "▓", "▒", "░"} + characters = []string{"▄", "▀"} // "█", "▓", "▒", "░"} ) type frameMsg time.Time func animate() tea.Cmd { - return tea.Tick(time.Second/fps, func(t time.Time) tea.Msg { + return tea.Tick(time.Second/framesPerSecond, func(t time.Time) tea.Msg { return frameMsg(t) }) } @@ -37,6 +40,7 @@ func wait(d time.Duration) tea.Cmd { } } +// Confetti model type model struct { particles []*Particle viewport viewport.Model @@ -45,27 +49,26 @@ type model struct { type Particle struct { char string physics *physics.Physics - color lipgloss.Color } func InitialModel() model { particles := []*Particle{} - width, height, err := term.GetSize(0) + width, _, err := term.GetSize(0) if err != nil { panic(err) } - for i := 0; i < 25; i++ { + for i := 0; i < numParticles; i++ { x := float64(width / 2) - y := float64(height / 2) + y := float64(-1) p := &Particle{ physics: physics.New( - physics.Vector{X: x, Y: y}, - physics.Vector{X: (rand.Float64() - 0.5) * 100, Y: (rand.Float64() - 0.5) * 100}, + physics.Vector{X: x + (float64(width/4) * (rand.Float64() - 0.5)), Y: y}, + physics.Vector{X: (rand.Float64() - 0.5) * 100, Y: rand.Float64() * 50}, physics.Vector(physics.Gravity), - fps, + framesPerSecond, ), char: lipgloss.NewStyle(). Foreground(lipgloss.Color(array.Sample(colors))). @@ -78,28 +81,36 @@ func InitialModel() model { return model{particles: particles} } +// Init initializes the confetti after a small delay func (m model) Init() tea.Cmd { - return tea.Sequentially(wait(time.Second), animate()) + return tea.Sequentially(wait(time.Second/2), animate()) } +// Update updates the model every frame, it handles the animation loop and +// updates the particle physics every frame func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: return m, tea.Quit + + // frame animation case frameMsg: for _, p := range m.particles { p.physics.Update() } return m, animate() + case tea.WindowSizeMsg: m.viewport.Width = msg.Width m.viewport.Height = msg.Height return m, nil + default: return m, nil } } +// View displays all the particles on the screen func (m model) View() string { if m.viewport.Height <= 0 || m.viewport.Width <= 0 { return "" @@ -109,14 +120,19 @@ func (m model) View() string { for i := range grid { grid[i] = make([]string, m.viewport.Width) } + for _, p := range m.particles { y := p.physics.PosY() x := p.physics.PosX() - if y < 0 || x < 0 || x >= m.viewport.Width-1 || y >= m.viewport.Height-1 { + + if y < 0 || y >= m.viewport.Height-1 || x < 0 || x >= m.viewport.Width-1 { continue } + grid[y][x] = p.char } + + // Print out grid for i := range grid { for _, col := range grid[i] { if col == "" { @@ -127,5 +143,6 @@ func (m model) View() string { } fmt.Fprint(&out, "\n") } + return out.String() }