package main import ( "log" "time" "github.com/nsf/termbox-go" ) func main() { t := NewTB() t.Run() } type TB struct { viewX, viewY int vcenter int hcenter int arms [][]rune arm int } func NewTB() *TB { return &TB{ arms: [][]rune{ {'.', '.'}, {'.', '.'}, {'-', '-'}, {'\\', '/'}, {'\'', '/'}, {'\\', '/'}, {'\\', '\''}, {'-', '-'}, }, } } func (tb *TB) Run() { err := termbox.Init() if err != nil { log.Fatal(err) } defer termbox.Close() tb.viewX, tb.viewY = termbox.Size() tb.vcenter = tb.viewY / 2.0 tb.hcenter = tb.viewX / 2.0 events := make(chan termbox.Event) go func() { for { events <- termbox.PollEvent() } }() termbox.HideCursor() func() { tick := time.Tick(200 * time.Millisecond) for { termbox.Clear(termbox.ColorBlack, termbox.ColorBlack) tb.draw() err := termbox.Flush() if err != nil { log.Fatal(err) } select { case <-tick: case event := <-events: switch event.Type { case termbox.EventKey: switch event.Key { case termbox.KeyCtrlZ, termbox.KeyCtrlC: log.Printf("exiting ...") return } switch event.Ch { case 'q': return } case termbox.EventResize: tb.viewX, tb.viewY = event.Width, event.Height tb.vcenter = tb.viewY / 2.0 tb.hcenter = tb.viewX / 2.0 case termbox.EventError: log.Fatalf("Quitting because of termbox error: \n%s\n", event.Err) } } } }() } func (tb *TB) draw() { termbox.SetCell( tb.hcenter-1, tb.vcenter, tb.arms[tb.arm%len(tb.arms)][0], termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlack, ) termbox.SetCell( tb.hcenter, tb.vcenter, 'o', termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlack, ) termbox.SetCell( tb.hcenter+1, tb.vcenter, tb.arms[tb.arm%len(tb.arms)][1], termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlack, ) tb.arm += 1 }