mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
* WiP: Move the devtools and related code to `textual-dev` (#2834) * Remove the textual script from the project file This is moving into the textual-dev package. * Remove the textual CLI code from Textual This has all gone to live in textual-dev. * Remove the devtools testing from Textual's unit tests They've moved over to textual-dev instead. * Remove the devtools server from Textual itself The start of the process to remove as much of the core devtools as possible from Textual. * Switch the console docs example screenshot over to textual_dev * Remove rednerables.py from Textual * Remove the last parts of devtools from Textual This is the last step. It remains to be seen if this is sustainable, but for testing purposes this is the extreme case we're aiming for. I *think* this will work though. Hereon we'll be needing to do an editable install of textual-dev into textual, and more generally and once this is "live" we'll be needing to make sure that textual[dev] is installed when doing development work on textual apps. The thing that remains to be seen however is how this all works with *developing* Textual itself. Will I always need to do an editable install? Still got to figure that one out. * Start to whittle down the pyproject file The next step is to try and work out what can come out of the pyproject file. * Remove aiohttp from Textual * Remove some more development dependencies we don't need any more * Relock * Remove the pointer to the previews directory * Reintroduce the border preview snapshot test * Reintroduce the color preview snapshot test * Reinstate the key press for the border preview snapshot test * Reintroduce the easing preview snapshot test * Reintroduce the keys tool snapshot test * Add pytest-asyncio as a development dependency * Relock * Pin the textual-dev version to 0.1.0 or later Mostly to try and get the tests kicked off properly. * Relock dependencies * Further `textual-dev` changes (#2850) * Remove the textual script from the project file This is moving into the textual-dev package. * Remove the textual CLI code from Textual This has all gone to live in textual-dev. * Remove the devtools testing from Textual's unit tests They've moved over to textual-dev instead. * Remove the devtools server from Textual itself The start of the process to remove as much of the core devtools as possible from Textual. * Switch the console docs example screenshot over to textual_dev * Remove rednerables.py from Textual * Remove the last parts of devtools from Textual This is the last step. It remains to be seen if this is sustainable, but for testing purposes this is the extreme case we're aiming for. I *think* this will work though. Hereon we'll be needing to do an editable install of textual-dev into textual, and more generally and once this is "live" we'll be needing to make sure that textual[dev] is installed when doing development work on textual apps. The thing that remains to be seen however is how this all works with *developing* Textual itself. Will I always need to do an editable install? Still got to figure that one out. * Start to whittle down the pyproject file The next step is to try and work out what can come out of the pyproject file. * Remove aiohttp from Textual * Remove some more development dependencies we don't need any more * Relock * Remove the pointer to the previews directory * Reintroduce the border preview snapshot test * Reintroduce the color preview snapshot test * Reinstate the key press for the border preview snapshot test * Reintroduce the easing preview snapshot test * Reintroduce the keys tool snapshot test * Add pytest-asyncio as a development dependency * Relock * Pin the textual-dev version to 0.1.0 or later Mostly to try and get the tests kicked off properly. * Relock dependencies * Whitespace cleaning * Swap mentions of textual[dev] to textual-dev * Remove the dev extra * Tweak README.md in response to PR review * Tweak animation.md in response to PR review * Tweak getting_started.md in response to PR review * bump version * lock * drop dev * more * version bump --------- Co-authored-by: Dave Pearson <davep@davep.org>
88 lines
3.4 KiB
Markdown
88 lines
3.4 KiB
Markdown
# Animation
|
|
|
|
Ths chapter discusses how to use Textual's animation system to create visual effects such as movement, blending, and fading.
|
|
|
|
|
|
## Animating styles
|
|
|
|
Textual's animator can change an attribute from one value to another in fixed increments over a period of time. You can apply animations to [styles](styles.md) such as `offset` to move widgets around the screen, and `opacity` to create fading effects.
|
|
|
|
Apps and widgets both have an [animate][textual.app.App.animate] method which will animate properties on those objects. Additionally, `styles` objects have an identical `animate` method which will animate styles.
|
|
|
|
Let's look at an example of how we can animate the opacity of a widget to make it fade out.
|
|
The following example app contains a single `Static` widget which is immediately animated to an opacity of `0.0` (making it invisible) over a duration of two seconds.
|
|
|
|
```python hl_lines="14"
|
|
--8<-- "docs/examples/guide/animator/animation01.py"
|
|
```
|
|
|
|
The animator updates the value of the `opacity` attribute on the `styles` object in small increments over two seconds. Here's what the output will look like after each half a second.
|
|
|
|
|
|
=== "After 0s"
|
|
|
|
```{.textual path="docs/examples/guide/animator/animation01_static.py"}
|
|
```
|
|
|
|
=== "After 0.5s"
|
|
|
|
```{.textual path="docs/examples/guide/animator/animation01.py" press="wait:500"}
|
|
```
|
|
|
|
|
|
=== "After 1s"
|
|
|
|
```{.textual path="docs/examples/guide/animator/animation01.py" press="wait:1000"}
|
|
```
|
|
|
|
=== "After 1.5s"
|
|
|
|
```{.textual path="docs/examples/guide/animator/animation01.py" press="wait:1500"}
|
|
```
|
|
|
|
=== "After 2s"
|
|
|
|
```{.textual path="docs/examples/guide/animator/animation01.py" press="wait:2000"}
|
|
```
|
|
|
|
## Duration and Speed
|
|
|
|
When requesting an animation you can specify a *duration* or *speed*.
|
|
The duration is how long the animation should take in seconds. The speed is how many units a value should change in one second.
|
|
For instance, if you animate a value at 0 to 10 with a speed of 2, it will complete in 5 seconds.
|
|
|
|
## Easing functions
|
|
|
|
The easing function determines the journey a value takes on its way to the target value.
|
|
It could move at a constant pace, or it might start off slow then accelerate towards its final value.
|
|
Textual supports a number of [easing functions](https://easings.net/).
|
|
|
|
<div class="excalidraw">
|
|
--8<-- "docs/images/animation/animation.excalidraw.svg"
|
|
</div>
|
|
|
|
|
|
Run the following from the command prompt to preview them.
|
|
|
|
```bash
|
|
textual easing
|
|
```
|
|
|
|
You can specify which easing method to use via the `easing` parameter on the `animate` method. The default easing method is `"in_out_cubic"` which accelerates and then decelerates to produce a pleasing organic motion.
|
|
|
|
!!! note
|
|
|
|
The `textual easing` preview requires the `textual-dev` package to be installed (using `pip install textual-dev`).
|
|
|
|
|
|
## Completion callbacks
|
|
|
|
You can pass a callable to the animator via the `on_complete` parameter. Textual will run the callable when the animation has completed.
|
|
|
|
## Delaying animations
|
|
|
|
You can delay the start of an animation with the `delay` parameter of the `animate` method.
|
|
This parameter accepts a `float` value representing the number of seconds to delay the animation by.
|
|
For example, `self.box.styles.animate("opacity", value=0.0, duration=2.0, delay=5.0)` delays the start of the animation by five seconds,
|
|
meaning the animation will start after 5 seconds and complete 2 seconds after that.
|