Hide blob in 2D example if user hasn't clicked in awhile

This commit is contained in:
Christian Rocha 2021-07-09 18:03:32 -04:00
parent 25d8790040
commit 17bfa34c33
No known key found for this signature in database
GPG Key ID: D6CC7A16E5878018

View File

@ -8,81 +8,129 @@ import (
) )
const ( const (
width = 1024 canvasWidth = 1024
height = 768 canvasHeight = 768
fps = 60 fps = 60
bgColor = "#111111" circleRadius = 100
bgColor = "#111111"
idleTimeout = time.Second * 5
)
type State int
const (
unstarted State = iota
running
timeout
) )
func main() { func main() {
var ( var (
circ = newCircle() circ Circle
clickedYet bool state State
lastClick time.Time
) )
c := canvas.NewCanvas(&canvas.CanvasConfig{ c := canvas.NewCanvas(&canvas.CanvasConfig{
Width: width, Width: canvasWidth,
Height: height, Height: canvasHeight,
FrameRate: fps, FrameRate: fps,
Title: "Harmonica", Title: "Harmonica",
}) })
c.Draw(func(ctx *canvas.Context) { c.Draw(func(ctx *canvas.Context) {
ctx.SetHexColor(bgColor)
ctx.Clear() ctx.Clear()
ctx.SetHexColor(bgColor)
if ctx.IsMouseDragged { switch state {
if !clickedYet { case unstarted:
// Set starting positions. if ctx.IsMouseDragged {
circ.x = ctx.Mouse.X const frequency = 0.8
circ.y = ctx.Mouse.Y const damping = 1.0
circ.Radius = 100 circ = Circle{
clickedYet = true // Setup a new spring.
spring: harmonica.NewSpring(harmonica.TimeDelta(time.Second/fps), frequency, damping),
// Set target radius.
Radius: circleRadius,
}
// Set starting position.
circ.SetPos(ctx.Mouse.X, ctx.Mouse.Y)
lastClick = time.Now()
state = running
} }
circ.X = ctx.Mouse.X
circ.Y = ctx.Mouse.Y
}
if clickedYet { case running:
circ.draw(ctx) if ctx.IsMouseDragged {
lastClick = time.Now()
if circ.Hidden {
circ.SetPos(ctx.Mouse.X, ctx.Mouse.Y)
circ.Hidden = false
}
// Update targets for our spring animation.
circ.X = ctx.Mouse.X
circ.Y = ctx.Mouse.Y
circ.Radius = circleRadius
}
circ.Draw(ctx)
if time.Now().After(lastClick.Add(idleTimeout)) {
state = timeout
}
case timeout:
circ.Radius = 0
circ.Draw(ctx)
if circ.rad == 0 {
state = running
lastClick = time.Now()
}
} }
}) })
} }
type circle struct { type Circle struct {
// Target values. This is what the spring will seek. // Target values. This is what the spring will use as an equilibrium to
// animate towards.
X, Y, Radius float64 X, Y, Radius float64
// Managed values. These are the initial
x, xVel float64 x, xVel float64
y, yVel float64 y, yVel float64
rad, radVel float64 rad, radVel float64
spring harmonica.Spring
spring harmonica.Spring Hidden bool
} }
func newCircle() circle { func (c *Circle) SetPos(x, y float64) {
const ( c.x = x
frequency = 0.8 c.y = y
damping = 0.99 c.Hidden = false
)
return circle{
spring: harmonica.NewSpring(harmonica.TimeDelta(time.Second/fps), frequency, damping),
}
} }
func (c *circle) draw(ctx *canvas.Context) { func (c *Circle) Draw(ctx *canvas.Context) {
// Update // Update position and radius.
c.spring.Update(&c.x, &c.xVel, c.X) c.spring.Update(&c.x, &c.xVel, c.X)
c.spring.Update(&c.y, &c.yVel, c.Y) c.spring.Update(&c.y, &c.yVel, c.Y)
c.spring.Update(&c.rad, &c.radVel, c.Radius) c.spring.Update(&c.rad, &c.radVel, c.Radius)
if c.rad < 0 {
c.rad = 0
c.radVel = 0
c.Hidden = true
}
const color = "#f1f1f1" const color = "#f1f1f1"
ctx.Push() ctx.Push()
ctx.DrawCircle(c.x, c.y, c.rad) ctx.DrawCircle(c.x, c.y, c.rad)
ctx.SetHexColor(color) ctx.SetHexColor(color)
ctx.Fill() ctx.Fill()
ctx.Pop()
} }