package ui import ( "image/color" "math" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/vector" ) var ( SPINNER_DEFAULT_FOREGROUND = color.White SPINNER_DEFAULT_STROKE = 5 ) type Spinner struct { WidgetBase fg color.Color alpha uint64 } func NewSpinner(x, y int, diameter int) *Spinner { s := &Spinner{ WidgetBase: NewWidgetBase(x, y, diameter, diameter), fg: SPINNER_DEFAULT_FOREGROUND, } s.renderImpl = func() *ebiten.Image { return s.render() } s.EventHandlersMap["update"] = func() error { s.alpha = s.alpha + 3 s.ForceRedraw() return nil } return s } func (s *Spinner) Fg(fg color.Color) *Spinner { s.fg = fg return s } func (s *Spinner) render() *ebiten.Image { img := ebiten.NewImage(s.Width, s.Height) var path vector.Path r := float64((s.Width - 2*SPINNER_DEFAULT_STROKE) / 2) cx := s.Width/2 + SPINNER_DEFAULT_STROKE cy := cx a1 := float64(s.alpha%360) * math.Pi / 180 a2 := float64((s.alpha+90)%360) * math.Pi / 180 path.Arc(float32(cx), float32(cy), float32(r), float32(a2), float32(a1), vector.Clockwise) strokeOp := &vector.StrokeOptions{} strokeOp.Width = float32(SPINNER_DEFAULT_STROKE) drawOp := &vector.DrawPathOptions{} drawOp.AntiAlias = true vector.StrokePath(img, &path, strokeOp, drawOp) return img }