Animation
Chain Diff Apply callbacks into a continuously running animation.
Animation
Create a continuously changing animation by chaining Diff Apply callbacks.
Live Demo
Source
package examples
import (
"context"
"log"
l "github.com/SamHennessy/hlive"
. "github.com/SamHennessy/hlive/hhtml"
)
const animationStyle l.HTML = `
.box {
overflow: hidden;
padding: 3em;
text-align: center;
border: solid;
}
.text {
display: inline-block;
font-size: 3em;
}
`
var animations = []string{
"animate__hinge", "animate__jackInTheBox", "animate__rollIn", "animate__rollOut",
"animate__bounce", "animate__flash", "animate__pulse", "animate__rubberBand", "animate__shakeX",
"animate__shakeY", "animate__headShake", "animate__swing", "animate__tada", "animate__wobble",
"animate__jello", "animate__heartBeat", "animate__flip", "animate__backInDown", "animate__backOutDown",
}
// AnimationDemo is a live, interactive instance of the Animation example,
// served for the "Live Demo" iframe.
func AnimationDemo() *l.Page {
var (
index = l.Box(0)
current = l.Box("")
playing = l.NewLockBox(false)
btnLabel = l.Box("Start")
)
// Forced to a Component (rather than the hhtml Div() tag builder) because
// its animation event bindings are attached after creation.
animationTarget := l.C("div", l.Class("animate__animated text"), "HLive")
nextAnimation := func() {
index.Lock(func(v int) int {
animationTarget.Add(l.ClassOff(animations[v]))
v++
if len(animations) == v {
v = 0
}
current.Set(animations[v])
animationTarget.Add(l.Class(animations[v]))
return v
})
}
animationTarget.Add(l.On("animationend", func(ctx context.Context, e l.Event) {
if playing.Get() {
nextAnimation()
}
}))
animationTarget.Add(l.On("animationcancel", func(ctx context.Context, e l.Event) {
playing.Set(false)
btnLabel.Set("Start")
current.Set("")
}))
btn := Button(btnLabel,
l.On("click", func(ctx context.Context, e l.Event) {
playing.Lock(func(v bool) bool {
if !v {
nextAnimation()
btnLabel.Set("Stop")
} else {
btnLabel.Set("Start")
current.Set("")
}
return !v
})
}),
// You can create multiple event bindings for the same event and component
l.On("click", func(ctx context.Context, e l.Event) {
log.Println("INFO: Button Clicked")
}),
)
page := l.NewPage()
page.DOM().Title().Add("Animation Example")
page.DOM().Head().Add(
Link(Rel("stylesheet"), Href("https://cdn.simplecss.org/simple.min.css")),
Link(Rel("stylesheet"), Href("https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css")),
Style(animationStyle),
)
page.DOM().Body().Add(
Header(
H1("CSS Animations"),
P("We can wait for the CSS animation to end before starting the next one"),
),
Main(
P(btn),
P("Current: ", current),
Div(Class("box"), animationTarget),
),
)
return page
}