@@ -29,10 +29,10 @@ def __init__(
2929 super ().__init__ (* args , ** kwargs )
3030 self ._output_folder : Path = output_folder
3131 self ._slides : List [PreSlideConfig ] = []
32+ self ._pre_slide_config_kwargs : MutableMapping [str , Any ] = {}
3233 self ._current_slide = 1
3334 self ._current_animation = 0
34- self ._loop_start_animation : Optional [int ] = None
35- self ._pause_start_animation = 0
35+ self ._start_animation = 0
3636 self ._canvas : MutableMapping [str , Mobject ] = {}
3737 self ._wait_time_between_slides = 0.0
3838
@@ -252,13 +252,16 @@ def play(self, *args: Any, **kwargs: Any) -> None:
252252 super ().play (* args , ** kwargs ) # type: ignore[misc]
253253 self ._current_animation += 1
254254
255- def next_slide (self ) -> None :
255+ def next_slide (self , loop : bool = False ) -> None :
256256 """
257- Create a new slide with previous animations.
257+ Create a new slide with previous animations, and setup options
258+ for the next slide.
258259
259260 This usually means that the user will need to press some key before the
260261 next slide is played. By default, this is the right arrow key.
261262
263+ :param loop:
264+ If set, next slide will be looping.
262265
263266 .. note::
264267
@@ -267,7 +270,8 @@ def next_slide(self) -> None:
267270
268271 .. warning::
269272
270- This is not allowed to call :func:`next_slide` inside a loop.
273+ When rendered with RevealJS, loops cannot be in the first nor
274+ the last slide.
271275
272276 Examples
273277 --------
@@ -290,58 +294,7 @@ def construct(self):
290294
291295 self.next_slide()
292296 self.play(FadeOut(text))
293- """
294- assert (
295- self ._loop_start_animation is None
296- ), "You cannot call `self.next_slide()` inside a loop"
297-
298- if self .wait_time_between_slides > 0.0 :
299- self .wait (self .wait_time_between_slides ) # type: ignore[attr-defined]
300-
301- self ._slides .append (
302- PreSlideConfig (
303- start_animation = self ._pause_start_animation ,
304- end_animation = self ._current_animation ,
305- )
306- )
307- self ._current_slide += 1
308- self ._pause_start_animation = self ._current_animation
309-
310- def _add_last_slide (self ) -> None :
311- """Add a 'last' slide to the end of slides."""
312- if (
313- len (self ._slides ) > 0
314- and self ._current_animation == self ._slides [- 1 ].end_animation
315- ):
316- return
317-
318- self ._slides .append (
319- PreSlideConfig (
320- start_animation = self ._pause_start_animation ,
321- end_animation = self ._current_animation ,
322- loop = self ._loop_start_animation is not None ,
323- )
324- )
325-
326- def start_loop (self ) -> None :
327- """
328- Start a loop. End it with :func:`end_loop`.
329297
330- A loop will automatically replay the slide, i.e., everything between
331- :func:`start_loop` and :func:`end_loop`, upon reaching end.
332-
333- .. warning::
334-
335- You should always call :func:`next_slide` before calling this
336- method. Otherwise, ...
337-
338- .. warning::
339-
340- When rendered with RevealJS, loops cannot be in the first nor
341- the last slide.
342-
343- Examples
344- --------
345298 The following contains one slide that will loop endlessly.
346299
347300 .. manim-slides:: LoopExample
@@ -354,38 +307,46 @@ def construct(self):
354307 dot = Dot(color=BLUE, radius=1)
355308
356309 self.play(FadeIn(dot))
357- self.next_slide()
358310
359- self.start_loop( )
311+ self.next_slide(loop=True )
360312
361313 self.play(Indicate(dot, scale_factor=2))
362314
363- self.end_loop ()
315+ self.next_slide ()
364316
365317 self.play(FadeOut(dot))
366318 """
367- assert self ._loop_start_animation is None , "You cannot nest loops"
368- self ._loop_start_animation = self ._current_animation
319+ if self ._current_animation > self ._start_animation :
320+ if self .wait_time_between_slides > 0.0 :
321+ self .wait (self .wait_time_between_slides ) # type: ignore[attr-defined]
322+
323+ self ._slides .append (
324+ PreSlideConfig (
325+ start_animation = self ._start_animation ,
326+ end_animation = self ._current_animation ,
327+ ** self ._pre_slide_config_kwargs ,
328+ )
329+ )
369330
370- def end_loop (self ) -> None :
371- """
372- End an existing loop.
331+ self ._pre_slide_config_kwargs = dict (loop = loop )
332+ self ._current_slide += 1
333+ self ._start_animation = self ._current_animation
334+
335+ def _add_last_slide (self ) -> None :
336+ """Add a 'last' slide to the end of slides."""
337+ if (
338+ len (self ._slides ) > 0
339+ and self ._current_animation == self ._slides [- 1 ].end_animation
340+ ):
341+ return
373342
374- See :func:`start_loop` for more details.
375- """
376- assert (
377- self ._loop_start_animation is not None
378- ), "You have to start a loop before ending it"
379343 self ._slides .append (
380344 PreSlideConfig (
381- start_animation = self ._loop_start_animation ,
345+ start_animation = self ._start_animation ,
382346 end_animation = self ._current_animation ,
383- loop = True ,
347+ ** self . _pre_slide_config_kwargs ,
384348 )
385349 )
386- self ._current_slide += 1
387- self ._loop_start_animation = None
388- self ._pause_start_animation = self ._current_animation
389350
390351 def _save_slides (self , use_cache : bool = True ) -> None :
391352 """
0 commit comments