package yay import ( "log" "time" "github.com/nsf/termbox-go" ) func init() { log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) } type Animation interface { Next() []rune } type ViewPort struct { viewX, viewY int vcenter int hcenter int timeout time.Duration animation Animation } func NewViewPort(a Animation, to time.Duration) *ViewPort { vp := &ViewPort{ animation: a, timeout: to, } return vp } func (tb *ViewPort) 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(tb.timeout) 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 *ViewPort) draw() { curFrame := tb.animation.Next() width := len(curFrame) / 2 for i, r := range curFrame { termbox.SetCell( tb.hcenter-width+i, tb.vcenter, r, termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlack, ) } }