|
3 | 3 | __all__ = ["Scene"]
|
4 | 4 |
|
5 | 5 | import copy
|
| 6 | +import datetime |
6 | 7 | import inspect
|
7 | 8 | import platform
|
8 | 9 | import random
|
|
12 | 13 | from queue import Queue
|
13 | 14 | from typing import List, Optional
|
14 | 15 |
|
| 16 | +import srt |
| 17 | + |
15 | 18 | from manim.scene.section import DefaultSectionType
|
16 | 19 |
|
17 | 20 | try:
|
@@ -899,8 +902,50 @@ def get_run_time(self, animations):
|
899 | 902 | else:
|
900 | 903 | return np.max([animation.run_time for animation in animations])
|
901 | 904 |
|
902 |
| - def play(self, *args, **kwargs): |
| 905 | + def play( |
| 906 | + self, |
| 907 | + *args, |
| 908 | + subcaption=None, |
| 909 | + subcaption_duration=None, |
| 910 | + subcaption_offset=0, |
| 911 | + **kwargs, |
| 912 | + ): |
| 913 | + r"""Plays an animation in this scene. |
| 914 | +
|
| 915 | + Parameters |
| 916 | + ---------- |
| 917 | +
|
| 918 | + args |
| 919 | + Animations to be played. |
| 920 | + subcaption |
| 921 | + The content of the external subcaption that should |
| 922 | + be added during the animation. |
| 923 | + subcaption_duration |
| 924 | + The duration for which the specified subcaption is |
| 925 | + added. If ``None`` (the default), the run time of the |
| 926 | + animation is taken. |
| 927 | + subcaption_offset |
| 928 | + An offset (in seconds) for the start time of the |
| 929 | + added subcaption. |
| 930 | + kwargs |
| 931 | + All other keywords are passed to the renderer. |
| 932 | +
|
| 933 | + """ |
| 934 | + start_time = self.renderer.time |
903 | 935 | self.renderer.play(self, *args, **kwargs)
|
| 936 | + run_time = self.renderer.time - start_time |
| 937 | + if subcaption: |
| 938 | + if subcaption_duration is None: |
| 939 | + subcaption_duration = run_time |
| 940 | + # The start of the subcaption needs to be offset by the |
| 941 | + # run_time of the animation because it is added after |
| 942 | + # the animation has already been played (and Scene.renderer.time |
| 943 | + # has already been updated). |
| 944 | + self.add_subcaption( |
| 945 | + content=subcaption, |
| 946 | + duration=subcaption_duration, |
| 947 | + offset=-run_time + subcaption_offset, |
| 948 | + ) |
904 | 949 |
|
905 | 950 | def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None):
|
906 | 951 | self.play(Wait(run_time=duration, stop_condition=stop_condition))
|
@@ -1242,6 +1287,55 @@ def update_to_time(self, t):
|
1242 | 1287 | self.update_meshes(dt)
|
1243 | 1288 | self.update_self(dt)
|
1244 | 1289 |
|
| 1290 | + def add_subcaption( |
| 1291 | + self, content: str, duration: float = 1, offset: float = 0 |
| 1292 | + ) -> None: |
| 1293 | + r"""Adds an entry in the corresponding subcaption file |
| 1294 | + at the current time stamp. |
| 1295 | +
|
| 1296 | + The current time stamp is obtained from ``Scene.renderer.time``. |
| 1297 | +
|
| 1298 | + Parameters |
| 1299 | + ---------- |
| 1300 | +
|
| 1301 | + content |
| 1302 | + The subcaption content. |
| 1303 | + duration |
| 1304 | + The duration (in seconds) for which the subcaption is shown. |
| 1305 | + offset |
| 1306 | + This offset (in seconds) is added to the starting time stamp |
| 1307 | + of the subcaption. |
| 1308 | +
|
| 1309 | + Examples |
| 1310 | + -------- |
| 1311 | +
|
| 1312 | + This example illustrates both possibilities for adding |
| 1313 | + subcaptions to Manimations:: |
| 1314 | +
|
| 1315 | + class SubcaptionExample(Scene): |
| 1316 | + def construct(self): |
| 1317 | + square = Square() |
| 1318 | + circle = Circle() |
| 1319 | +
|
| 1320 | + # first option: via the add_subcaption method |
| 1321 | + self.add_subcaption("Hello square!", duration=1) |
| 1322 | + self.play(Create(square)) |
| 1323 | +
|
| 1324 | + # second option: within the call to Scene.play |
| 1325 | + self.play( |
| 1326 | + Transform(square, circle), |
| 1327 | + subcaption="The square transforms." |
| 1328 | + ) |
| 1329 | +
|
| 1330 | + """ |
| 1331 | + subtitle = srt.Subtitle( |
| 1332 | + index=len(self.renderer.file_writer.subcaptions), |
| 1333 | + content=content, |
| 1334 | + start=datetime.timedelta(seconds=self.renderer.time + offset), |
| 1335 | + end=datetime.timedelta(seconds=self.renderer.time + offset + duration), |
| 1336 | + ) |
| 1337 | + self.renderer.file_writer.subcaptions.append(subtitle) |
| 1338 | + |
1245 | 1339 | def add_sound(self, sound_file, time_offset=0, gain=None, **kwargs):
|
1246 | 1340 | """
|
1247 | 1341 | This method is used to add a sound to the animation.
|
|
0 commit comments