Skip to content

Instantly share code, notes, and snippets.

@coreyhaines coreyhaines/Animation.elm
Last active Jun 19, 2017

Embed
What would you like to do?
Animation support library
html,head,body { padding:100px; margin:0; }
body { font-family: calibri, helvetica, arial, sans-serif; }
.fader {
display: none;
opacity: 0.0;
}
.fader.animating {
display: block;
transition: opacity 1s linear;
}
.fader.shown {
display: block;
opacity: 1.0;
}
.left, .right {
height: 200px;
}
module Animation exposing (..)
import Task
import Process
import Time exposing (Time, millisecond)
type Animation state
= Setup state
| Animate state
| Done state
type alias AnimationDelays =
{ setup : Time
, animate : Time
, done : Time
}
type ShowHideState
= Show
| Hide
type alias ShowHideAnimation =
Animation ShowHideState
type alias ShowHideStateAnimationDelays =
{ show : AnimationDelays
, hide : AnimationDelays
}
standardShortDelays : AnimationDelays
standardShortDelays =
{ setup = 10
, animate = 150
, done = 0
}
standardMediumDelays : AnimationDelays
standardMediumDelays =
{ setup = 10
, animate = 300
, done = 0
}
standardLongDelays : AnimationDelays
standardLongDelays =
{ setup = 10
, animate = 1000
, done = 0
}
delaysForShowHideState : ShowHideStateAnimationDelays -> ShowHideState -> AnimationDelays
delaysForShowHideState delays state =
case state of
Hide ->
delays.hide
Show ->
delays.show
transitionTask : Animation state -> Time -> Cmd (Animation state)
transitionTask animation delay =
Task.perform identity (always animation) (Process.sleep <| delay * millisecond)
startShowHideAnimation : ShowHideStateAnimationDelays -> ShowHideAnimation -> Cmd ShowHideAnimation
startShowHideAnimation delays animation =
let
delaysRecord =
delaysForShowHideState delays
in
case animation of
Done Hide ->
transitionTask (Setup Show) (delaysRecord Show).setup
Done Show ->
transitionTask (Setup Hide) (delaysRecord Hide).setup
_ ->
Cmd.none
transitionShowHideAnimationState : ShowHideStateAnimationDelays -> ShowHideAnimation -> Cmd ShowHideAnimation
transitionShowHideAnimationState delays currentAnimation =
let
delaysRecord =
delaysForShowHideState delays
in
case currentAnimation of
Setup state ->
transitionTask (Animate state) (delaysRecord state).setup
Animate state ->
transitionTask (Done state) (delaysRecord state).animate
Done _ ->
Cmd.none
classesForShowHideStateAnimations : ShowHideAnimation -> String
classesForShowHideStateAnimations animation =
case animation of
Setup Show ->
"animating"
Animate Show ->
"animating shown"
Done Show ->
"shown"
Setup Hide ->
"animating shown"
Animate Hide ->
"animating"
Done Hide ->
""
invertShowHideState : ShowHideState -> ShowHideState
invertShowHideState state =
case state of
Show ->
Hide
Hide ->
Show
invertShowHideStateForAnimation : ShowHideAnimation -> ShowHideAnimation
invertShowHideStateForAnimation animation =
case animation of
Setup a ->
Setup <| invertShowHideState a
Animate a ->
Animate <| invertShowHideState a
Done a ->
Done <| invertShowHideState a
classesForShowHideStateAnimationInverted : ShowHideAnimation -> String
classesForShowHideStateAnimationInverted =
invertShowHideStateForAnimation >> classesForShowHideStateAnimations
showHideIsInTransitTo : ShowHideState -> ShowHideAnimation -> Bool
showHideIsInTransitTo state animation =
case animation of
Setup a ->
a == state
Animate a ->
a == state
Done a ->
a == state
showHideIsInTransitToShow : ShowHideAnimation -> Bool
showHideIsInTransitToShow =
showHideIsInTransitTo Show
showHideIsInTransitToHide : ShowHideAnimation -> Bool
showHideIsInTransitToHide =
showHideIsInTransitTo Hide
elm make src/Start.elm --output elm.js
<!DOCTYPE HTML>
<html><head><meta charset="UTF-8"><title>Main</title>
<link href="animation.css" rel="stylesheet">
<script type="text/javascript" src="elm.js"> </script>
</head>
<body>
<script type="text/javascript">Elm.Start.fullscreen()</script>
</body></html>
module Start exposing (..)
import Animation
import Html.App as App
import Html exposing (Html, text, div, h1)
import Html.Attributes exposing (class, classList)
import Html.Events exposing (onClick)
type alias Model =
{ name : String
, faderAnimation : Animation.ShowHideAnimation
, fader2Animation : Animation.ShowHideAnimation
}
type Msg
= NoOp
| ShowFader
| TransitionFaderAnimation Animation.ShowHideAnimation
| ShowFader2
| TransitionFader2Animation Animation.ShowHideAnimation
faderDelay : Animation.ShowHideStateAnimationDelays
faderDelay =
{ show = Animation.standardLongDelays
, hide = Animation.standardLongDelays
}
init : ( Model, Cmd Msg )
init =
( { name = "Elm Remote Conf"
, faderAnimation = Animation.Done Animation.Hide
, fader2Animation = Animation.Done Animation.Hide
}
, Cmd.none
)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
ShowFader ->
let
transitionCmd =
Animation.startShowHideAnimation faderDelay model.faderAnimation
in
( model
, Cmd.map TransitionFaderAnimation transitionCmd
)
TransitionFaderAnimation animation ->
let
_ =
Debug.log "Transition" animation
transitionCmd =
Animation.transitionShowHideAnimationState faderDelay animation
in
( { model | faderAnimation = animation }
, Cmd.map TransitionFaderAnimation transitionCmd
)
ShowFader2 ->
let
transitionCmd =
Animation.startShowHideAnimation faderDelay model.fader2Animation
in
( model
, Cmd.map TransitionFader2Animation transitionCmd
)
TransitionFader2Animation animation ->
let
_ =
Debug.log "Transition2" animation
transitionCmd =
Animation.transitionShowHideAnimationState faderDelay animation
in
( { model | fader2Animation = animation }
, Cmd.map TransitionFader2Animation transitionCmd
)
fader : Model -> Html Msg
fader model =
let
contentHtml =
case model.faderAnimation of
Animation.Done (Animation.Hide) ->
text ""
_ ->
div
[ classList
[ ( "fader", True )
, ( Animation.classesForShowHideStateAnimations model.faderAnimation, True )
]
]
[ text "This fades in and out" ]
in
div []
[ div
[ onClick ShowFader ]
[ text "Fader" ]
, contentHtml
]
twoFaders : Model -> Html Msg
twoFaders model =
let
contentHtml =
div [ class "twoFader" ]
[ div
[ classList
[ ( "fader", True )
, ( Animation.classesForShowHideStateAnimationInverted model.fader2Animation, True )
]
]
[ text <| "Hello, " ++ model.name ]
, div
[ classList
[ ( "fader", True )
, ( Animation.classesForShowHideStateAnimations model.fader2Animation, True )
]
]
[ text <| "Goodbye, " ++ model.name ]
]
in
div []
[ div [ onClick ShowFader2 ]
[ text "Two Faders" ]
, contentHtml
]
view : Model -> Html Msg
view model =
div []
[ h1 [] [ text "OMG! CSS TRANSITIONS" ]
, div [ class "left" ]
[ fader model ]
, div [ class "right" ]
[ twoFaders model ]
]
main : Program Never
main =
App.program
{ init = init
, update = update
, view = view
, subscriptions = always Sub.none
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.