Animated¶
PythonNative's Animated API mirrors React Native's. Build performant
animations declaratively by binding AnimatedValue
instances to the style of an Animated.View, Animated.Text, or
Animated.Image. The reconciler holds a ref to the underlying
native view. Connected values, derived expressions, and style bindings
form a graph the renderer core evaluates on the UI thread, so animations
bypass Python reconciliation on each frame. Unattached values and values
with Python listeners have the core report each frame's value to Python,
and a callable easing function is sampled into a curve the core
interpolates.
A few types frame the surface:
Easingis a namespace of serializableEasingSpeccurves (Easing.ease_out,Easing.bezier(...)) accepted byAnimated.timing(easing=...); a misspelled easing name raisesValueErrorinstead of falling back.await handleandhandle.start(callback)deliver anAnimationResultwhosefinishedflag tells a stopped or superseded animation from one that ran to completion.ANIMATABLE_PROPSlists the style keys an animated node may drive; binding a layout key such aswidthraisesValueErrorat element construction.Animated.decayuses React Native's model on every platform: velocity in points per millisecond decays asv0 * deceleration ** t, withdecelerationdefaulting to0.998.
Animated values, derived animated nodes, and native-driven animation.
Modeled on React Native's Animated API with an async-aware
completion contract. The core primitives are:
AnimatedValue: a numeric cell attached to native view properties; animations drive it over time.- Derived nodes: every animated node supports
interpolate(range mapping with numeric, color, and angle outputs) and Python arithmetic (opacity * 0.5,x + y,-value), producing read-onlyAnimatedNodeinstances that update whenever their inputs change. Animated.timing/Animated.spring/Animated.decay: animation factories. The objects they return implement__await__, so you can writeawait Animated.timing(v, to=1.0)to suspend until the animation finishes. Awaiting yields anAnimationResultwhosefinishedflag isFalsewhen the animation was stopped or interrupted;handle.start(callback)passes the same value.Animated.sequence/Animated.parallel/Animated.stagger/Animated.delay/Animated.loop: composition; also awaitable. A composite isfinishedonly if every child finished.Easing: serializable easing descriptors forAnimated.timing(Easing.ease_in_out,Easing.bezier(0.2, 0.8, 0.2, 1.0), ...). Every renderer evaluates the same curve definitions; a plain Python callable is still accepted and crosses the bridge as a sampled curve.Animated.event: build an event-prop callback that copies event fields into animated values (on_scroll=pn.Animated.event(y=v)).Animated.diff_clamp: accumulate an input's deltas into a clamped range (the collapsing-header primitive).Animated.View/Animated.Text/Animated.Image: components whosestylemay contain animated nodes, including insidetransformentries.
Driver architecture:
Every animation runs in the renderer core's animator on the platform's UI
thread (RFC 0007), at the display's refresh rate. Mounted bindings install
a serialized graph of connected values, arithmetic, interpolation, and view
properties; starting an animation hands its timing, spring, or decay
specification to the core through the backend's start_animation hook
(see BridgeBackend).
The core evaluates the graph and applies its bindings without Python work
on every frame. Completion settles the
AnimatedValue and resolves
awaiting tasks.
A value with Python listeners, or one no view is bound to, asks the core to report its value every frame, and Python updates the value and runs the listeners. A Python easing callable is sampled into a curve the core interpolates. Headless code without a mounted screen animates on the host build of the same core, so tests see the shipping math.
Scroll and gesture bindings feed graph values on the UI thread before input is queued to Python.
Example
import pythonnative as pn
@pn.component
def FadeIn():
opacity = pn.use_animated_value(0.0)
async def fade_in():
await pn.Animated.timing(opacity, to=1.0, duration=400)
await pn.Animated.timing(opacity, to=0.5, duration=200)
pn.use_effect(fade_in, [])
return pn.Animated.View(
pn.Text("Hello!"),
style={"opacity": opacity, "padding": 20},
)
Classes:
| Name | Description |
|---|---|
EasingSpec |
A serializable easing curve for |
AnimatedNode |
Base class for every animated node (settable leaves and derived nodes). |
AnimatedValue |
A numeric cell that can be attached to native view properties. |
AnimatedInterpolation |
Read-only node mapping a parent node through an input/output range. |
AnimatedEvent |
Callable event handler copying event fields into animated values. |
AnimationResult |
Outcome of an animation, delivered by |
Functions:
| Name | Description |
|---|---|
native_animation_message |
Route an |
use_animated_value |
Return an |
Attributes:
| Name | Type | Description |
|---|---|---|
DECAY_REST_VELOCITY |
|
|
DEFAULT_DECAY_DECELERATION |
|
|
EASING_NAMES |
Tuple[str, ...]
|
The easing names |
Easing |
|
|
ANIMATABLE_PROPS |
FrozenSet[str]
|
Style keys an |
Animated |
|
EASING_NAMES
module-attribute
¶
The easing names Animated.timing accepts as strings.
EasingLike
module-attribute
¶
What Animated.timing(easing=...) accepts.
CompletionCallback
module-attribute
¶
CompletionCallback = Callable[[AnimationResult], Any]
Signature of the optional callback accepted by start().
ANIMATABLE_PROPS
module-attribute
¶
ANIMATABLE_PROPS: FrozenSet[str] = (
frozenset({"opacity", "background_color", "color"})
| _ANIMATED_TRANSFORM_KEYS
)
Style keys an AnimatedNode may be bound to.
These are the properties every renderer can drive on its UI thread
without a layout pass. Layout keys (width, margin, padding,
top, ...) and the remaining transform channels (skew_x,
perspective, ...) are rejected at element construction time so an
animation never silently degrades to a re-render per frame.
EasingSpec
dataclass
¶
A serializable easing curve for Animated.timing.
Build instances through the Easing
namespace (Easing.ease_in_out, Easing.bezier(...)) rather
than directly. The descriptor crosses the bridge as data, so the
renderer core can run the curve on the UI thread, and it evaluates
identically in Python for tests.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
One of the named curves ( |
points |
Optional[Tuple[float, float, float, float]]
|
The |
Methods:
| Name | Description |
|---|---|
evaluate |
Return the eased value for |
to_wire |
Return the bridge representation: the name, or |
points
class-attribute
instance-attribute
¶
AnimatedNode
¶
Base class for every animated node (settable leaves and derived nodes).
An animated node holds a current output value and a set of
(tag, prop) attachments binding it to native view
properties. Whenever the node's output changes (a leaf was set or
animated, or an input of a derived node changed), the new value is
pushed to every attachment through the registry's
set_animated_property and to every Python-side listener, then
propagated to derived nodes built from this one.
Derived nodes are constructed with
interpolate,
with Python arithmetic operators (+, -, *, /,
%, unary -), or with Animated.diff_clamp. They are
read-only: only AnimatedValue
leaves can be set or animated directly.
Methods:
| Name | Description |
|---|---|
attach |
Bind this node to |
attachments |
Snapshot of the current |
add_listener |
Register |
has_listeners |
Whether any Python-side listeners are registered. |
interpolate |
Map this node's value through an input/output range. |
Attributes:
| Name | Type | Description |
|---|---|---|
value |
Any
|
Return the node's current output value. |
attach
¶
Bind this node to prop of the native view under tag.
The current value is pushed immediately so the view reflects it
even if no animation is running. backend is the backend that
owns the view (the process's backend by default). Returns a detach
callable.
add_listener
¶
Register callback for Python-driven changes to this node.
Returns an unsubscribe callable. prop is metadata only; it
lets the subscriber differentiate this binding from others on
the same node.
interpolate
¶
interpolate(
input_range: Sequence[float],
output_range: Sequence[Any],
extrapolate: str = "extend",
extrapolate_left: Optional[str] = None,
extrapolate_right: Optional[str] = None,
) -> "AnimatedInterpolation"
Map this node's value through an input/output range.
Mirrors React Native's interpolate. output_range may
contain numbers, colors ("#RRGGBB" / "#AARRGGBB"), or
angle strings ("45deg" / "0.5rad", emitted as numeric
degrees for the rotate transform).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_range
|
Sequence[float]
|
Monotonically non-decreasing breakpoints for this node's value. At least two entries. |
required |
output_range
|
Sequence[Any]
|
Output breakpoints, same length as
|
required |
extrapolate
|
str
|
Behavior outside the input range:
|
'extend'
|
extrapolate_left
|
Optional[str]
|
Override |
None
|
extrapolate_right
|
Optional[str]
|
Override |
None
|
Returns:
| Type | Description |
|---|---|
'AnimatedInterpolation'
|
A derived, read-only animated node. |
AnimatedValue
¶
AnimatedValue(initial: float = 0.0)
Bases: AnimatedNode
A numeric cell that can be attached to native view properties.
Animated components (Animated.View et al.) attach the value
to (tag, prop) bindings after mount. Setting the value pushes
the new number to every attached native view through the registry's
set_animated_property (and through every derived node built
from this value), and when an animation can be driven natively, the
platform animates those same bindings directly.
Python-side listeners registered via
add_listener
observe every Python-driven change. Natively-driven animations
intentionally skip per-frame Python callbacks (that's the point);
listeners see the final settled value.
Methods:
| Name | Description |
|---|---|
set_value |
Set the value immediately, pushing to native views and listeners. |
stop_animation |
Cancel any in-flight animation on this value. |
Attributes:
| Name | Type | Description |
|---|---|---|
value |
float
|
Return the current numeric value (without subscribing). |
AnimatedInterpolation
¶
AnimatedInterpolation(
parent: AnimatedNode,
input_range: Sequence[float],
output_range: Sequence[Any],
extrapolate: str = "extend",
extrapolate_left: Optional[str] = None,
extrapolate_right: Optional[str] = None,
)
Bases: AnimatedNode
Read-only node mapping a parent node through an input/output range.
Built via
AnimatedNode.interpolate;
see that method for the semantics of the arguments.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
Any
|
Return the interpolated output for the parent's current value. |
AnimatedEvent
¶
AnimatedEvent(
listener: Optional[Callable[..., None]] = None,
**bindings: AnimatedValue
)
Callable event handler copying event fields into animated values.
Built via pn.Animated.event(...). Each keyword argument names a
field on the incoming event payload (a dict key for scroll payloads
such as {"x": ..., "y": ...}, or an attribute for
GestureEvent instances) and
maps it onto an AnimatedValue.
Because the result is an ordinary callable, it can be passed to any event prop:
scroll_y = pn.use_animated_value(0.0)
pn.ScrollView(..., on_scroll=pn.Animated.event(y=scroll_y))
tx = pn.use_animated_value(0.0)
gestures.Pan(on_change=pn.Animated.event(translation_x=tx))
AnimationResult
dataclass
¶
AnimationResult(finished: bool)
Outcome of an animation, delivered by await handle and handle.start(callback).
Mirrors the {finished} object React Native passes to animation
callbacks.
Attributes:
| Name | Type | Description |
|---|---|---|
finished |
bool
|
|
release_view_backend
¶
Forget that backend owns tags (its views were destroyed or its surface reset).
native_animation_message
¶
Route an animation message from the core: a frame report or a completion.
Completions carry {"id", "finished", "value"} (finished is
False when the driver was cancelled or superseded); reports carry
{"id", "value"}. Unknown ids are ignored (an animation cancelled
moments before its completion arrived).
use_animated_value
¶
use_animated_value(initial: float = 0.0) -> AnimatedValue
Return an AnimatedValue that is stable across renders.
Convenience wrapper for the common pattern
pn.use_memo(lambda: AnimatedValue(initial), []). The same
instance is returned on every render of the same component, so
you can drive it from event handlers without recreating it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial
|
float
|
The starting numeric value. |
0.0
|
Returns:
| Type | Description |
|---|---|
AnimatedValue
|
A mount-stable |
See also¶
- The Animations guide walks through fade-ins, springs, sequences, easing, decay, and gesture-driven animations.
use_refexplains therefsemantics that backAnimated.View.