aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go/dummy-ui/main.go2
-rw-r--r--go/ui/spinner.go77
2 files changed, 79 insertions, 0 deletions
diff --git a/go/dummy-ui/main.go b/go/dummy-ui/main.go
index a3e90f48..fd936466 100644
--- a/go/dummy-ui/main.go
+++ b/go/dummy-ui/main.go
@@ -34,6 +34,8 @@ func (a *app) build() {
a.AddWidget(tI)
a.AddWidget(ui.NewTimerBar(0, 10, a.windowWidth, 5, 30*time.Second))
+
+ a.AddWidget(ui.NewSpinner(100, 400, 50))
}
func (a *app) Layout(width, height int) (int, int) {
diff --git a/go/ui/spinner.go b/go/ui/spinner.go
new file mode 100644
index 00000000..083ec292
--- /dev/null
+++ b/go/ui/spinner.go
@@ -0,0 +1,77 @@
+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)
+ vertices := []ebiten.Vertex{}
+ indices := []uint16{}
+ vertices, indices = path.AppendVerticesAndIndicesForStroke(vertices, indices, strokeOp)
+
+ {
+ r, g, b, a := s.fg.RGBA()
+ for i := range vertices {
+ vertices[i].SrcX = 1
+ vertices[i].SrcY = 1
+ vertices[i].ColorR = float32(r)
+ vertices[i].ColorG = float32(g)
+ vertices[i].ColorB = float32(b)
+ vertices[i].ColorA = float32(a)
+ }
+ }
+
+ op := &ebiten.DrawTrianglesOptions{}
+ op.AntiAlias = true
+ op.FillRule = ebiten.FillRuleNonZero
+ op.ColorScaleMode = ebiten.ColorScaleModePremultipliedAlpha
+ img.DrawTriangles(vertices, indices, whiteSubImage, op)
+ return img
+}