Skip to content

Instantly share code, notes, and snippets.

@axelerator
Last active May 3, 2020 02:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save axelerator/0fc300493b0de188bbffb3f462ba44b7 to your computer and use it in GitHub Desktop.
Save axelerator/0fc300493b0de188bbffb3f462ba44b7 to your computer and use it in GitHub Desktop.
animation_navigation.elm
module Main exposing (Model, Msg(..), init, main, subscriptions, update, view)
import Animation exposing (px)
import Browser
import Browser.Navigation as Nav
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Url
main : Program () Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
, onUrlChange = UrlChanged
, onUrlRequest = LinkClicked
}
type alias Model =
{ style : Animation.State
, pos : Bool
, key : Nav.Key
, url : Url.Url
}
init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init _ url key =
( { style =
Animation.style
[ Animation.left (px 0.0)
]
, pos = False
, url = url
, key = key
}
, Cmd.none
)
subscriptions : Model -> Sub Msg
subscriptions model =
let
_ =
Debug.log "Subscription for animation:" model.style
in
Animation.subscription Animate [ model.style ]
type Msg
= FadeInFadeOut
| Animate Animation.Msg
| LinkClicked Browser.UrlRequest
| UrlChanged Url.Url
reanimateIfNecessarry : Url.Url -> Model -> Model
reanimateIfNecessarry url model =
let
newPos =
case url.fragment of
Just frag ->
if frag == "left" then
True
else
False
_ ->
model.pos
newStyle =
if newPos /= model.pos then
let
l =
if model.pos then
100
else
-100
_ =
Debug.log "setting new style to model left:" l
in
Animation.interrupt
[ Animation.to
[ Animation.left (px l)
]
]
model.style
else
model.style
in
{ model
| url = url
, pos = newPos
, style = newStyle
}
update : Msg -> Model -> ( Model, Cmd Msg )
update action model =
case action of
LinkClicked urlRequest ->
case urlRequest of
Browser.Internal url ->
( model, Nav.pushUrl model.key (Url.toString url) )
-- Calling reanimate here as well will 'fix' the problem
-- ( reanimateIfNecessarry url model, Nav.pushUrl model.key (Url.toString url) )
Browser.External href ->
( model, Nav.load href )
UrlChanged url ->
( reanimateIfNecessarry url model, Cmd.none )
FadeInFadeOut ->
( { model
| pos = not model.pos
, style =
let
l =
if model.pos then
100
else
-100
in
Animation.interrupt
[ Animation.to
[ Animation.left (px l)
]
]
model.style
}
, Cmd.none
)
Animate animMsg ->
( { model
| style = Animation.update animMsg model.style
}
, Cmd.none
)
view : Model -> Browser.Document Msg
view model =
{ title = "Animation & Naviagion"
, body =
[ div
[ style "border" "1px solid red"
, style "position" "relative"
, style "margin" "100px auto"
, style "width" "400px"
, style "height" "250px"
]
[ div
(Animation.render model.style
++ [ style "position" "relative"
, style "margin" "0 auto"
, style "padding" "25px"
, style "width" "200px"
, style "height" "200px"
, style "background-color" "#268bd2"
, style "color" "white"
]
)
[ text "Click to Animate!" ]
]
, div []
[ a [ href "#left" ] [ text "left" ]
, br [] []
, a [ href "#right" ] [ text "right" ]
]
]
}
@axelerator
Copy link
Author

After the first UrlChanged a new style gets applied to the model. But the subscription does not trigger new Animate messages to update the position. However if I click the link again the animation gets kicked off.
What am I missing?
screencast 2020-05-02 22-01-52

@axelerator
Copy link
Author

axelerator commented May 3, 2020

The problem seems to be related to the issue @mdgriffith mentions in one of his examples:
https://github.com/mdgriffith/elm-animator/blob/master/examples/Pages.elm#L134

I added the fix as a comment in line 116

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment