manim-stateflow 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- manim_stateflow-0.1.0a1/CHANGELOG.md +35 -0
- manim_stateflow-0.1.0a1/CONTRIBUTING.md +52 -0
- manim_stateflow-0.1.0a1/LICENSE +21 -0
- manim_stateflow-0.1.0a1/MANIFEST.in +16 -0
- manim_stateflow-0.1.0a1/PKG-INFO +369 -0
- manim_stateflow-0.1.0a1/README.md +335 -0
- manim_stateflow-0.1.0a1/docs/assets/README.md +5 -0
- manim_stateflow-0.1.0a1/docs/assets/gif_sources/readme_tiny_examples.py +47 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/call-vs-apply.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/core-pattern.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/custom-python-object-state.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/d-call-custom-builder.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/frame-simulation-pattern.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/jump-is-necessary.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/matrix-state.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/multiple-state-values-and-types.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/object-wiring.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/quickstart.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/reactive-surface-3d.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/smooth-interpolation.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/tiny-mixed-state.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/tiny-moving-dot.gif +0 -0
- manim_stateflow-0.1.0a1/docs/assets/gifs/tiny-sine-point.gif +0 -0
- manim_stateflow-0.1.0a1/docs/contributing.md +17 -0
- manim_stateflow-0.1.0a1/docs/guide.md +205 -0
- manim_stateflow-0.1.0a1/docs/index.md +28 -0
- manim_stateflow-0.1.0a1/docs/quickstart.md +79 -0
- manim_stateflow-0.1.0a1/docs/reference.md +184 -0
- manim_stateflow-0.1.0a1/docs/troubleshooting.md +105 -0
- manim_stateflow-0.1.0a1/examples/01_quickstart.py +68 -0
- manim_stateflow-0.1.0a1/examples/advanced/11_reactive_surface_3d.py +57 -0
- manim_stateflow-0.1.0a1/examples/beginner/01_core_pattern.py +56 -0
- manim_stateflow-0.1.0a1/examples/beginner/02_frame_simulation_pattern.py +69 -0
- manim_stateflow-0.1.0a1/examples/beginner/03_smooth_interpolation.py +41 -0
- manim_stateflow-0.1.0a1/examples/beginner/04_jump_is_necessary.py +66 -0
- manim_stateflow-0.1.0a1/examples/beginner/05_multiple_state_values_and_types.py +65 -0
- manim_stateflow-0.1.0a1/examples/intermediate/06_matrix_state.py +94 -0
- manim_stateflow-0.1.0a1/examples/intermediate/07_object_wiring.py +70 -0
- manim_stateflow-0.1.0a1/examples/intermediate/08_d_call_custom_builder.py +72 -0
- manim_stateflow-0.1.0a1/examples/intermediate/09_custom_python_object_state.py +56 -0
- manim_stateflow-0.1.0a1/examples/intermediate/10_call_vs_apply.py +66 -0
- manim_stateflow-0.1.0a1/pyproject.toml +49 -0
- manim_stateflow-0.1.0a1/setup.cfg +4 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/__init__.py +45 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/__init__.pyi +14 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/_colors.py +34 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/_compat.py +582 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/_graph.py +21 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/_mobject_state.py +27 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/_values.py +113 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/adapter.py +142 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/adapter.pyi +33 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/animations.py +504 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/core.py +350 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/core.pyi +84 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/d.py +211 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/d.pyi +10011 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/effects.py +259 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/inspect.py +88 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/inspect.pyi +7 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/py.typed +1 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/render.py +213 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/runtime.py +275 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/scene.py +160 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/scene.pyi +58 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/templates.py +64 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow/utils.py +45 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow.egg-info/PKG-INFO +369 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow.egg-info/SOURCES.txt +82 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow.egg-info/dependency_links.txt +1 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow.egg-info/requires.txt +13 -0
- manim_stateflow-0.1.0a1/src/manim_stateflow.egg-info/top_level.txt +1 -0
- manim_stateflow-0.1.0a1/tests/test_core.py +776 -0
- manim_stateflow-0.1.0a1/tests/test_custom_mobject_patterns.py +244 -0
- manim_stateflow-0.1.0a1/tests/test_docs.py +187 -0
- manim_stateflow-0.1.0a1/tests/test_edge_cases.py +148 -0
- manim_stateflow-0.1.0a1/tests/test_effects.py +310 -0
- manim_stateflow-0.1.0a1/tests/test_inspect.py +68 -0
- manim_stateflow-0.1.0a1/tests/test_package.py +146 -0
- manim_stateflow-0.1.0a1/tests/test_performance.py +91 -0
- manim_stateflow-0.1.0a1/tests/test_regressions.py +120 -0
- manim_stateflow-0.1.0a1/tests/test_render.py +389 -0
- manim_stateflow-0.1.0a1/tests/test_stress.py +295 -0
- manim_stateflow-0.1.0a1/tests/test_transform_integration.py +154 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Manim Stateflow will be documented here.
|
|
4
|
+
|
|
5
|
+
## 0.1.0a1 - Early Alpha
|
|
6
|
+
|
|
7
|
+
This is the first community-feedback release.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `ReactiveScene` and `ReactiveThreeDScene`.
|
|
12
|
+
- `self.state(...)` as the primary scene state API.
|
|
13
|
+
- `lift(...)` for derived reactive values.
|
|
14
|
+
- Automatic `d.<ManimMobject>(...)` constructors for Manim `Mobject` subclasses.
|
|
15
|
+
- Reactive helper constructors: `d.Graph(...)`, `d.Surface(...)`, and `d.Trace(...)`.
|
|
16
|
+
- Generic method effects with `mobject.d.<method>(...)`, such as `label.d.next_to(...)`.
|
|
17
|
+
- Custom dependency effects with `mobject.d.apply(...)`.
|
|
18
|
+
- Lifecycle-managed frame effects with `mobject.d.on_frame(...)`.
|
|
19
|
+
- Effect suspension with `mobject.d.pause()`, `mobject.d.resume(...)`, and `self.suspend_reactive(...)`.
|
|
20
|
+
- Dependency inspection with `runtime_snapshot(...)` and `d.DependencyGraph(...)`.
|
|
21
|
+
- Generated editor hover stubs for common `d.<ManimClass>` constructors.
|
|
22
|
+
- Commented tutorial scenes in `examples/`.
|
|
23
|
+
|
|
24
|
+
### Design Boundary
|
|
25
|
+
|
|
26
|
+
Manim Stateflow decides when Manim constructors, methods, and managed frame
|
|
27
|
+
effects should run. Manim still owns geometry, layout, interpolation, rendering,
|
|
28
|
+
and normal `self.play(...)` choreography.
|
|
29
|
+
|
|
30
|
+
### Known Alpha Gaps
|
|
31
|
+
|
|
32
|
+
- Effect priorities are not implemented.
|
|
33
|
+
- Advanced layout/bounds signals are not implemented.
|
|
34
|
+
- Documentation is Markdown-first; there is no full docs site yet.
|
|
35
|
+
- API stability is not guaranteed before feedback from real scenes.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Manim Stateflow is test-first.
|
|
4
|
+
|
|
5
|
+
Before adding a feature, write the smallest automated test that describes the behavior. If the feature affects visible behavior, also add a small review scene in `examples/` so the motion can be inspected.
|
|
6
|
+
|
|
7
|
+
## Development Setup
|
|
8
|
+
|
|
9
|
+
Create an environment, then install the package in editable mode:
|
|
10
|
+
|
|
11
|
+
```powershell
|
|
12
|
+
python -m pip install -e ".[test]"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If you want to render examples, install Manim too:
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
python -m pip install -e ".[test,manim]"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Test Commands
|
|
22
|
+
|
|
23
|
+
Run the fast test suite:
|
|
24
|
+
|
|
25
|
+
```powershell
|
|
26
|
+
pytest -q
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Render a review scene:
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
manim -ql examples/01_quickstart.py Quickstart
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Before opening a release PR, also run:
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
python -m build
|
|
39
|
+
python -m twine check dist/*
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Design Rules
|
|
43
|
+
|
|
44
|
+
- Manim Stateflow owns dependency tracking, dirty scheduling, and cleanup.
|
|
45
|
+
- Manim owns geometry, layout, interpolation, rendering, and user-authored updaters.
|
|
46
|
+
- The pure graph should not contain raw Manim `Mobject`s.
|
|
47
|
+
- Object relations should be method effects, such as `label.d.next_to(dot, UP)`.
|
|
48
|
+
- `.d.apply(...)` is dependency-driven; `.d.on_frame(...)` is frame-driven.
|
|
49
|
+
- A feature is incomplete until tests exist and pass.
|
|
50
|
+
- Visible behavior should have a review scene.
|
|
51
|
+
|
|
52
|
+
See `docs/guide.md` for the longer version of the core patterns.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rehan Khan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
include CHANGELOG.md
|
|
2
|
+
include CONTRIBUTING.md
|
|
3
|
+
include LICENSE
|
|
4
|
+
include README.md
|
|
5
|
+
include pyproject.toml
|
|
6
|
+
recursive-include docs *.md
|
|
7
|
+
recursive-include docs/assets/gifs *.gif
|
|
8
|
+
recursive-include docs/assets/gif_sources *.py
|
|
9
|
+
recursive-include examples *.py
|
|
10
|
+
recursive-include tests *.py
|
|
11
|
+
recursive-include src/manim_stateflow *.pyi py.typed
|
|
12
|
+
prune media
|
|
13
|
+
prune build
|
|
14
|
+
prune dist
|
|
15
|
+
global-exclude __pycache__/*
|
|
16
|
+
global-exclude *.py[cod]
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: manim-stateflow
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: State-driven animation helpers for Manim scenes
|
|
5
|
+
Author: Manim Stateflow contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rehanmm/manim-stateflow
|
|
8
|
+
Project-URL: Repository, https://github.com/rehanmm/manim-stateflow
|
|
9
|
+
Project-URL: Issues, https://github.com/rehanmm/manim-stateflow/issues
|
|
10
|
+
Keywords: manim,animation,reactive,math,visualization
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Education
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: numpy
|
|
24
|
+
Provides-Extra: manim
|
|
25
|
+
Requires-Dist: manim>=0.20; extra == "manim"
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
30
|
+
Requires-Dist: build>=1; extra == "dev"
|
|
31
|
+
Requires-Dist: twine>=6.2; extra == "dev"
|
|
32
|
+
Requires-Dist: packaging>=24.2; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# Manim Stateflow
|
|
36
|
+
|
|
37
|
+
State-driven Manim scenes without manual updater wiring.
|
|
38
|
+
|
|
39
|
+
Manim Stateflow generalizes the idea behind `ValueTracker`. A state can hold a
|
|
40
|
+
number, color, array, string, dataclass, or any Python object. Animate the
|
|
41
|
+
state, and every object that depends on it moves with the animation.
|
|
42
|
+
|
|
43
|
+
Instead of manually updating each dependent dot, label, line, brace, number,
|
|
44
|
+
graph, or custom mobject, describe the relationship once: this object depends
|
|
45
|
+
on this state, this computed value, or this other object.
|
|
46
|
+
|
|
47
|
+
All normal Manim features still work. Use `self.play(...)`, `Create`,
|
|
48
|
+
`Transform`, camera moves, updaters, and regular mobjects as usual. Stateflow
|
|
49
|
+
is an extension layer that changes the programming style: define state, connect
|
|
50
|
+
dependencies, then animate the state.
|
|
51
|
+
|
|
52
|
+
## Start Here
|
|
53
|
+
|
|
54
|
+
Install from GitHub:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install "manim-stateflow[manim] @ git+https://github.com/rehanmm/manim-stateflow.git"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If Manim is already installed in your environment, `pip install
|
|
61
|
+
git+https://github.com/rehanmm/manim-stateflow.git` is enough.
|
|
62
|
+
|
|
63
|
+
## Install For Development
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/rehanmm/manim-stateflow.git
|
|
67
|
+
cd manim-stateflow
|
|
68
|
+
python -m pip install -e ".[test]"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Use `".[test,manim]"` when you also want to render the example scenes from that
|
|
72
|
+
environment.
|
|
73
|
+
|
|
74
|
+
## Three Tiny API Snippets
|
|
75
|
+
|
|
76
|
+
### Move A Dot From State
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from manim import *
|
|
80
|
+
from manim_stateflow import ReactiveScene, d
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class MovingDot(ReactiveScene):
|
|
84
|
+
def construct(self):
|
|
85
|
+
x = self.state(-3)
|
|
86
|
+
dot = d.Dot([x, 0, 0], color=YELLOW)
|
|
87
|
+
|
|
88
|
+
self.add(NumberLine(x_range=[-4, 4, 1]), dot)
|
|
89
|
+
self.play(x.animate_to(3), run_time=3)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
<p align="center">
|
|
93
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/tiny-moving-dot.gif" alt="Moving dot preview" width="520">
|
|
94
|
+
</p>
|
|
95
|
+
|
|
96
|
+
### Compute A Point With `lift(...)`
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from manim import *
|
|
100
|
+
import numpy as np
|
|
101
|
+
|
|
102
|
+
from manim_stateflow import ReactiveScene, d, lift
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class SinePoint(ReactiveScene):
|
|
106
|
+
def construct(self):
|
|
107
|
+
axes = Axes(x_range=[-4, 4, 1], y_range=[-2, 2, 1])
|
|
108
|
+
x = self.state(-3.0)
|
|
109
|
+
|
|
110
|
+
y = lift(lambda value: np.sin(value), x)
|
|
111
|
+
point = lift(lambda x_value, y_value: axes.c2p(x_value, y_value), x, y)
|
|
112
|
+
dot = d.Dot(point, color=YELLOW)
|
|
113
|
+
|
|
114
|
+
self.add(axes, axes.plot(np.sin, x_range=[-4, 4]), dot)
|
|
115
|
+
self.play(x.animate_to(3.0), run_time=4)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
<p align="center">
|
|
119
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/tiny-sine-point.gif" alt="Sine point preview" width="520">
|
|
120
|
+
</p>
|
|
121
|
+
|
|
122
|
+
### Use Mixed State Types
|
|
123
|
+
|
|
124
|
+
State does not have to be one scalar. One `self.state(...)` object can hold
|
|
125
|
+
independent fields, and those fields can have different types.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from manim import *
|
|
129
|
+
|
|
130
|
+
from manim_stateflow import ReactiveScene, d
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class MixedStateTypes(ReactiveScene):
|
|
134
|
+
def construct(self):
|
|
135
|
+
state = self.state(x=-2.5, radius=0.07, color="#ffcc44")
|
|
136
|
+
|
|
137
|
+
dot = d.Dot([state.x, 0, 0], radius=state.radius, color=state.color)
|
|
138
|
+
label = MathTex(r"\text{state}").scale(0.45)
|
|
139
|
+
label.d.next_to(dot, UP, buff=0.18)
|
|
140
|
+
|
|
141
|
+
self.add(NumberLine(x_range=[-3, 3, 1]), dot, label)
|
|
142
|
+
self.play(
|
|
143
|
+
state.animate_to(x=2.5, radius=0.13, color="#66d9ef"),
|
|
144
|
+
run_time=3,
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
<p align="center">
|
|
149
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/tiny-mixed-state.gif" alt="Mixed state preview" width="520">
|
|
150
|
+
</p>
|
|
151
|
+
|
|
152
|
+
## Core Example
|
|
153
|
+
|
|
154
|
+
This one scene shows the main pattern:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
state -> lift -> d.<ManimMobject> / d.call -> mobject.d.<method>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from math import cos, sin
|
|
162
|
+
|
|
163
|
+
from manim import *
|
|
164
|
+
import numpy as np
|
|
165
|
+
|
|
166
|
+
from manim_stateflow import ReactiveScene, d, lift
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class CorePattern(ReactiveScene):
|
|
170
|
+
def construct(self):
|
|
171
|
+
center = ORIGIN
|
|
172
|
+
|
|
173
|
+
# state: multiple independent source values in one object
|
|
174
|
+
state = self.state(angle=0.25, radius=1.15)
|
|
175
|
+
|
|
176
|
+
# lift: computed values derived from state
|
|
177
|
+
point = lift(
|
|
178
|
+
lambda angle, radius: center
|
|
179
|
+
+ radius * np.array([cos(angle), sin(angle), 0.0]),
|
|
180
|
+
state.angle,
|
|
181
|
+
state.radius,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# d.<ManimMobject>: normal Manim constructors with reactive inputs
|
|
185
|
+
dot = d.Dot(point, radius=0.1, color=YELLOW)
|
|
186
|
+
|
|
187
|
+
# d.call: custom Manim builders from reactive inputs
|
|
188
|
+
orbit = d.call(
|
|
189
|
+
lambda radius: Circle(radius=radius, color=BLUE)
|
|
190
|
+
.move_to(center)
|
|
191
|
+
.set_stroke(width=4, opacity=0.35),
|
|
192
|
+
state.radius,
|
|
193
|
+
)
|
|
194
|
+
radius_line = d.Line(center, point, color=BLUE, stroke_width=6)
|
|
195
|
+
|
|
196
|
+
# mobject.d.<method>: existing objects follow reactive objects
|
|
197
|
+
label = MathTex("p").scale(0.8)
|
|
198
|
+
label.d.next_to(dot, UR, buff=0.12)
|
|
199
|
+
|
|
200
|
+
title = MathTex(r"\text{state}\rightarrow\text{lift}\rightarrow\text{object}")
|
|
201
|
+
title.scale(0.68).to_edge(UP, buff=0.45)
|
|
202
|
+
|
|
203
|
+
self.play(Write(title), FadeIn(orbit), FadeIn(radius_line), FadeIn(dot), FadeIn(label))
|
|
204
|
+
self.play(state.animate_to(angle=TAU * 0.82), run_time=4)
|
|
205
|
+
self.play(state.animate_to(radius=1.75), run_time=2)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
<p align="center">
|
|
209
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/core-pattern.gif" alt="Core pattern preview" width="520">
|
|
210
|
+
</p>
|
|
211
|
+
|
|
212
|
+
## All Examples
|
|
213
|
+
|
|
214
|
+
The examples are the full tutorial. Each source file has comments explaining
|
|
215
|
+
what to notice and how to run it.
|
|
216
|
+
|
|
217
|
+
### 00. Quickstart
|
|
218
|
+
|
|
219
|
+
<p align="center">
|
|
220
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/quickstart.gif" alt="Quickstart preview" width="520">
|
|
221
|
+
</p>
|
|
222
|
+
|
|
223
|
+
[`examples/01_quickstart.py`](examples/01_quickstart.py)
|
|
224
|
+
A compact calculus scene using state, `lift(...)`, `d.call(...)`, and object wiring.
|
|
225
|
+
|
|
226
|
+
### 01. Core Pattern
|
|
227
|
+
|
|
228
|
+
[`examples/beginner/01_core_pattern.py`](examples/beginner/01_core_pattern.py)
|
|
229
|
+
The core `state -> lift -> d.Object / d.call -> mobject.d.<method>` pattern.
|
|
230
|
+
|
|
231
|
+
### 02. Frame Simulation Pattern
|
|
232
|
+
|
|
233
|
+
<p align="center">
|
|
234
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/frame-simulation-pattern.gif" alt="Frame simulation preview" width="520">
|
|
235
|
+
</p>
|
|
236
|
+
|
|
237
|
+
[`examples/beginner/02_frame_simulation_pattern.py`](examples/beginner/02_frame_simulation_pattern.py)
|
|
238
|
+
Frame-time simulation with `.d.on_frame(...)` and `dt`.
|
|
239
|
+
|
|
240
|
+
### 03. Smooth Interpolation
|
|
241
|
+
|
|
242
|
+
<p align="center">
|
|
243
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/smooth-interpolation.gif" alt="Smooth interpolation preview" width="520">
|
|
244
|
+
</p>
|
|
245
|
+
|
|
246
|
+
[`examples/beginner/03_smooth_interpolation.py`](examples/beginner/03_smooth_interpolation.py)
|
|
247
|
+
Smooth interpolation for numbers, NumPy arrays, and hex colors.
|
|
248
|
+
|
|
249
|
+
### 04. Jump Is Necessary
|
|
250
|
+
|
|
251
|
+
<p align="center">
|
|
252
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/jump-is-necessary.gif" alt="Jump preview" width="520">
|
|
253
|
+
</p>
|
|
254
|
+
|
|
255
|
+
[`examples/beginner/04_jump_is_necessary.py`](examples/beginner/04_jump_is_necessary.py)
|
|
256
|
+
Discrete state changes with `jump(...)`.
|
|
257
|
+
|
|
258
|
+
### 05. Multiple State Values And Types
|
|
259
|
+
|
|
260
|
+
<p align="center">
|
|
261
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/multiple-state-values-and-types.gif" alt="Multiple state values preview" width="520">
|
|
262
|
+
</p>
|
|
263
|
+
|
|
264
|
+
[`examples/beginner/05_multiple_state_values_and_types.py`](examples/beginner/05_multiple_state_values_and_types.py)
|
|
265
|
+
Multiple independent state fields in one named state object.
|
|
266
|
+
|
|
267
|
+
### 06. Matrix State
|
|
268
|
+
|
|
269
|
+
<p align="center">
|
|
270
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/matrix-state.gif" alt="Matrix state preview" width="520">
|
|
271
|
+
</p>
|
|
272
|
+
|
|
273
|
+
[`examples/intermediate/06_matrix_state.py`](examples/intermediate/06_matrix_state.py)
|
|
274
|
+
A NumPy matrix driving a linear transformation.
|
|
275
|
+
|
|
276
|
+
### 07. Object Wiring
|
|
277
|
+
|
|
278
|
+
<p align="center">
|
|
279
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/object-wiring.gif" alt="Object wiring preview" width="520">
|
|
280
|
+
</p>
|
|
281
|
+
|
|
282
|
+
[`examples/intermediate/07_object_wiring.py`](examples/intermediate/07_object_wiring.py)
|
|
283
|
+
Labels, braces, and values following reactive geometry.
|
|
284
|
+
|
|
285
|
+
### 08. Custom Builder With `d.call(...)`
|
|
286
|
+
|
|
287
|
+
<p align="center">
|
|
288
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/d-call-custom-builder.gif" alt="Custom builder preview" width="520">
|
|
289
|
+
</p>
|
|
290
|
+
|
|
291
|
+
[`examples/intermediate/08_d_call_custom_builder.py`](examples/intermediate/08_d_call_custom_builder.py)
|
|
292
|
+
Rebuilding a composed chart visual with `d.call(...)`.
|
|
293
|
+
|
|
294
|
+
### 09. Custom Python Object State
|
|
295
|
+
|
|
296
|
+
<p align="center">
|
|
297
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/custom-python-object-state.gif" alt="Custom Python object state preview" width="520">
|
|
298
|
+
</p>
|
|
299
|
+
|
|
300
|
+
[`examples/intermediate/09_custom_python_object_state.py`](examples/intermediate/09_custom_python_object_state.py)
|
|
301
|
+
Dataclass state switched through exact states with `jump(...)`.
|
|
302
|
+
|
|
303
|
+
### 10. `d.call(...)` Vs `.d.apply(...)`
|
|
304
|
+
|
|
305
|
+
<p align="center">
|
|
306
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/call-vs-apply.gif" alt="Call vs apply preview" width="520">
|
|
307
|
+
</p>
|
|
308
|
+
|
|
309
|
+
[`examples/intermediate/10_call_vs_apply.py`](examples/intermediate/10_call_vs_apply.py)
|
|
310
|
+
The difference between rebuilding with `d.call(...)` and mutating with `.d.apply(...)`.
|
|
311
|
+
|
|
312
|
+
### 11. Reactive Surface 3D
|
|
313
|
+
|
|
314
|
+
<p align="center">
|
|
315
|
+
<img src="https://raw.githubusercontent.com/rehanmm/manim-stateflow/main/docs/assets/gifs/reactive-surface-3d.gif" alt="Reactive surface preview" width="520">
|
|
316
|
+
</p>
|
|
317
|
+
|
|
318
|
+
[`examples/advanced/11_reactive_surface_3d.py`](examples/advanced/11_reactive_surface_3d.py)
|
|
319
|
+
A 3D surface rebuilt from state inside `ReactiveThreeDScene`.
|
|
320
|
+
|
|
321
|
+
## Learn Next
|
|
322
|
+
|
|
323
|
+
The core example covers the everyday dependency pattern. After that, these are
|
|
324
|
+
the next ideas to learn:
|
|
325
|
+
|
|
326
|
+
- `jump(...)` for discrete state changes:
|
|
327
|
+
[Jump Is Necessary](examples/beginner/04_jump_is_necessary.py)
|
|
328
|
+
- `mobject.d.apply(...)` for custom dependency-driven updates:
|
|
329
|
+
[Call vs Apply](examples/intermediate/10_call_vs_apply.py)
|
|
330
|
+
- `mobject.d.on_frame(...)` for frame-time behavior with `dt`:
|
|
331
|
+
[Frame Simulation Pattern](examples/beginner/02_frame_simulation_pattern.py)
|
|
332
|
+
- Full guide:
|
|
333
|
+
[docs/guide.md](docs/guide.md)
|
|
334
|
+
|
|
335
|
+
## API Preview
|
|
336
|
+
|
|
337
|
+
The everyday API is intentionally small:
|
|
338
|
+
|
|
339
|
+
- `ReactiveScene`
|
|
340
|
+
- `ReactiveThreeDScene`
|
|
341
|
+
- `self.state(...)`
|
|
342
|
+
- `lift(...)`
|
|
343
|
+
- `jump(...)`
|
|
344
|
+
- `d.<ManimMobject>(...)`
|
|
345
|
+
- `d.call(...)`
|
|
346
|
+
- `value.animate_to(...)`
|
|
347
|
+
- `state.animate_to(...)`
|
|
348
|
+
- `state.animate.transform(...).using({...})`
|
|
349
|
+
- `mobject.d.<method>(...)`
|
|
350
|
+
- `mobject.d.apply(...)`
|
|
351
|
+
- `mobject.d.on_frame(...)`
|
|
352
|
+
|
|
353
|
+
See [`docs/reference.md`](docs/reference.md) for the full reference.
|
|
354
|
+
|
|
355
|
+
## Tests
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
python -m pytest tests -q
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Status
|
|
362
|
+
|
|
363
|
+
Manim Stateflow is early and experimental. The package has a passing test suite
|
|
364
|
+
and runnable example scenes, but the public API may still change before a first
|
|
365
|
+
stable release.
|
|
366
|
+
|
|
367
|
+
## License
|
|
368
|
+
|
|
369
|
+
MIT
|