What every backend writes of an element's motion (spec/02 §2.1, spec/14 §3.10, D-176).
An element's style may carry :transition, the list of {property, duration, easing} a
style's transition part resolves to — property :fill, :stroke or :opacity,
duration in milliseconds, easing a Visualize.Ease name — and the element the
attribute "data-vis-id", the identity the motion is keyed by. SVG writes the motion as
CSS (css_easing/1, css_properties/1, oklch/1), a canvas as a motion span the hooks
run (span/3, json/1); both ease along the same samples of one curve (samples/1).
Examples
iex> Visualize.IR.Motion.css_easing(:linear)
"linear"
iex> Visualize.IR.Motion.samples(:quad_in) |> Enum.take(3)
[0, 0.0025, 0.01]
iex> Visualize.IR.Motion.css_properties(:stroke)
["stroke", "stroke-width", "stroke-opacity"]
iex> Visualize.IR.Motion.oklch("#ffffff")
"oklch(1 0 0)"
iex> Visualize.IR.Motion.oklch("var(--vis-red, #c23238)")
"oklch(from var(--vis-red, #c23238) l c h / alpha)"
Summary
Types
A property a transition moves.
A resolved transition: what moves, for how long, along which curve.
Functions
The CSS animation value of a resolved animation: the keyframes — vis-<name> for a
built-in, a host's name as it is — the duration, the easing, the delay and the
iterations.
The easing as CSS: linear, or linear() of samples/1.
A built-in's keyframes as CSS: @keyframes vis-<name> { … }, each offset a percentage,
opacity as itself, x and y as translate, rotate and scale as the individual
transform properties, which compose with an element's transform.
The CSS properties a property moves.
The CSS transition value of a resolved transition: each CSS property a property moves,
its duration and its easing, joined by commas.
The text of data-vis-exit for element leaving with exit (spec/14 §3.12): the name,
the duration, the samples, the element's box as drawn and a built-in's keyframes, as
JSON.
A span's arguments as JSON text: lists, strings, numbers and nil, numbers formatted as
path data is, every string escaped — the text the :json command and the binary record
both carry (spec/09 §3.3.5, §4.3.15).
A built-in animation's keyframes (spec/14 §3.11): offsets from 0 to 1, each with the
values there of :opacity, :x, :y (a translation in user units), :rotate (degrees,
about the center of the element's box as drawn) and :scale.
A color as oklch(), so CSS interpolates it in OKLab (spec/14 §3.10): a literal
Visualize.Color.parse/1 reads as its coordinates, an oklch(…) as it is, anything
else — a theme's var(--vis-…, literal), a transform's color-mix(…) — as the relative
color oklch(from <value> l c h / alpha). :none, :current_color, a paint and any
value that is not a string pass through.
The easing's 21 values at t = 0, 0.05, …, 1, each rounded to 4 decimals; [0, 1] for
:linear, which two points draw exactly.
The arguments of a motion span (spec/09 §3.3.5): [id, box, transitions] for an element
that names its identity, drawn with style, its effective style — its own over what its
groups give it. An element whose style moves nothing has a span too, with no
transitions: a hook then knows what it shows when a later stream moves it.
The resolved transition as the canvas encoders write it: [[property, duration, samples], …].
Types
Functions
The CSS animation value of a resolved animation: the keyframes — vis-<name> for a
built-in, a host's name as it is — the duration, the easing, the delay and the
iterations.
iex> Visualize.IR.Motion.css_animation(%{name: :pulse, duration: 1200, easing: :linear, iterations: :infinite, delay: 0})
"vis-pulse 1200ms linear 0ms infinite"
The easing as CSS: linear, or linear() of samples/1.
A built-in's keyframes as CSS: @keyframes vis-<name> { … }, each offset a percentage,
opacity as itself, x and y as translate, rotate and scale as the individual
transform properties, which compose with an element's transform.
iex> Visualize.IR.Motion.css_keyframes(:spin)
"@keyframes vis-spin { 0% { rotate: 0deg; } 100% { rotate: 360deg; } }"
The CSS properties a property moves.
@spec css_transition(transition()) :: String.t()
The CSS transition value of a resolved transition: each CSS property a property moves,
its duration and its easing, joined by commas.
@spec exit_attribute(map(), Visualize.IR.Element.t()) :: String.t()
The text of data-vis-exit for element leaving with exit (spec/14 §3.12): the name,
the duration, the samples, the element's box as drawn and a built-in's keyframes, as
JSON.
iex> exit = %{name: :fade, duration: 300, easing: :linear}
iex> Visualize.IR.Motion.exit_attribute(exit, Visualize.IR.Element.rect(0, 0, 4, 2))
~s(["fade",300,[0,1],[0,0,4,2],[[0,1,null,null,null,null],[1,0,null,null,null,null]]])
A span's arguments as JSON text: lists, strings, numbers and nil, numbers formatted as
path data is, every string escaped — the text the :json command and the binary record
both carry (spec/09 §3.3.5, §4.3.15).
A built-in animation's keyframes (spec/14 §3.11): offsets from 0 to 1, each with the
values there of :opacity, :x, :y (a translation in user units), :rotate (degrees,
about the center of the element's box as drawn) and :scale.
iex> Visualize.IR.Motion.keyframes(:pulse)
[{0, %{opacity: 1}}, {0.5, %{opacity: 0.35}}, {1, %{opacity: 1}}]
A color as oklch(), so CSS interpolates it in OKLab (spec/14 §3.10): a literal
Visualize.Color.parse/1 reads as its coordinates, an oklch(…) as it is, anything
else — a theme's var(--vis-…, literal), a transform's color-mix(…) — as the relative
color oklch(from <value> l c h / alpha). :none, :current_color, a paint and any
value that is not a string pass through.
The easing's 21 values at t = 0, 0.05, …, 1, each rounded to 4 decimals; [0, 1] for
:linear, which two points draw exactly.
@spec span(String.t(), Visualize.IR.Element.t(), map()) :: list()
The arguments of a motion span (spec/09 §3.3.5): [id, box, transitions] for an element
that names its identity, drawn with style, its effective style — its own over what its
groups give it. An element whose style moves nothing has a span too, with no
transitions: a hook then knows what it shows when a later stream moves it.
@spec transitions(transition()) :: [list()]
The resolved transition as the canvas encoders write it: [[property, duration, samples], …].