elm-style-animation

by mdgriffith

The style animation library for Elm!

451 Stars 39 Forks Last release: Not found BSD 3-Clause "New" or "Revised" License 305 Commits 26 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

The Style Animation library for Elm!

The Basics

To get started, there are a few things that need to happen.

Set an initial style in your model.

import Animation exposing (px)

init : Model init = { style = Animation.style [ Animation.left (px 0.0) , Animation.opacity 1.0 ] }

Subscribe to Animation's subscription. This will animate using AnimationFrame when something is running, and stop giving updates when there is no animation. ```elm subscriptions : Model -> Sub Msg subscriptions model = Animation.subscription Animate [ model.style ]

Set up an update Msg in your update function.

```elm Animate animMsg -> { model | style = Animation.update animMsg model.style }

Render our animation at the necessary element in your view. Not all animated properties are style properties(such as the svg.d property and polygon.points property), so

Animation.render
actually returns a list of
Html.Attributes
. Fortunately, you can add your own style because
Html.Attributes.style
stacks!
elm
    div
        (List.concat
            [ Animation.render model.style
            , [ style
                    [ ( "position", "absolute" )
                    , ( "border-style", "dotted" )
                    ]
               ]
            ]
        )
        [ text "This is being Animated!" ]

Start an animation in your update statement.

case msg of
    Show ->
        let 
            newStyle = 
                Animation.interrupt
                    [ Animation.to 
                        [ Animation.left (px 0.0)
                        , Animation.opacity 1.0
                        ]
                    ]
                    model.style
        in
            { model
                | style = newStyle
            }

Here's generally how we compose animations.

  • Choose
    Animation.queue
    or
    Animation.interrupt
    , both of which take a list of steps and your animation model. This describes what the strategy should be if the thing you're trying to animate is already in the process of being animated. You either want to interrupt what its doing and do this new animation. Or you want to queue up this new animation to run after the current animation is finished. 90% of the time you want
    Animation.interrupt
  • Steps can be
    • Animation.to
      - Animate to a target style
    • Animation.set
      - Set a animation to a style immediately.
    • Animation.wait (5 * second)
      - wait for some amount of time
    • Animation.repeat x [..list of steps to repeat]
      - Repeat a list of steps x times.
    • Animation.loop [..list of steps to repeat]
      - Loop a list of steps forever/until interrupted.

Examples

Advanced!

Note!

The compiler is going to refer to your animation model as

Animation.Model.Animation msg
.
Animation.State
is just a synonym for that.

Sending Messages

  • Send Messages Example - Code

First, import

Animation.Messenger

Change your

Animation.State
to
Animation.Messenger.State MyMsgType
.

You can now use

Animation.Messenger.send MyCustomMessage
as a step in composing your animation.

You need to update this new animation state using

Animation.Messenger.update
, which will return
(newAnimState, messagesSentinCmdForm)
. So you need to change your animation update section to something like the following.
case msg of
    Animate animMsg ->
        let
            (newStyle, cmds) =
                Animation.Messenger.update
                    animMsg
                    model.style
        in
            ( { model
                 | style = newStyle
              },
              cmds
            )

Note! Make sure you're sending the cmds in the above code. If you're note, then the animation will run, but the messages won't be sent.

Also, if you're running this in a child component, make sure you're

Cmd.map
ing the child's commands back to the child or else the messages will be lost!

Animating Properties that aren't directly supported.

You can construct custom properties if you don't find them in the library using

Animation.custom
. These will be rendered in the style property.
Animation.to
    [ Animation.custom "my-custom-prop" 5 "px"
    ]

There is also

customColor
for color based properties.

Setting Custom Interpolation

Behind the curtain elm-style-animation mostly uses springs to animate values from A to B. However you can specify custom values for a spring, or a duration and easing if you want. There are two basic ways to do this.

Set them with your initial style.

Use

Animation.styleWith
or
Animation.styleWithEach
to set your initial style instead of
Animation.style
.
Animation.styleWith
    (Animation.spring
        { stiffness = 400
        , damping = 23 }
    )
    [ Animation.opacity 0
    , Animation.left (px 20)
    ]

This will set the spring used for these properties. Alternatively

Animation.styleWithEach
is a way to set a custom interpolation for each individual property.

Set a temporary spring/duration + easing

You can also use

Animation.toWith
and
Animation.toWithEach
. These can be substituted for
Animation.to
and allow you to specify a spring or duration+easing that lasts for exactly one step. After that step, whatever default spring or duration/easing there is (either the auto default or via being specified in
Animation.styleWith
) is then used.
Animation.interrupt
    [ Animation.toWith
        (Animation.easing
            { duration = 2*second
            , ease = (\x -> x^2)
            }
        ) 
        [ Animation.left (px 0.0)
        , Animation.opacity 1.0
        ]
    ]
    model.style

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.