Skip to content

Simultaneous animations

Brian Marick edited this page Aug 31, 2017 · 1 revision

Full source

The animation has this FixedPart:

view : AnimationModel -> Svg msg
view =
  animatable S.rect <| HasFixedPart
    [ SA.width "40"
    , SA.x "100"
    , SA.fill "grey"
    ]

The width of the droplet is fixed, but the height and y position are not. We start with a full rectangle:

initStyles : List Animation.Property
initStyles =
  [ Animation.y 10
  , Animation.height (Animation.px 100)
  ]

The animation moves to from the starting value to the height of 0. Because SVG y values grow downward, we also have to change the top of the rectangle:

drainedStyles : List Animation.Property    
drainedStyles =
  [ Animation.y 110
  , Animation.height (Animation.px 0)
  ]

If we didn't change the y value, the fluid would shrink from the bottom instead of the top.

The new AnimationModel has to be added to the App.Model, and started alongside the droplet in update:

  case msg of
    Start ->
      ( { model
          | droplet = Droplet.falls model.droplet
          , fluid = Fluid.drains model.fluid          -- Added
        }
      , Cmd.none
      )

Each Tick message needs to change both AnimationModels:

    Tick subMsg ->
      ( { model
          | droplet = Animation.update subMsg model.droplet
          , fluid = Animation.update subMsg model.fluid       -- Added
        }
      , Cmd.none
      )

And the fluid needs to be added to the view:

view : Model -> Html Msg
view model =
  Layout.wrapper
    [ Layout.canvas [ Droplet.view model.droplet
                    , Fluid.view model.fluid        -- Added
                    ]
    , Layout.button Start "Click Me"
    ]

Finally, the app should be added to the subscription list:

subscriptions : Model -> Sub Msg    
subscriptions model =
  Animation.subscription Tick
    [ model.droplet
    , model.fluid                    -- Added
    ]

When that list becomes empty, the app will unsubscribe to the browser's animation loop. That is, each model doesn't get its own Tick: if any models are running, they all share the same Tick.

(Since model.droplet never stops, it's not strictly necessary to add model.fluid)

Clone this wiki locally