11# Animations
22
33PythonNative ships an ` Animated ` API modelled on React Native's. It's
4- designed for the common case where a small set
5- of style properties (opacity, transform, color) need to interpolate
6- smoothly over time without re-rendering the component tree on every
7- frame.
4+ designed for the common case where a small set of style properties
5+ (opacity, transform, color) need to interpolate smoothly over time
6+ without re-rendering the component tree on every frame.
87
98## Mental model
109
@@ -14,8 +13,10 @@ frame.
14132 . Bind the value into the ` style ` of an ` Animated.View ` ,
1514 ` Animated.Text ` , or ` Animated.Image ` .
16153 . Drive the value with ` Animated.timing ` , ` Animated.spring ` , or
17- ` Animated.decay ` . Each driver returns a handle with ` .start() ` /
18- ` .stop() ` .
16+ ` Animated.decay ` . Each driver returns a handle with two faces:
17+ - ` handle.start() ` is fire-and-forget (returns ` self ` ).
18+ - ` await handle ` runs the animation and suspends until it
19+ completes. Cancelling the awaiting task stops the animation.
1920
2021The animated component captures a ` ref ` to the underlying native view
2122(via the same [ ` use_ref ` ] [ pythonnative.use_ref ] mechanism users have
@@ -34,10 +35,10 @@ import pythonnative as pn
3435def FadeInBox ():
3536 opacity = pn.use_animated_value(0.0 )
3637
37- def _fade_in ():
38- pn.Animated.timing(opacity, to = 1.0 , duration = 400 ).start( )
38+ async def _fade_in ():
39+ await pn.Animated.timing(opacity, to = 1.0 , duration = 400 )
3940
40- pn.use_effect (_fade_in, [])
41+ pn.use_async_effect (_fade_in, [])
4142
4243 return pn.Animated.View(
4344 pn.Text(" Hello!" ),
@@ -51,7 +52,17 @@ def FadeInBox():
5152```
5253
5354` opacity ` starts at ` 0.0 ` and the timing animation interpolates it to
54- ` 1.0 ` over 400 ms.
55+ ` 1.0 ` over 400 ms. Using ` use_async_effect ` means the in-flight
56+ animation is automatically cancelled if the component unmounts before
57+ the 400 ms is up.
58+
59+ If you don't need to react to completion, the synchronous form is fine
60+ too:
61+
62+ ``` python
63+ def _press ():
64+ pn.Animated.timing(opacity, to = 1.0 , duration = 400 ).start()
65+ ```
5566
5667## Spring animation on press
5768
@@ -80,17 +91,21 @@ animation property.
8091## Sequencing and parallel composition
8192
8293``` python
83- opacity = pn.use_animated_value(0.0 )
84- translate_y = pn.use_animated_value(20.0 )
85-
86- pn.Animated.parallel([
87- pn.Animated.timing(opacity, to = 1.0 , duration = 300 ),
88- pn.Animated.spring(translate_y, to = 0.0 ),
89- ]).start()
94+ async def _intro ():
95+ opacity = pn.use_animated_value(0.0 )
96+ translate_y = pn.use_animated_value(20.0 )
97+
98+ await pn.Animated.parallel([
99+ pn.Animated.timing(opacity, to = 1.0 , duration = 300 ),
100+ pn.Animated.spring(translate_y, to = 0.0 ),
101+ ])
102+ await pn.Animated.delay(80 )
103+ await pn.Animated.timing(opacity, to = 0.5 , duration = 200 )
90104```
91105
92- Use ` Animated.sequence ` for one-after-another execution and
93- ` Animated.delay(ms) ` to insert pauses inside a sequence.
106+ ` Animated.parallel ` returns when ** all** animations finish.
107+ ` Animated.sequence ` runs animations one-after-another. Both are also
108+ awaitable.
94109
95110## Easing
96111
@@ -101,7 +116,18 @@ Use `Animated.sequence` for one-after-another execution and
101116
102117` start() ` returns the handle you started with, and the handle exposes
103118` .stop() ` . A common pattern is to keep the handle in a ` use_ref ` so
104- you can cancel a long-running animation when the user interrupts.
119+ you can cancel a long-running animation when the user interrupts. If
120+ you're awaiting the animation instead, cancelling the awaiting task
121+ stops the animation:
122+
123+ ``` python
124+ async def _enter ():
125+ await pn.Animated.timing(opacity, to = 1.0 , duration = 2000 )
126+
127+ task = pn.run_async(_enter())
128+ # Sometime later:
129+ task.cancel() # animation snaps to wherever it was; opacity stops here.
130+ ```
105131
106132## When NOT to use ` Animated `
107133
0 commit comments