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 evaluated by the renderer, so supported animations bypass
Python reconciliation on each frame. Unattached values, Python listeners,
callable easing functions, and backends that decline native animation use
the Python ticker.
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.Animated.sequence/Animated.parallel/Animated.stagger/Animated.delay/Animated.loop: composition; also awaitable.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 (the native driver):
Mounted bindings install a serialized graph of connected values, arithmetic,
interpolation, and view properties. When an animation starts, PythonNative
offers its timing, spring, or decay specification to the renderer through
ViewHandler.start_animation.
- Accepted: the renderer evaluates the graph and applies its bindings
without Python work on every frame. Completion callbacks settle the
AnimatedValueand resolve awaiting tasks. - Declined (unattached values, callable easings,
values feeding Python-side listeners, or an unsupported backend): a single
background thread ticks the animation at ~60 Hz from Python, pushing
each frame through
set_animated_property. Semantics are identical; only the frame source differs.
On mobile, scroll and gesture bindings feed graph values before input is queued to Python. Derived expressions can run in the renderer alongside their source drivers. Backends without graph support use Python for derived bindings.
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 |
|---|---|
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. |
Functions:
| Name | Description |
|---|---|
native_animation_completed |
Report a natively-driven animation as settled. |
use_animated_value |
Return an |
Attributes:
| Name | Type | Description |
|---|---|---|
Animated |
|
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. 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 (native or Python). |
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))
native_animation_completed
¶
Report a natively-driven animation as settled.
Called by platform handlers from their completion callbacks (iOS
UIView completion blocks, Android withEndAction /
DynamicAnimation.OnAnimationEndListener). Safe to call from any
thread; unknown ids are ignored (e.g. an animation cancelled
moments before its completion fired).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
anim_id
|
int
|
The id passed to |
required |
finished
|
bool
|
|
True
|
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, and gesture-driven animations.
use_refexplains therefsemantics that backAnimated.View.