buildrtech / elm-animator-with-elm-css / Animator.Watcher

If you're tracking a number of timelines in your model, you may decide to use a Watching to simplify adding new timelines.


type alias Watching model =
Internal.Timeline.Animator model

An Animator knows how to read and write all the Timelines within your Model.

Here's an animator from the Checkbox.elm example,

import Animator.Watcher as Watcher

animator : Watcher.Watching Model
animator =
    Watcher.init
        |> Watcher.watching
            -- we tell the animator how
            -- to get the checked timeline using .checked
            .checked
            -- and we tell the animator how
            -- to update that timeline as well
            (\newChecked model ->
                { model | checked = newChecked }
            )

Notice you could add any number of timelines to this animator:

animator : Watcher.Watching Model
animator =
    Watcher.init
        |> Watcher.watching
            .checked
            (\newChecked model ->
                { model | checked = newChecked }
            )
        |> Watcher.watching
            .anotherChecked
            (\anotherCheckboxState ->
                { model | anotherChecked = anotherCheckboxState }
            )

Note — You likely only need one animator for a given project.

Note 2 — Once we have an Animator Model, we have two more steps in order to set things up:

init : Watching model

watching : (model -> Animator.Timeline.Timeline state) -> (Animator.Timeline.Timeline state -> model -> model) -> Watching model -> Watching model

list : (model -> List item) -> (List item -> model -> model) -> Watching item -> Watching model -> Watching model

update : Time.Posix -> Watching model -> model -> model

When new messages come in, we then need to update our model. This looks something like this:

type Msg
    = Tick Time.Posix

update msg model =
    case msg of
        Tick newTime ->
            ( Animator.update newTime animator model
            , Cmd.none
            )

And voilà, we can begin animating!

Note — To animate more things, all you need to do is add a new with to your Animator.

toSubscription : (Time.Posix -> msg) -> model -> Watching model -> Platform.Sub.Sub msg

Convert an Animator to a subscription.

This is where the animator will decide if a running animation needs another frame or not.

subscriptions model =
    Animator.toSubscription Tick model animator