Elm-Motion pre-publish feedback request

Hello all,

I’d like to share Elm-Motion, a library for animations and scrolling built around one idea: define an animation or scroll once, then run it on whichever engine fits - without rewriting the animation or scroll.

hellotext

Build once, swap engines

The animation definition is engine-agnostic. The same fadeIn runs on any engine:


-- Define it once - reusable, engine-agnostic
fadeIn : AnimBuilder { eng | withTiming : () } -> AnimBuilder { eng | withTiming : () }
fadeIn =
    Opacity.begin
        >> Opacity.to 1
        >> Opacity.duration 2500
        >> Opacity.end

-- Run it with the Transition engine (pure CSS, minimal setup)
Transition.animate model.animState <|
    Transition.for "box" 
        >> fadeIn

-- ...or the Keyframe engine (CSS @keyframes) - same `fadeIn`, no rewrite
Keyframe.animate model.animState <|
    Keyframe.for "box" 
        >> fadeIn


-- ...or the Sub engine (pure Elm, frame-based) - same `fadeIn`, no rewrite
Sub.animate model.animState <|
    Sub.for "box" 
        >> fadeIn

-- ...or the WAAPI engine (JS Web Animations API) - same `fadeIn`, no rewrite
WAAPI.animate model.animState <|
    WAAPI.for "box"
        >> fadeIn

Some engines have more capabilities than others - the type system and compiler keep you honest about what each one supports.

Animation engines

  • Transition - Simplest - CSS transitions, minimal setup
  • Keyframe - CSS keyframes, looping, full control
  • Sub - Pure Elm, frame-based, real-time queries
  • WAAPI - JS Web Animations API, fine-grained control
  • ScrollTimeline - Scroll-driven (via WAAPI)
  • ViewTimeline - Viewport/element-in-view driven (via WAAPI)

Scroll engines

  • Cmd - Fire-and-forget
  • Task - Composable, with error handling
  • Sub - Stateful, full control, mid-scroll queries

The same scroll configuration works across all three.

Pure Elm vs JS interop

  • Pure Elm, no setup: Transition, Keyframe, Sub.
  • Needs JS companion (@phollyer/elm-motion, on npm + CDN): WAAPI, ScrollTimeline, ViewTimeline — these drive the browser’s Web Animations / scroll-timeline APIs through ports.

Links

Status

It’s not published yet - I can’t possibly test every edge case or use, so if you’d like to have a play, any and all feedback would really be appreciated.

Thanks for taking a look!

10 Likes

Looks fantastic and very comprehensive approach to animation in Elm. Always been a pain when you wanted to add some “magic” in your pages… How easily can this be integrated within an elm-ui app for example?

1 Like

Hi FelmLemar,

It’s completely view agnostic. So all you need to do is use Elm-UI’s helper functions:

engineAttrs : Model -> List (Element.Attribute msg)
engineAttrs model =
    -- swap 'Engine' for your chosen engine
    Engine.attributes "animGroupName" model.animState
        |> List.map Element.htmlAttribute

Glad you like it.

And welcome to the community :slight_smile:

Thank you Paul, impressive work. Always amazed by the quality of the Elm lang & its eco-system. Will share more when I get an opportunity to implement in a project.

2 Likes