Animate the height of a container to its contents
Simply get any view and elm-animate-height
will take care of animating.. well.. the height!
Animating the height of a container in a resilient way can get really tricky really fast! There's
performance, dom queries, height information to manage, timing calculations, interruptions and a whole
lot of gnarly edge cases.
From the outset elm-animate-height's number one goal was to make set up as frictionless as possible.
Here are the steps,
Set an initial state in your model.
init : Model
init = initialState (uniqueContainerId "123")Subscribe to AnimateHeight subscription.
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.map AnimateMsg (AnimateHeight.subscription model)Set up an update Msg in your update function.
AnimateMsg animMsg ->
let
(newState, cmds) = update model.animState
in
({ model | animState = newState }, Cmd.map AnimateHeight cmds)Render your view in our container.
someCoolView : Html Msg
someCoolView :
-- cool view stuff --
view : Model -> Msg
view model =
container
(default
|> content someCoolView
|> state model.animHeightState
)Trigger an Animation in your update statement.
case msg of
ShowContainerStuff ->
(toHigh animHeightState, Cmd.none)
HideContainerStuff ->
(toLow animHeightState, Cmd.none)Animating the height of a container does mean paying a performance cost. The browser needs to perform layout and paint operations and these can be expensive.
elm-animate-height gives you two strategies in which to perform
the animation, Transition and AnimationFrame.
Transition leverages css transitions to perform the animation which
means no view updates are triggered on the container.
AnimationFrame will trigger view updates but manually calculates the height
of the container to the browsers refresh cadence.
Which one performs the best in your situation is just a matter of experimenting.
Setting the strategy can be done on the initial state
init : Model
init =
initialState (uniqueContainerId "123")
|> animationFrame Sometimes the content you give elm-animate-height can change. For example
you might have a list of old wooden ship names that you can add and remove,
making the list longer or shorter. To animate the container height to the
changing content you can ask elm-animate-height to perform a recalculation.
case msg of
ContentChanged ->
let
newstate =
recalculation model.animHeightState
in
({ model | animHeightState = newState }, Cmd.none)