improvements?

This commit is contained in:
Maas Lalani 2021-08-06 23:43:02 -04:00
parent 46edff14e5
commit 8a8e8df463
No known key found for this signature in database
GPG Key ID: F53774FA051C052A
2 changed files with 30 additions and 13 deletions

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
p := tea.NewProgram(confetty.InitialModel()) p := tea.NewProgram(confetty.InitialModel(), tea.WithAltScreen())
if err := p.Start(); err != nil { if err := p.Start(); err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

View File

@ -15,17 +15,20 @@ import (
"golang.org/x/term" "golang.org/x/term"
) )
const fps = 60.0 const (
framesPerSecond = 60.0
numParticles = 75
)
var ( var (
colors = []string{"#a864fd", "#29cdff", "#78ff44", "#ff718d", "#fdff6a"} colors = []string{"#a864fd", "#29cdff", "#78ff44", "#ff718d", "#fdff6a"}
characters = []string{"▄", "▀", "█"} // "▓", "▒", "░"} characters = []string{"▄", "▀"} // "█", "▓", "▒", "░"}
) )
type frameMsg time.Time type frameMsg time.Time
func animate() tea.Cmd { 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) return frameMsg(t)
}) })
} }
@ -37,6 +40,7 @@ func wait(d time.Duration) tea.Cmd {
} }
} }
// Confetti model
type model struct { type model struct {
particles []*Particle particles []*Particle
viewport viewport.Model viewport viewport.Model
@ -45,27 +49,26 @@ type model struct {
type Particle struct { type Particle struct {
char string char string
physics *physics.Physics physics *physics.Physics
color lipgloss.Color
} }
func InitialModel() model { func InitialModel() model {
particles := []*Particle{} particles := []*Particle{}
width, height, err := term.GetSize(0) width, _, err := term.GetSize(0)
if err != nil { if err != nil {
panic(err) panic(err)
} }
for i := 0; i < 25; i++ { for i := 0; i < numParticles; i++ {
x := float64(width / 2) x := float64(width / 2)
y := float64(height / 2) y := float64(-1)
p := &Particle{ p := &Particle{
physics: physics.New( physics: physics.New(
physics.Vector{X: x, Y: y}, physics.Vector{X: x + (float64(width/4) * (rand.Float64() - 0.5)), Y: y},
physics.Vector{X: (rand.Float64() - 0.5) * 100, Y: (rand.Float64() - 0.5) * 100}, physics.Vector{X: (rand.Float64() - 0.5) * 100, Y: rand.Float64() * 50},
physics.Vector(physics.Gravity), physics.Vector(physics.Gravity),
fps, framesPerSecond,
), ),
char: lipgloss.NewStyle(). char: lipgloss.NewStyle().
Foreground(lipgloss.Color(array.Sample(colors))). Foreground(lipgloss.Color(array.Sample(colors))).
@ -78,28 +81,36 @@ func InitialModel() model {
return model{particles: particles} return model{particles: particles}
} }
// Init initializes the confetti after a small delay
func (m model) Init() tea.Cmd { 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) { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyMsg:
return m, tea.Quit return m, tea.Quit
// frame animation
case frameMsg: case frameMsg:
for _, p := range m.particles { for _, p := range m.particles {
p.physics.Update() p.physics.Update()
} }
return m, animate() return m, animate()
case tea.WindowSizeMsg: case tea.WindowSizeMsg:
m.viewport.Width = msg.Width m.viewport.Width = msg.Width
m.viewport.Height = msg.Height m.viewport.Height = msg.Height
return m, nil return m, nil
default: default:
return m, nil return m, nil
} }
} }
// View displays all the particles on the screen
func (m model) View() string { func (m model) View() string {
if m.viewport.Height <= 0 || m.viewport.Width <= 0 { if m.viewport.Height <= 0 || m.viewport.Width <= 0 {
return "" return ""
@ -109,14 +120,19 @@ func (m model) View() string {
for i := range grid { for i := range grid {
grid[i] = make([]string, m.viewport.Width) grid[i] = make([]string, m.viewport.Width)
} }
for _, p := range m.particles { for _, p := range m.particles {
y := p.physics.PosY() y := p.physics.PosY()
x := p.physics.PosX() 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 continue
} }
grid[y][x] = p.char grid[y][x] = p.char
} }
// Print out grid
for i := range grid { for i := range grid {
for _, col := range grid[i] { for _, col := range grid[i] {
if col == "" { if col == "" {
@ -127,5 +143,6 @@ func (m model) View() string {
} }
fmt.Fprint(&out, "\n") fmt.Fprint(&out, "\n")
} }
return out.String() return out.String()
} }