CSS keyframe animations with browser-native performance.
This engine is a good fit for 'on-load' animations, or if you need looping, alternating, or pause/resume functionality.
📖 See Keyframe Engine Documentation and Engine Overview for details.
The name of the animation group you want to target.
Type alias for the base AnimBuilder type.
Builder type for Keyframe-only builders.
Use this in type annotations when a builder function should only work with this engine.
Equivalent to AnimBuilder ForKeyframe.
📖 See Engine Capabilities for patterns and examples.
📖 See Initialize for details.
Initialize the engine state with optional property initializers.
import Anim.Engine.Keyframe as Keyframe
import Anim.Property.Opacity as Opacity
Keyframe.init
[ Opacity.init "animGroupName" 0.5
, ... -- other property initializers
]Select the animation group that subsequent property builders will target.
Keyframe.for "animGroupName"
>> Opacity.begin
>> Opacity.to 0.2
>> Opacity.end📖 See Triggering Animations for details.
Trigger animations.
import Anim.Engine.Keyframe as Keyframe
{ model
| animState =
Keyframe.animate model.animState <|
Keyframe.for "animGroupName"
>> entryAnim
}Change the targeted properties instantly to their new values. If currently animating, stop.
This is a convenience function for immediately snapping properties or axes to new values
without needing to construct a full animation builder with animate.
Just target the properties or axes you want to change. Any other properties or axes on the group will snap to their targeted end values if mid-flight.
import Anim.Engine.Keyframe as Keyframe
import Anim.Property.Translate as Translate
{ model
| animState =
Keyframe.retarget model.animState <|
Keyframe.for "animGroupName"
>> Translate.begin
>> Translate.toY 0
>> Translate.end
}📖 See Event Reference for details.
The ID of the element that owns the event listener.
The ID of the element that started the event.
This will be different from CurrentTargetId if the event bubbled from a child element.
CSS keyframe animation lifecycle events.
📖 See React for details.
Message type used with update.
import Anim.Engine.Keyframe as Keyframe
type Msg
= KeyframeMsg Keyframe.AnimMsg
| ...Handle messages from this engine.
Returns the updated state and an event for this message, if one should be surfaced.
import Anim.Engine.Keyframe as Keyframe
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyframeMsg animMsg ->
let
( animState, maybeEvent ) =
Keyframe.update animMsg model.animState
nextModel =
{ model | animState = animState }
in
case maybeEvent of
Just event ->
handleAnimationEvent event nextModel
Nothing ->
( nextModel, Cmd.none )
handleAnimationEvent : Keyframe.AnimEvent -> Model -> ( Model, Cmd Msg )
handleAnimationEvent event model =
case event of
...To render keyframes, add attributes to the element and include styleNode
or styleNodeFor somewhere in your view.
📖 See Render and Keyframe Style Node for details.
Apply the animation attributes to your element.
import Anim.Engine.Keyframe as Keyframe
import Html exposing (div, text)
div
(Keyframe.attributes "animGroupName" animState)
[ text "Animating element" ]Get a <style> node containing the keyframes for all animations.
import Anim.Engine.Keyframe as Keyframe
import Html exposing (div)
view model =
div []
[ Keyframe.styleNode model.animState
, ...
]If there are no animations, this returns an empty text node.
Get a <style> node containing keyframes for a specific animation group.
import Anim.Engine.Keyframe as Keyframe
import Html exposing (div)
view model =
div []
[ Keyframe.styleNodeFor "animGroupName" model.animState
, ...
]If there are no animations, this returns an empty text node.
Get the raw generated CSS keyframes string for advanced use cases.
You probably want styleNodeFor instead,
which handles creating the full <style> node for you.
📖 See Events for details.
Receive keyframe animation lifecycle events.
Add events to your element with a message constructor that wraps AnimMsg.
import Anim.Engine.Keyframe as Keyframe
import Html exposing (div, text)
type Msg
= KeyframeMsg Keyframe.AnimMsg
div
(Keyframe.attributes "animGroupName" animState
++ Keyframe.events "animGroupName" KeyframeMsg
)
[ text "Animating element" ]The same as events but with propagation stopped.
import Anim.Engine.Keyframe as Keyframe
import Html exposing (div, text)
div
(Keyframe.attributes "animGroupName" animState
++ Keyframe.eventsStopPropagation "animGroupName" KeyframeMsg
)
[ text "Animated element" ]Set the default length unit for all length-bearing properties.
responsivePanelMotion : AnimBuilder eng -> AnimBuilder eng
responsivePanelMotion =
cssUnit Unit.Vw
>> slidePanelIn
>> growPanelSet the default length unit for the X axis.
responsiveDrawerMotion : AnimBuilder eng -> AnimBuilder eng
responsiveDrawerMotion =
cssUnitX Unit.Vw
>> slidePanelIn
>> growPanelSet the default length unit for the Y axis.
responsiveSheetMotion : AnimBuilder eng -> AnimBuilder eng
responsiveSheetMotion =
cssUnitY Unit.Vh
>> slidePanelIn
>> growPanelSet the default length unit for the Z axis.
layeredSceneMotion : AnimBuilder eng -> AnimBuilder eng
layeredSceneMotion =
cssUnitZ Unit.Px
>> slidePanelIn
>> growPanelSet the default length unit used for width values in Keyframe animations.
responsiveCardWidth : AnimBuilder eng -> AnimBuilder eng
responsiveCardWidth =
cssUnitWidth Unit.Vw
>> slidePanelIn
>> growPanelSet the default length unit used for height values in Keyframe animations.
responsivePanelHeight : AnimBuilder eng -> AnimBuilder eng
responsivePanelHeight =
cssUnitHeight Unit.Vh
>> slidePanelIn
>> growPanelThese functions are precedence functions, so they can operate as a global setting for all groups in the builder chain, or you can set them on a per-group basis which overrides any global setting for that group.
Keyframe.iterations 3 -- global setting
>> Keyframe.for "box"
>> Keyframe.iterations 5 -- overrides global for this group
>> ... -- other buildersSet how many times an animation should repeat.
Make an animation loop infinitely.
Make an animation alternate direction on each iteration.
Only has a visible effect when the animation runs more than once,
so calling it when iterations is unset or 1 automatically bumps
iterations to 2.
An explicit iterations count (or loopForever) set before or after
alternate is preserved.
📖 See Timing for details.
Set the global delay for all animations in this builder.
introAnim : AnimBuilder eng -> AnimBuilder eng
introAnim =
delay 500
>> fadeInHeader
>> slideInSidebar
>> fadeInContentSet the global duration for all animations in this builder.
introAnim : AnimBuilder eng -> AnimBuilder eng
introAnim =
duration 500
>> fadeInHeader
>> slideInSidebar
>> fadeInContentSet the global speed for all animations in this builder.
introAnim : AnimBuilder eng -> AnimBuilder eng
introAnim =
speed 300
>> slideDownHeader
>> slideInSidebar
>> slideUpContent📖 See Easing for details.
Set the global easing function.
heroEntrance : AnimBuilder eng -> AnimBuilder eng
heroEntrance =
easing EaseInOut
>> fadeInHeroTitle
>> slideInHeroArtwork
>> revealPrimaryCtaSet the global spring.
draggableCardSettle : AnimBuilder eng -> AnimBuilder eng
draggableCardSettle =
spring Spring.wobbly
>> settleCardPosition
>> settleCardShadow📖 See Controlling Animations for details.
Stop a running animation by instantly jumping to its end state.
import Anim.Engine.Keyframe as Keyframe
Keyframe.stop "animGroup" model.animStateReset an animation by instantly jumping back to its start state.
import Anim.Engine.Keyframe as Keyframe
Keyframe.reset "animGroup" model.animStateRestart an animation from the beginning.
import Anim.Engine.Keyframe as Keyframe
let
( newState, cmd ) =
Keyframe.restart "boxAnim" GotAnimMsg model.animState
in
( { model | animState = newState }, cmd )Pause a running animation.
import Anim.Engine.Keyframe as Keyframe
let
( newState, cmd ) =
Keyframe.pause "boxAnim" GotAnimMsg model.animState
in
( { model | animState = newState }, cmd )Resume a paused animation.
import Anim.Engine.Keyframe as Keyframe
let
( newState, cmd ) =
Keyframe.resume "boxAnim" GotAnimMsg model.animState
in
( { model | animState = newState }, cmd )📖 See Discrete Properties for details.
Add a discrete CSS property for entry animations.
The value is applied at every step of the animation, ensuring the element is immediately in the target state when the animation starts. The browser already knows the element's pre-animation state from its own CSS.
This function is a precedence function, so it can operate as a global setting for all groups in the builder chain, or you can set it on a per-group basis which overrides any global setting for that group.
import Anim.Engine.Keyframe as Keyframe
import Anim.Property.Opacity as Opacity
Keyframe.animate model.animState <|
Keyframe.discreteEntry "display" "block"
>> Keyframe.discreteEntry "pointer-events" "auto"
>> Keyframe.for "box"
>> Opacity.begin
>> Opacity.to 1
>> Opacity.endAdd a discrete CSS property for exit animations.
Exit animations need to hold their initial state until the very end of the animation, at which point they flip to the final state. Therefore you need to set both entry and exit values for the property.
This function is a precedence function, so it can operate as a global setting for all groups in the builder chain, or you can set it on a per-group basis which overrides any global setting for that group.
Use when an element is disappearing (e.g., going from
display: block to display: none):
import Anim.Engine.Keyframe as Keyframe
import Anim.Property.Opacity as Opacity
Keyframe.animate model.animState <|
Keyframe.discreteExit "display" "block" "none"
>> Keyframe.for "box"
>> Opacity.begin
>> Opacity.to 0
>> Opacity.end📖 See Transform Ordering for details.
Set the transform order.
The transform order specifies how translate, rotate, skew and scale transforms
are combined. Start the list with the transform to apply first.
This is a precedence function, so it can operate as a global setting for all groups in the builder chain, or you can set it on a per-group basis which overrides any global setting for that group.
Any missing transforms are automatically appended in the default order
(Translate → Rotate → Skew → Scale).
import Anim.Engine.Keyframe as Keyframe
import Anim.Extra.TransformOrder exposing (TransformProperty(..))
Keyframe.transformOrder [ Scale, Rotate, Translate, Skew ] -- global setting
>> Keyframe.for "box"
>> Keyframe.transformOrder [ Rotate, Translate ] -- overrides global for this group
>> ... -- other builders📖 See State Queries for details.
Check if any animations are currently running.
Returns Nothing if there are no animations.
Check if a specific animation group is currently running.
Returns Nothing if there are no animations for the group.
Check if all animations are complete.
Returns Nothing if there are no animations.
Check if a specific animation group has completed.
Returns Nothing if there are no animations for the group.
Check if a specific animation group was cancelled.
Returns Nothing if there are no animations for the group.
Get the end value of a custom property animation.
The second argument is the CSS property name.
Returns Nothing if the element has no animation for the given custom property.
Get the custom property range (start and end) of an element being animated.
The second argument is the CSS property name.
Returns Nothing if the element has no animation for the given custom property.
Get the start value of a custom property animation.
The second argument is the CSS property name.
Returns Nothing if the element has no animation for the given custom property.
Returns Just 0 if no explicit start value was set, which is the default when no start value is set.
Get the end value of a custom color property animation.
The second argument is the CSS property name.
Returns Nothing if the element has no animation for the given custom color property.
Get the custom color property range (start and end) of an element being animated.
The second argument is the CSS property name.
Returns Nothing if the element has no animation for the given custom color property.
Get the start value of a custom color property animation.
The second argument is the CSS property name.
Returns Nothing if the element has no animation for the given custom color property.
Returns transparent white (rgba 255 255 255 0) if no explicit start value was set, which is the default when no start value is set.
Get the start opacity of an element being animated.
Returns Nothing if the element has no opacity animation.
Returns Just 1.0 (fully opaque) if no explicit start value was set, which is the default when no start value is set.
Get the end opacity of an element being animated.
Returns Nothing if the element has no opacity animation.
Get the opacity range (start and end) of an element being animated.
Returns Nothing if the element has no opacity animation.
Get the start perspective origin of an element being animated.
Returns Nothing if the element has no perspective origin animation.
Returns Just { x = 50, y = 50 } if no explicit start value was set, which is the default when no start value is set.
Get the end perspective origin of an element being animated.
Returns Nothing if the element has no perspective origin animation.
Get the perspective origin range (start and end) of an element being animated.
Returns Nothing if the element has no perspective origin animation.
Get the start rotation of an element being animated.
Returns Nothing if the element has no rotate animation.
Returns Just { x = 0, y = 0, z = 0 } if no explicit start value was set, which is the default when no start value is set.
Get the end rotation of an element being animated.
Returns Nothing if the element has no rotate animation.
Get the rotate range (start and end) of an element being animated.
Returns Nothing if the element has no rotate animation.
Get the start scale of an element being animated.
Returns Nothing if the element has no scale animation.
Returns Just { x = 1, y = 1, z = 1 } if no explicit start value was set, which is the default when no start value is set.
Get the end scale of an element being animated.
Returns Nothing if the element has no scale animation.
Get the scale range (start and end) of an element being animated.
Returns Nothing if the element has no scale animation.
Get the start size of an element being animated.
Returns Nothing if the element has no size animation.
Returns Just { width = 0, height = 0 } if no explicit start value was set, which is the default when no start value is set.
Get the end size of an element being animated.
Returns Nothing if the element has no size animation.
Get the size range (start and end) of an element being animated.
Returns Nothing if the element has no size animation.
Get the end skew of an element being animated.
Returns Nothing if the element has no skew animation.
Get the skew range (start and end) of an element being animated.
Returns Nothing if the element has no skew animation.
Get the start skew of an element being animated.
Returns Nothing if the element has no skew animation.
Returns Just { x = 0, y = 0 } if no explicit start value was set, which is the default when no start value is set.
Get the start translate of an element being animated.
Returns Nothing if the element has no translate animation.
Returns Just { x = 0, y = 0, z = 0 } if no explicit start value was set, which is the default when no start value is set.
Get the end translate of an element being animated.
Returns Nothing if the element has no translate animation.
Get the translate range (start and end) of an element being animated.
Returns Nothing if the element has no translate animation.
Holds the Keyframe engine state.
Keep this in your model.