|
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" ] |
|
] |
|
] |
|
} |
After the first

UrlChanged
a newstyle
gets applied to the model. But the subscription does not trigger newAnimate
messages to update the position. However if I click the link again the animation gets kicked off.What am I missing?