From b07a83898b0ff12e97091a6bdfd8f2c57e6a0e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Wed, 22 Jan 2025 21:10:37 +0100 Subject: [PATCH] feat(lib): add `start_skip_animations` and `stop_skip_animations` meth. (#523) --- CHANGELOG.md | 6 ++++++ docs/source/reference/api.md | 2 ++ manim_slides/slide/base.py | 27 +++++++++++++++++++++++++++ tests/test_base_slide.py | 9 +++++++++ tests/test_slide.py | 22 ++++++++++++++++++++++ 5 files changed, 66 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 596db159..24717d4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 (unreleased)= ## [Unreleased](https://github.com/jeertmans/manim-slides/compare/v5.4.0...HEAD) +(unreleased-added)= +### Added + +- Added `start_skip_animations` and `stop_skip_animations` methods. + [#523](https://github.com/jeertmans/manim-slides/pull/523) + (v5.4.0)= ## [v5.4.0](https://github.com/jeertmans/manim-slides/compare/v5.3.1...v5.4.0) diff --git a/docs/source/reference/api.md b/docs/source/reference/api.md index 3a707933..25d2ae1f 100644 --- a/docs/source/reference/api.md +++ b/docs/source/reference/api.md @@ -18,6 +18,8 @@ use, not the methods used internally when rendering. next_section, next_slide, remove_from_canvas, + start_skip_animations, + stop_skip_animations, wait_time_between_slides, wipe, zoom, diff --git a/manim_slides/slide/base.py b/manim_slides/slide/base.py index cc728de6..64f23992 100644 --- a/manim_slides/slide/base.py +++ b/manim_slides/slide/base.py @@ -49,6 +49,7 @@ def __init__( self._start_animation = 0 self._canvas: MutableMapping[str, Mobject] = {} self._wait_time_between_slides = 0.0 + self._skip_animations = False @property @abstractmethod @@ -304,6 +305,11 @@ def next_slide( If `manim` is used, this is also passed to `:meth:`Scene.next_section`, which will avoid rendering the corresponding animations. + + .. seealso:: + + :meth:`start_skip_animations` + :meth:`stop_skip_animations` :param loop: If set, next slide will be looping. :param auto_next: @@ -463,6 +469,9 @@ def construct(self): self._current_slide += 1 + if self._skip_animations: + base_slide_config.skip_animations = True + self._base_slide_config = base_slide_config self._start_animation = self._current_animation @@ -572,6 +581,24 @@ def _save_slides( f"Slide '{scene_name}' configuration written in '{slide_path.absolute()}'" ) + def start_skip_animations(self) -> None: + """ + Start skipping animations. + + This automatically applies ``skip_animations=True`` + to all subsequent calls to :meth:`next_slide`. + + This is useful when you want to skip animations from multiple slides in a row, + without having to manually set ``skip_animations=True``. + """ + self._skip_animations = True + + def stop_skip_animations(self) -> None: + """ + Stop skipping animations. + """ + self._skip_animations = False + def wipe( self, *args: Any, diff --git a/tests/test_base_slide.py b/tests/test_base_slide.py index 7119fbcc..6ece844c 100644 --- a/tests/test_base_slide.py +++ b/tests/test_base_slide.py @@ -86,6 +86,15 @@ def test_wait_time_between_slides(self, base_slide: BaseSlide) -> None: assert base_slide.wait_time_between_slides == 0.0 + def test_skip_animations(self, base_slide: BaseSlide) -> None: + assert base_slide._skip_animations == False + + def test_start_and_stop_skip_animations(self, base_slide: BaseSlide) -> None: + base_slide.start_skip_animations() + assert base_slide._skip_animations == True + base_slide.stop_skip_animations() + assert base_slide._skip_animations == False + def test_play(self) -> None: pass # This method should be tested in test_slide.py diff --git a/tests/test_slide.py b/tests/test_slide.py index 1a6ccf60..c4baeba2 100644 --- a/tests/test_slide.py +++ b/tests/test_slide.py @@ -527,9 +527,25 @@ def construct(self) -> None: assert not self._base_slide_config.skip_animations self.play(GrowFromCenter(square)) + class Baz(CESlide): + def construct(self) -> None: + circle = Circle(color=BLUE) + self.play(GrowFromCenter(circle)) + assert not self._base_slide_config.skip_animations + self.start_skip_animations() + self.next_slide() + square = Square(color=BLUE) + self.play(GrowFromCenter(square)) + assert self._base_slide_config.skip_animations + self.next_slide() + assert self._base_slide_config.skip_animations + self.play(GrowFromCenter(square)) + self.stop_skip_animations() + with tmp_cwd() as tmp_dir: init_slide(Foo).render() init_slide(Bar).render() + init_slide(Baz).render() slides_folder = Path(tmp_dir) / "slides" @@ -547,6 +563,12 @@ def construct(self) -> None: assert len(config.slides) == 3 + slide_file = slides_folder / "Baz.json" + + config = PresentationConfig.from_file(slide_file) + + assert len(config.slides) == 1 + def test_canvas(self) -> None: @assert_constructs class _(CESlide):