View Source LiveMotion (LiveMotion v0.3.1)
LiveMotion provides high performance animations declared on the server and run on the client.
The main goal of LiveMotion is to make animations as easy as possible by using a simple declarative model to define animations. Traditionally animations have to be defined upfront using CSS transitions and keyframes. This approach requires a lot of context switching and is hard to make dependant on server state.
With LiveMotion animations can be declared by using the LiveMotion.motion
component.
Its's props allow dynamic keyframe animations which can be dependant on the server state.
These animations are only declared on the server, but are fully performed on the client.
It's just a tiny configuration, which is added via a data-motion
attribute. This attribute
is picked up by a LiveView JS Hook which performs the animation using the
Motion One animation library. Animations happen using the WebAnimations
API.
example
Example
To declare a simple animation which starts immediately after mount, define the following component. This will rotate the popcorn 🍿 for 360°.
def render(assigns) do
~H"""
<.motion id="popcorn" animate={[rotate: 360]}>
<span>🍿</span>
</.motion>
"""
end
To see all supported options, take a look at the documentation of LiveMotion.motion
.
manually-triggering-animations
Manually triggering animations
Animations can also be triggered by user events like button clicks. These animations do not require a round trip to the server and can be defined upfront. Following the previous example:
def render(assigns) do
~H"""
<div>
<.motion
id="popcorn"
initial={[opacity: 0]}
animate={[opacity: 1]}
exit={[opacity: 0]}
>
<span>🍿</span>
</.motion>
<button phx-click={LiveMotion.JS.toggle(to: "#popcorn")}>
Toggle me
</button>
</div>
"""
end
This will toggle the opacity from the #popcorn
element. See LiveMotion.JS
for more
information on how to manually trigger animations.
Tip
You can call
import LiveMotion
at the beginning for your file so that you don't have to call the component using the full module name (LiveMotion.motion
).
limitations
Limitations
LiveMotion is still in the early days, so breaking changes are expected. Additionally, there are still a few limitations, which will be added in future releases.
- Currently standard easing functions (e.g.
ease-in-out
, bezier curves), spring, and glide animations are supported. Due to the nature of spring and glide animations, they do not have a fixed duration (theoretically they can run indefinetely). When using unmount transition, this adds a challenge, as we do not know how long Phoenix LiveView should defer the actual removal of the DOM node. For now, we fall back to the maximum supported duration of ten seconds. - Stagger animations will be added in a later release.
- Layout animations are not yet supported. Think of animations which automatically move items in the correct place after an element is removed which affects the layout.
Link to this section Summary
Functions
This is the main component for declaring animations.
Link to this section Functions
This is the main component for declaring animations.
Tip
As LiveMotion uses Motion One to perform the animations, keyframes and transition options will be passed directly to Motion One. For a more complete reference, have a look at their documentation of the animate function.
keyframe
Keyframe
A keyframe is represented by a keyword list defining CSS properties. These can one or multiple values. For example:
[x: 200]
This will animate the component to 200px on the x axis. As previously mentioned, multiple
values are supported, too. The following will animate the element on the x
axis to
each of the values one after another, spreading the steps equally on the duration.
[x: [0, 200, 50, 100]]
You might have noticed that x
itself is not a valid CSS property. In fact, this is a shorthand
to make common animation operations easier. x
eventually translates to the CSS property
transform: translateX(200px)
.
The following shorthands are supported:
x
y
y
scale
scaleX
scaleY
scaleZ
rotate
rotateX
rotateY
rotateZ
skewX
skewY
You need to pass the options as a Keyword list and in snake case.
transition-options
Transition options
The transition options are passed directly to Motion One. Options are provided as a
keyword list. You can find a full reference of all supported options in the documentation
of the animate
function of Motion One.
spring-and-glide-animations
Spring and glide animations
Create spring
or glide
animations by providing a keyword list with the according
options for each into the easing
option of the transition
.
[easing: [spring: [stiffness: 100, damping: 50]]]
[easing: [glide: [velocity: 1000]]]
You need to pass the options as a Keyword list and in snake case.
limitations
Limitations
As these animations are based on physics, there is no duration provided. However,
when using exit
animations (e.g. something is removed from the DOM by LiveView),
we are forced to provide LiveView with a fixed duration before the element is removed
from the DOM.
This currently defaults to the maximum of the WebAnimations API duration (10 seconds). If the animation completed before, the element will be hidden until it is removed from the DOM by LiveView.
duration
hintIf you provide a
duration
in thetransition
prop, this will be used a hint for the LiveView transition, so that the actual element is removed from the DOM before reaching the ten seconds timeout.It is recommended to always provide the duration hint when you plan to hide the element via a server event.
Please note that the
duration
itself does not have any effect on the actual length ofspring
orglide
animations.
attributes
Attributes
id
(:string
) (required) - A unique dom element id for the component.initial
(:list
) - Defines the initial style for the component. Useful when using mount transitions and you want the component to have an initial state to animate to. Accepts akeyframe
keyword list.If set to
false
it will directly apply the styles defined in theanimate
prop and skip the animation.Defaults to
nil
.animate
(:list
) - Defines the target animation style. Accepts akeyframe
keyword list. Defaults tonil
.transition
(:list
) - Additional options to specify the behaviour of the animation. These are things like the easing function, duration and delay.Defaults to
nil
.exit
(:list
) - The target animation to animate to when the component is unmounted. Accepts the same options asanimate
does.Defaults to
nil
.hover
(:list
) - Animate the element on mouse hover. Accepts akeyframe
keyword list. Defaults tonil
.press
(:list
) - Animate the element when pressed. Accepts akeyframe
keyword list. Defaults tonil
.in_view
(:list
) - Animate the element when it appears in the viewport. Accepts akeyframe
keyword list. Defaults tonil
.in_view_options
(:list
) - Options forin_view
attr. Pass as keyword list. For a list of available options, see inView Options on motion.dev. Defaults tonil
.defer
(:boolean
) - If set, will defer the animation until it's somehow manually triggered. Use in combination withLiveMotion.JS.show/1
.Defaults to
false
.on_motion_start
(:any
) - Lifecycle event when the animation starts. If given a string, then the event will be sent to the LiveView. You can also call aLiveMotion.JS
orPhoenix.LiveView.JS
function.Defaults to
nil
.on_motion_complete
(:any
) - Lifecycle event when the animation has completed. If given a string, then the event will be sent to the LiveView. You can also call aLiveMotion.JS
orPhoenix.LiveView.JS
function.Defaults to
nil
.as
(:string
) - The tag element to render. Defaults todiv
. Defaults to"div"
.rest
(:global
) - Additional HTML attributes to add to the tag, ensuring proper escaping.
slots
Slots
inner_block