Hi everyone ![]()
Iβm happy to announce the first release of elm-motion β a comprehensive animation and scrolling library for Elm.
The core idea: six animation engines behind a single, consistent builder API. You describe what should animate once, then decide how it runs by selecting (or swapping) the engine β CSS transitions, keyframes, pure-Elm frames, or the Web Animations API β without rewriting your definitions. Alongside them are three scroll engines with their own API in the same builder style.
Animation engines (one shared API)
- Transition β CSS transitions, minimal setup
- Keyframe β CSS keyframes with looping and full control
- Sub β pure Elm, frame-based, with real-time state queries
- WAAPI β the Web Animations API, via a small JS companion
- ScrollTimeline β scroll-driven animation
- ViewTimeline β viewport-driven animation
The Transition, Keyframe and Sub engines (and all scroll engines) are pure Elm β no ports, no JavaScript. The WAAPI/ScrollTimeline/ViewTimeline engines use an optional companion (@phollyer/elm-motion on npm) for hardware-accelerated and scroll-driven motion.
Scroll engines
- Cmd β fire-and-forget
- Task β composable, with error handling
- Sub β stateful, with mid-scroll queries
Also included
- Property modules: opacity, translate, rotate, scale, skew, size, perspective-origin, plus
Custom(any numeric CSS property) andCustomColor(any color property) - Shared easing helpers for animation and scroll engines
- Springs support for 5 of the 6 animation engines
- Reduced-motion support β the WAAPI-based engines honour
prefers-reduced-motion: reduce, snapping to the end state while still firing lifecycle events
Getting started
elm install phollyer/elm-motion
Thereβs a documentation site with guides and live examples here: Elm Motion
Feedback welcome
This is my most ambitious Elm project so far, and Iβd love to hear what you think β API ergonomics, missing pieces, rough edges, or things youβd animate with it. Issues and ideas are very welcome on the GitHub repo.
Thanks to the Elm community β Iβve learned a huge amount here, and this is a small way of giving back while also having a great deal of fun creating it. ![]()