I'm trying to do CSS animation in Elm, and I just can't get it to work!
Elm has several animation packages. The one I'm attempting to use is mdgriffith/elm-animator. Sadly, like many Elm packages, its documentation is sparse. It appears it provides two ways to render: one by running an Elm event loop to do a DOM update each frame, and one using CSS animation [which I didn't realise even existed]. I'm trying to do the latter.
I've tried to shrink the code down to a minimal example:
module Main exposing (main)
import Time
import Platform.Cmd
import Browser
import Html
import Html.Attributes
import Html.Events
import Color
import Svg
import Svg.Attributes
import Animator
import Animator.Css
main =
Browser.document
{
init = \ () -> ({fill = Animator.init <| Color.rgb 1 0 0}, Platform.Cmd.none),
subscriptions = \ state -> Animator.toSubscription Tick state animator,
view = \ state -> {title = "Animation test", body = view state},
update = \ msg state -> (update msg state, Platform.Cmd.none)
}
type alias State = { fill : Animator.Timeline Color.Color }
animator : Animator.Animator State
animator =
Animator.animator
|> Animator.Css.watching (\ state -> state.fill) (\ c state -> { state | fill = c })
type Msg = Tick Time.Posix | DoSomething
update : Msg -> State -> State
update msg state0 =
case msg of
Tick t -> Animator.update t animator state0
DoSomething -> { state0 | fill = Animator.go Animator.slowly (Color.rgb 1 1 0) state0.fill }
view : State -> List (Html.Html Msg)
view state0 =
[
Html.button [Html.Events.onClick DoSomething] [Html.text "Do something"],
Svg.svg
[
Svg.Attributes.width "100px",
Svg.Attributes.height "100px"
]
[
Animator.Css.node "circle"
state0.fill
[
Animator.Css.color
"fill"
(\ x -> x)
]
[
Svg.Attributes.cx "50",
Svg.Attributes.cy "50",
Svg.Attributes.r "50"
]
[]
]
]
I appreciate that's still pretty big, but I don't see how to easily make it much shorter without obfuscating what it's doing.
When I run this, the SVG fails to render. When I click the button, nothing happens.
Here's the really weird part: If I open the Firefox Inspector window, I can see the SVG <circle> element. If I edit its various properties, nothing happens. However, if I right-click the <circle> and select "Edit as HTML...", then add a single space to the element text and click off it, suddenly the circle appears! Moreover, if I right-click the element again, now it shows as "Edit as SVG...", which is suspicious.
Even more fun: If I load the page, click the button, and then do the above trick, the colour animation runs!
Note that if I edit the HTML and change nothing, it doesn't work. I have to make a trivial change to the text (or else I guess the browser decides it doesn't need to reprocess?)
I was so convinced this was going to end up being a weird Firefox bug... but then I tried it in Chrome and Edge, and it does exactly the same thing!
Does anybody have to vaguest clue why this doesn't work? Have I done something wrong with the Elm code? (I'm really, really struggling to figure out how this library works; I'm basically just guessing how the types fit together. So maybe I've done something dumb.)