Skip to content

Commit af3c497

Browse files
authored
feat(lib): add return_animation option (#331)
* feat(lib): add `return_animation` option Allow to return animation instead of playing it. * fix(lib): docs issue * fix(ci): build with Python 3.10
1 parent b3ed127 commit af3c497

File tree

5 files changed

+58
-13
lines changed

5 files changed

+58
-13
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[bumpversion]
22
current_version = 5.1.0-rc1
33
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-rc(?P<release>\d+))?
4-
serialize =
4+
serialize =
55
{major}.{minor}.{patch}-rc{release}
66
{major}.{minor}.{patch}
77
commit = True

.github/workflows/pages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
- name: Install Python
3939
uses: actions/setup-python@v4
4040
with:
41-
python-version: '3.9'
41+
python-version: '3.10'
4242
cache: poetry
4343
- name: Setup Pages
4444
uses: actions/configure-pages@v3

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2727
This is somewhat a **breaking change**, but changes to the CLI
2828
API are not considered to be very important.
2929
[#325](https://github.com/jeertmans/manim-slides/pull/325)
30+
- Added `return_animation` option to slide animations `self.wipe`
31+
and `self.zoom`.
32+
[#331](https://github.com/jeertmans/manim-slides/pull/331)
3033

3134
(v5.1-modified)=
3235
### Modified

docs/source/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
# For the full list of built-in configuration values, see the documentation:
55
# https://www.sphinx-doc.org/en/master/usage/configuration.html
66

7+
import sys
8+
9+
assert sys.version_info >= (3, 10), "Building docs requires Python 3.10"
10+
711
# -- Project information -----------------------------------------------------
812
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
913

manim_slides/slide/base.py

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
from __future__ import annotations
2+
13
__all__ = ["BaseSlide"]
24

35
import platform
46
from abc import abstractmethod
57
from pathlib import Path
6-
from typing import Any, List, MutableMapping, Optional, Sequence, Tuple, ValuesView
8+
from typing import (
9+
TYPE_CHECKING,
10+
Any,
11+
MutableMapping,
12+
Sequence,
13+
ValuesView,
14+
)
715

816
import numpy as np
917
from tqdm import tqdm
@@ -14,6 +22,9 @@
1422
from ..utils import concatenate_video_files, merge_basenames, reverse_video_file
1523
from . import MANIM
1624

25+
if TYPE_CHECKING:
26+
from .animation import Wipe, Zoom
27+
1728
if MANIM:
1829
from manim.mobject.mobject import Mobject
1930
else:
@@ -28,7 +39,7 @@ def __init__(
2839
) -> None:
2940
super().__init__(*args, **kwargs)
3041
self._output_folder: Path = output_folder
31-
self._slides: List[PreSlideConfig] = []
42+
self._slides: list[PreSlideConfig] = []
3243
self._base_slide_config: BaseSlideConfig = BaseSlideConfig()
3344
self._current_slide = 1
3445
self._current_animation = 0
@@ -61,13 +72,13 @@ def _background_color(self) -> str:
6172

6273
@property
6374
@abstractmethod
64-
def _resolution(self) -> Tuple[int, int]:
75+
def _resolution(self) -> tuple[int, int]:
6576
"""Return the scene's resolution used during rendering."""
6677
raise NotImplementedError
6778

6879
@property
6980
@abstractmethod
70-
def _partial_movie_files(self) -> List[Path]:
81+
def _partial_movie_files(self) -> list[Path]:
7182
"""Return a list of partial movie files, a.k.a animations."""
7283
raise NotImplementedError
7384

@@ -85,7 +96,7 @@ def _leave_progress_bar(self) -> bool:
8596

8697
@property
8798
@abstractmethod
88-
def _start_at_animation_number(self) -> Optional[int]:
99+
def _start_at_animation_number(self) -> int | None:
89100
"""If set, return the animation number at which rendering start."""
90101
raise NotImplementedError
91102

@@ -453,7 +464,7 @@ def _save_slides(self, use_cache: bool = True) -> None:
453464

454465
scene_files_folder.mkdir(parents=True, exist_ok=True)
455466

456-
files: List[Path] = self._partial_movie_files
467+
files: list[Path] = self._partial_movie_files
457468

458469
# We must filter slides that end before the animation offset
459470
if offset := self._start_at_animation_number:
@@ -464,7 +475,7 @@ def _save_slides(self, use_cache: bool = True) -> None:
464475
slide.start_animation = max(0, slide.start_animation - offset)
465476
slide.end_animation -= offset
466477

467-
slides: List[SlideConfig] = []
478+
slides: list[SlideConfig] = []
468479

469480
for pre_slide_config in tqdm(
470481
self._slides,
@@ -513,15 +524,18 @@ def wipe(
513524
self,
514525
*args: Any,
515526
direction: np.ndarray = LEFT,
527+
return_animation: bool = False,
516528
**kwargs: Any,
517-
) -> None:
529+
) -> Wipe | None:
518530
"""
519531
Play a wipe animation that will shift all the current objects outside of the
520532
current scene's scope, and all the future objects inside.
521533
522534
:param args: Positional arguments passed to
523535
:class:`Wipe<manim_slides.slide.animation.Wipe>`.
524536
:param direction: The wipe direction, that will be scaled by the scene size.
537+
:param return_animation: If set, return the animation instead of
538+
playing it. This is useful to combine multiple animations with this one.
525539
:param kwargs: Keyword arguments passed to
526540
:class:`Wipe<manim_slides.slide.animation.Wipe>`.
527541
@@ -548,7 +562,13 @@ def construct(self):
548562
self.wipe(Group(square, text), beautiful, direction=UP)
549563
self.next_slide()
550564
551-
self.wipe(beautiful, circle, direction=DOWN + RIGHT)
565+
anim = self.wipe(
566+
beautiful,
567+
circle,
568+
direction=DOWN + RIGHT,
569+
return_animation=True
570+
)
571+
self.play(anim)
552572
"""
553573
from .animation import Wipe
554574

@@ -563,20 +583,27 @@ def construct(self):
563583
**kwargs,
564584
)
565585

586+
if return_animation:
587+
return animation
588+
566589
self.play(animation)
590+
return None
567591

568592
def zoom(
569593
self,
570594
*args: Any,
595+
return_animation: bool = False,
571596
**kwargs: Any,
572-
) -> None:
597+
) -> Zoom | None:
573598
"""
574599
Play a zoom animation that will fade out all the current objects, and fade in
575600
all the future objects. Objects are faded in a direction that goes towards the
576601
camera.
577602
578603
:param args: Positional arguments passed to
579604
:class:`Zoom<manim_slides.slide.animation.Zoom>`.
605+
:param return_animation: If set, return the animation instead of
606+
playing it. This is useful to combine multiple animations with this one.
580607
:param kwargs: Keyword arguments passed to
581608
:class:`Zoom<manim_slides.slide.animation.Zoom>`.
582609
@@ -598,10 +625,21 @@ def construct(self):
598625
self.zoom(circle, square)
599626
self.next_slide()
600627
601-
self.zoom(square, circle, out=True, scale=10.0)
628+
anim = self.zoom(
629+
square,
630+
circle,
631+
out=True,
632+
scale=10.0,
633+
return_animation=True
634+
)
635+
self.play(anim)
602636
"""
603637
from .animation import Zoom
604638

605639
animation = Zoom(*args, **kwargs)
606640

641+
if return_animation:
642+
return animation
643+
607644
self.play(animation)
645+
return None

0 commit comments

Comments
 (0)