Fading page transition with elm-ui+elm-animator?

Hey!

I’m working on a game where you transition between different states, and for some of these I’d like to have a fading animation between each stage.

I have have a graph of what we call scenes in the game, where each scene has a set of nodes (we call those frames), a set of edges (called choices, taking you to the next frame). We represent it as a graph. So the aim is that when a choice is clicked, we transition to the new frame.

My initial thinking was simply to check that if the node ID is different from the current frame, it should set the animation opacity to zero


animation : FrameId -> Animator.Timeline FrameId -> Html.Attribute Msg
animation frameId timeline =
    Animator.Inline.opacity timeline <|
        \currentFrame ->
            if currentFrame == frameId then
                Animator.at 1

            else
                Animator.at 0

Then I set up the following render function

render : List (Element.Attribute Msg) -> Frame -> Element.Element Msg
render attributes frame =
    let
        node =
            frame.node

        choices =
            IntDict.toList frame.outgoing
                |> List.filterMap
                    (\( id, choice ) ->
                        case choice of
                            Prompt str ->
                                Just ( id, str )
                    )
    in
    case node.label of
        Display text ->
            Element.column (attributes ++ [ Element.spacing 24, Element.scrollbarX ])
                [ textPrompt text
                , listChoices choices
                ]

Later I render it with

-- latest is the current Frame id from Animation.current, frame is the node.
render [ Element.htmlAttribute <| animation latest model.frameState ] frame

Now I’m curious how I can at the same time fade out the old page? With my current setup the new page only fades in and the old doesn’t transition “out”.

I thought maybe I could use an attribute like Element.below (render [ Element.htmlAttribute <| animation oldFrameId model.frameState ] oldFrame) but this doesn’t render correctly.