12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- // SPDX-License-Identifier: Unlicense OR MIT
- package material
- import (
- "image"
- "image/color"
- "math"
- "time"
- "gioui.org/f32"
- "gioui.org/layout"
- "gioui.org/op"
- "gioui.org/op/clip"
- "gioui.org/op/paint"
- )
- type LoaderStyle struct {
- Color color.NRGBA
- }
- func Loader(th *Theme) LoaderStyle {
- return LoaderStyle{
- Color: th.Palette.ContrastBg,
- }
- }
- func (l LoaderStyle) Layout(gtx layout.Context) layout.Dimensions {
- diam := gtx.Constraints.Min.X
- if minY := gtx.Constraints.Min.Y; minY > diam {
- diam = minY
- }
- if diam == 0 {
- diam = gtx.Dp(24)
- }
- sz := gtx.Constraints.Constrain(image.Pt(diam, diam))
- radius := sz.X / 2
- defer op.Offset(image.Pt(radius, radius)).Push(gtx.Ops).Pop()
- dt := float32((time.Duration(gtx.Now.UnixNano()) % (time.Second)).Seconds())
- startAngle := dt * math.Pi * 2
- endAngle := startAngle + math.Pi*1.5
- defer clipLoader(gtx.Ops, startAngle, endAngle, float32(radius)).Push(gtx.Ops).Pop()
- paint.ColorOp{
- Color: l.Color,
- }.Add(gtx.Ops)
- defer op.Offset(image.Pt(-radius, -radius)).Push(gtx.Ops).Pop()
- paint.PaintOp{}.Add(gtx.Ops)
- gtx.Execute(op.InvalidateCmd{})
- return layout.Dimensions{
- Size: sz,
- }
- }
- func clipLoader(ops *op.Ops, startAngle, endAngle, radius float32) clip.Op {
- const thickness = .25
- var (
- width = radius * thickness
- delta = endAngle - startAngle
- vy, vx = math.Sincos(float64(startAngle))
- inner = radius * (1. - thickness*.5)
- pen = f32.Pt(float32(vx), float32(vy)).Mul(inner)
- center = f32.Pt(0, 0).Sub(pen)
- p clip.Path
- )
- p.Begin(ops)
- p.Move(pen)
- p.Arc(center, center, delta)
- return clip.Stroke{
- Path: p.End(),
- Width: width,
- }.Op()
- }
|