manim 0.17.0__py3-none-any.whl → 0.19.1__py3-none-any.whl

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.
Files changed (163) hide show
  1. manim/__init__.py +11 -6
  2. manim/__main__.py +62 -19
  3. manim/_config/__init__.py +10 -9
  4. manim/_config/cli_colors.py +26 -9
  5. manim/_config/default.cfg +1 -3
  6. manim/_config/logger_utils.py +23 -13
  7. manim/_config/utils.py +662 -468
  8. manim/animation/animation.py +164 -18
  9. manim/animation/changing.py +34 -23
  10. manim/animation/composition.py +265 -67
  11. manim/animation/creation.py +208 -26
  12. manim/animation/fading.py +16 -18
  13. manim/animation/growing.py +35 -15
  14. manim/animation/indication.py +150 -76
  15. manim/animation/movement.py +56 -22
  16. manim/animation/numbers.py +64 -6
  17. manim/animation/rotation.py +78 -7
  18. manim/animation/specialized.py +6 -7
  19. manim/animation/speedmodifier.py +13 -10
  20. manim/animation/transform.py +14 -11
  21. manim/animation/transform_matching_parts.py +3 -4
  22. manim/animation/updaters/mobject_update_utils.py +152 -30
  23. manim/animation/updaters/update.py +10 -7
  24. manim/camera/camera.py +182 -118
  25. manim/camera/mapping_camera.py +34 -3
  26. manim/camera/moving_camera.py +95 -74
  27. manim/camera/multi_camera.py +23 -15
  28. manim/camera/three_d_camera.py +70 -52
  29. manim/cli/__init__.py +17 -0
  30. manim/cli/cfg/group.py +76 -44
  31. manim/cli/checkhealth/checks.py +192 -0
  32. manim/cli/checkhealth/commands.py +90 -0
  33. manim/cli/default_group.py +158 -25
  34. manim/cli/init/commands.py +33 -25
  35. manim/cli/plugins/commands.py +16 -3
  36. manim/cli/render/commands.py +72 -60
  37. manim/cli/render/ease_of_access_options.py +4 -3
  38. manim/cli/render/global_options.py +59 -17
  39. manim/cli/render/output_options.py +6 -5
  40. manim/cli/render/render_options.py +98 -33
  41. manim/constants.py +109 -59
  42. manim/data_structures.py +31 -0
  43. manim/mobject/frame.py +8 -5
  44. manim/mobject/geometry/__init__.py +1 -0
  45. manim/mobject/geometry/arc.py +277 -135
  46. manim/mobject/geometry/boolean_ops.py +32 -31
  47. manim/mobject/geometry/labeled.py +376 -0
  48. manim/mobject/geometry/line.py +192 -87
  49. manim/mobject/geometry/polygram.py +224 -58
  50. manim/mobject/geometry/shape_matchers.py +61 -25
  51. manim/mobject/geometry/tips.py +122 -48
  52. manim/mobject/graph.py +1027 -419
  53. manim/mobject/graphing/coordinate_systems.py +533 -278
  54. manim/mobject/graphing/functions.py +53 -32
  55. manim/mobject/graphing/number_line.py +123 -65
  56. manim/mobject/graphing/probability.py +88 -62
  57. manim/mobject/graphing/scale.py +33 -19
  58. manim/mobject/logo.py +118 -28
  59. manim/mobject/matrix.py +87 -83
  60. manim/mobject/mobject.py +912 -442
  61. manim/mobject/opengl/dot_cloud.py +16 -5
  62. manim/mobject/opengl/opengl_compatibility.py +4 -2
  63. manim/mobject/opengl/opengl_geometry.py +254 -153
  64. manim/mobject/opengl/opengl_image_mobject.py +3 -1
  65. manim/mobject/opengl/opengl_mobject.py +779 -482
  66. manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
  67. manim/mobject/opengl/opengl_surface.py +14 -92
  68. manim/mobject/opengl/opengl_three_dimensions.py +12 -8
  69. manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
  70. manim/mobject/svg/brace.py +173 -41
  71. manim/mobject/svg/svg_mobject.py +139 -53
  72. manim/mobject/table.py +61 -68
  73. manim/mobject/text/code_mobject.py +193 -539
  74. manim/mobject/text/numbers.py +81 -34
  75. manim/mobject/text/tex_mobject.py +130 -78
  76. manim/mobject/text/text_mobject.py +288 -164
  77. manim/mobject/three_d/polyhedra.py +111 -13
  78. manim/mobject/three_d/three_d_utils.py +17 -8
  79. manim/mobject/three_d/three_dimensions.py +239 -106
  80. manim/mobject/types/image_mobject.py +50 -30
  81. manim/mobject/types/point_cloud_mobject.py +120 -75
  82. manim/mobject/types/vectorized_mobject.py +841 -408
  83. manim/mobject/value_tracker.py +105 -38
  84. manim/mobject/vector_field.py +50 -31
  85. manim/opengl/__init__.py +3 -3
  86. manim/plugins/__init__.py +14 -1
  87. manim/plugins/plugins_flags.py +10 -14
  88. manim/renderer/cairo_renderer.py +65 -50
  89. manim/renderer/opengl_renderer.py +89 -69
  90. manim/renderer/opengl_renderer_window.py +39 -18
  91. manim/renderer/shader.py +123 -87
  92. manim/renderer/shader_wrapper.py +44 -28
  93. manim/renderer/vectorized_mobject_rendering.py +38 -10
  94. manim/scene/moving_camera_scene.py +32 -3
  95. manim/scene/scene.py +507 -242
  96. manim/scene/scene_file_writer.py +371 -220
  97. manim/scene/section.py +20 -16
  98. manim/scene/three_d_scene.py +14 -22
  99. manim/scene/vector_space_scene.py +223 -129
  100. manim/scene/zoomed_scene.py +46 -41
  101. manim/typing.py +990 -0
  102. manim/utils/bezier.py +1823 -371
  103. manim/utils/caching.py +12 -5
  104. manim/utils/color/AS2700.py +236 -0
  105. manim/utils/color/BS381.py +318 -0
  106. manim/utils/color/DVIPSNAMES.py +96 -0
  107. manim/utils/color/SVGNAMES.py +179 -0
  108. manim/utils/color/X11.py +533 -0
  109. manim/utils/color/XKCD.py +952 -0
  110. manim/utils/color/__init__.py +61 -0
  111. manim/utils/color/core.py +1667 -0
  112. manim/utils/color/manim_colors.py +218 -0
  113. manim/utils/commands.py +48 -20
  114. manim/utils/config_ops.py +39 -19
  115. manim/utils/debug.py +8 -7
  116. manim/utils/deprecation.py +86 -39
  117. manim/utils/docbuild/__init__.py +17 -0
  118. manim/utils/docbuild/autoaliasattr_directive.py +236 -0
  119. manim/utils/docbuild/autocolor_directive.py +99 -0
  120. manim/utils/docbuild/manim_directive.py +94 -41
  121. manim/utils/docbuild/module_parsing.py +245 -0
  122. manim/utils/exceptions.py +6 -0
  123. manim/utils/family.py +5 -3
  124. manim/utils/family_ops.py +17 -4
  125. manim/utils/file_ops.py +27 -17
  126. manim/utils/hashing.py +55 -45
  127. manim/utils/images.py +13 -7
  128. manim/utils/ipython_magic.py +13 -7
  129. manim/utils/iterables.py +163 -120
  130. manim/utils/module_ops.py +66 -24
  131. manim/utils/opengl.py +77 -24
  132. manim/utils/parameter_parsing.py +32 -0
  133. manim/utils/paths.py +30 -33
  134. manim/utils/polylabel.py +235 -0
  135. manim/utils/qhull.py +218 -0
  136. manim/utils/rate_functions.py +98 -32
  137. manim/utils/simple_functions.py +25 -33
  138. manim/utils/sounds.py +7 -1
  139. manim/utils/space_ops.py +188 -115
  140. manim/utils/testing/__init__.py +17 -0
  141. manim/utils/testing/_frames_testers.py +13 -8
  142. manim/utils/testing/_show_diff.py +5 -3
  143. manim/utils/testing/_test_class_makers.py +34 -18
  144. manim/utils/testing/frames_comparison.py +37 -19
  145. manim/utils/tex.py +130 -198
  146. manim/utils/tex_file_writing.py +77 -47
  147. manim/utils/tex_templates.py +2 -1
  148. manim/utils/unit.py +6 -5
  149. {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
  150. manim-0.19.1.dist-info/RECORD +220 -0
  151. {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
  152. manim-0.19.1.dist-info/entry_points.txt +3 -0
  153. {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
  154. manim/cli/new/group.py +0 -189
  155. manim/communitycolors.py +0 -9
  156. manim/gui/__init__.py +0 -0
  157. manim/gui/gui.py +0 -82
  158. manim/plugins/import_plugins.py +0 -43
  159. manim/utils/color.py +0 -552
  160. manim-0.17.0.dist-info/RECORD +0 -206
  161. manim-0.17.0.dist-info/entry_points.txt +0 -4
  162. /manim/cli/{new → checkhealth}/__init__.py +0 -0
  163. {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
@@ -70,29 +70,33 @@ __all__ = [
70
70
  "RemoveTextLetterByLetter",
71
71
  "ShowSubmobjectsOneByOne",
72
72
  "AddTextWordByWord",
73
+ "TypeWithCursor",
74
+ "UntypeWithCursor",
73
75
  ]
74
76
 
75
77
 
76
78
  import itertools as it
77
- from typing import TYPE_CHECKING, Callable, Iterable, Sequence
79
+ from collections.abc import Callable, Iterable, Sequence
80
+ from typing import TYPE_CHECKING
78
81
 
79
82
  import numpy as np
80
- from colour import Color
81
83
 
82
84
  if TYPE_CHECKING:
83
85
  from manim.mobject.text.text_mobject import Text
86
+ from manim.scene.scene import Scene
84
87
 
88
+ from manim.constants import RIGHT, TAU
85
89
  from manim.mobject.opengl.opengl_surface import OpenGLSurface
86
90
  from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
91
+ from manim.utils.color import ManimColor
87
92
 
88
93
  from .. import config
89
94
  from ..animation.animation import Animation
90
95
  from ..animation.composition import Succession
91
- from ..constants import TAU
92
96
  from ..mobject.mobject import Group, Mobject
93
97
  from ..mobject.types.vectorized_mobject import VMobject
94
98
  from ..utils.bezier import integer_interpolate
95
- from ..utils.rate_functions import double_smooth, linear, smooth
99
+ from ..utils.rate_functions import double_smooth, linear
96
100
 
97
101
 
98
102
  class ShowPartial(Animation):
@@ -116,7 +120,7 @@ class ShowPartial(Animation):
116
120
  ):
117
121
  pointwise = getattr(mobject, "pointwise_become_partial", None)
118
122
  if not callable(pointwise):
119
- raise NotImplementedError("This animation is not defined for this Mobject.")
123
+ raise TypeError(f"{self.__class__.__name__} only works for VMobjects.")
120
124
  super().__init__(mobject, **kwargs)
121
125
 
122
126
  def interpolate_submobject(
@@ -129,7 +133,7 @@ class ShowPartial(Animation):
129
133
  starting_submobject, *self._get_bounds(alpha)
130
134
  )
131
135
 
132
- def _get_bounds(self, alpha: float) -> None:
136
+ def _get_bounds(self, alpha: float) -> tuple[float, float]:
133
137
  raise NotImplementedError("Please use Create or ShowPassingFlash")
134
138
 
135
139
 
@@ -169,7 +173,7 @@ class Create(ShowPartial):
169
173
  ) -> None:
170
174
  super().__init__(mobject, lag_ratio=lag_ratio, introducer=introducer, **kwargs)
171
175
 
172
- def _get_bounds(self, alpha: float) -> tuple[int, float]:
176
+ def _get_bounds(self, alpha: float) -> tuple[float, float]:
173
177
  return (0, alpha)
174
178
 
175
179
 
@@ -225,8 +229,6 @@ class DrawBorderThenFill(Animation):
225
229
  rate_func: Callable[[float], float] = double_smooth,
226
230
  stroke_width: float = 2,
227
231
  stroke_color: str = None,
228
- draw_border_animation_config: dict = {}, # what does this dict accept?
229
- fill_animation_config: dict = {},
230
232
  introducer: bool = True,
231
233
  **kwargs,
232
234
  ) -> None:
@@ -240,13 +242,13 @@ class DrawBorderThenFill(Animation):
240
242
  )
241
243
  self.stroke_width = stroke_width
242
244
  self.stroke_color = stroke_color
243
- self.draw_border_animation_config = draw_border_animation_config
244
- self.fill_animation_config = fill_animation_config
245
245
  self.outline = self.get_outline()
246
246
 
247
247
  def _typecheck_input(self, vmobject: VMobject | OpenGLVMobject) -> None:
248
248
  if not isinstance(vmobject, (VMobject, OpenGLVMobject)):
249
- raise TypeError("DrawBorderThenFill only works for vectorized Mobjects")
249
+ raise TypeError(
250
+ f"{self.__class__.__name__} only works for vectorized Mobjects"
251
+ )
250
252
 
251
253
  def begin(self) -> None:
252
254
  self.outline = self.get_outline()
@@ -259,7 +261,7 @@ class DrawBorderThenFill(Animation):
259
261
  sm.set_stroke(color=self.get_stroke_color(sm), width=self.stroke_width)
260
262
  return outline
261
263
 
262
- def get_stroke_color(self, vmobject: VMobject | OpenGLVMobject) -> Color:
264
+ def get_stroke_color(self, vmobject: VMobject | OpenGLVMobject) -> ManimColor:
263
265
  if self.stroke_color:
264
266
  return self.stroke_color
265
267
  elif vmobject.get_stroke_width() > 0:
@@ -277,7 +279,7 @@ class DrawBorderThenFill(Animation):
277
279
  alpha: float,
278
280
  ) -> None: # Fixme: not matching the parent class? What is outline doing here?
279
281
  index: int
280
- subalpha: int
282
+ subalpha: float
281
283
  index, subalpha = integer_interpolate(0, 2, alpha)
282
284
  if index == 0:
283
285
  submobject.pointwise_become_partial(outline, 0, subalpha)
@@ -301,7 +303,7 @@ class Write(DrawBorderThenFill):
301
303
 
302
304
  class ShowWriteReversed(Scene):
303
305
  def construct(self):
304
- self.play(Write(Text("Hello", font_size=144), reverse=True))
306
+ self.play(Write(Text("Hello", font_size=144), reverse=True, remover=False))
305
307
 
306
308
  Tests
307
309
  -----
@@ -347,10 +349,7 @@ class Write(DrawBorderThenFill):
347
349
  ) -> tuple[float, float]:
348
350
  length = len(vmobject.family_members_with_points())
349
351
  if run_time is None:
350
- if length < 15:
351
- run_time = 1
352
- else:
353
- run_time = 2
352
+ run_time = 1 if length < 15 else 2
354
353
  if lag_ratio is None:
355
354
  lag_ratio = min(4.0 / max(1.0, length), 0.2)
356
355
  return run_time, lag_ratio
@@ -404,7 +403,6 @@ class Unwrite(Write):
404
403
  reverse: bool = True,
405
404
  **kwargs,
406
405
  ) -> None:
407
-
408
406
  run_time: float | None = kwargs.pop("run_time", None)
409
407
  lag_ratio: float | None = kwargs.pop("lag_ratio", None)
410
408
  run_time, lag_ratio = self._set_default_config_from_length(
@@ -457,7 +455,7 @@ class SpiralIn(Animation):
457
455
  fade_in_fraction=0.3,
458
456
  **kwargs,
459
457
  ) -> None:
460
- self.shapes = shapes
458
+ self.shapes = shapes.copy()
461
459
  self.scale_factor = scale_factor
462
460
  self.shape_center = shapes.get_center()
463
461
  self.fade_in_fraction = fade_in_fraction
@@ -474,15 +472,21 @@ class SpiralIn(Animation):
474
472
 
475
473
  def interpolate_mobject(self, alpha: float) -> None:
476
474
  alpha = self.rate_func(alpha)
477
- for shape in self.shapes:
475
+ for original_shape, shape in zip(self.shapes, self.mobject):
478
476
  shape.restore()
479
- shape.save_state()
480
- opacity = shape.get_fill_opacity()
481
- new_opacity = min(opacity, alpha * opacity / self.fade_in_fraction)
477
+ fill_opacity = original_shape.get_fill_opacity()
478
+ stroke_opacity = original_shape.get_stroke_opacity()
479
+ new_fill_opacity = min(
480
+ fill_opacity, alpha * fill_opacity / self.fade_in_fraction
481
+ )
482
+ new_stroke_opacity = min(
483
+ stroke_opacity, alpha * stroke_opacity / self.fade_in_fraction
484
+ )
482
485
  shape.shift((shape.final_position - shape.initial_position) * alpha)
483
486
  shape.rotate(TAU * alpha, about_point=self.shape_center)
484
487
  shape.rotate(-TAU * alpha, about_point=shape.get_center_of_mass())
485
- shape.set_opacity(new_opacity)
488
+ shape.set_fill(opacity=new_fill_opacity)
489
+ shape.set_stroke(opacity=new_stroke_opacity)
486
490
 
487
491
 
488
492
  class ShowIncreasingSubsets(Animation):
@@ -564,6 +568,11 @@ class AddTextLetterByLetter(ShowIncreasingSubsets):
564
568
  **kwargs,
565
569
  ) -> None:
566
570
  self.time_per_char = time_per_char
571
+ # Check for empty text using family_members_with_points()
572
+ if not text.family_members_with_points():
573
+ raise ValueError(
574
+ f"The text mobject {text} does not seem to contain any characters."
575
+ )
567
576
  if run_time is None:
568
577
  # minimum time per character is 1/frame_rate, otherwise
569
578
  # the animation does not finish.
@@ -664,3 +673,176 @@ class AddTextWordByWord(Succession):
664
673
  )
665
674
  )
666
675
  super().__init__(*anims, **kwargs)
676
+
677
+
678
+ class TypeWithCursor(AddTextLetterByLetter):
679
+ """Similar to :class:`~.AddTextLetterByLetter` , but with an additional cursor mobject at the end.
680
+
681
+ Parameters
682
+ ----------
683
+ time_per_char
684
+ Frequency of appearance of the letters.
685
+ cursor
686
+ :class:`~.Mobject` shown after the last added letter.
687
+ buff
688
+ Controls how far away the cursor is to the right of the last added letter.
689
+ keep_cursor_y
690
+ If ``True``, the cursor's y-coordinate is set to the center of the ``Text`` and remains the same throughout the animation. Otherwise, it is set to the center of the last added letter.
691
+ leave_cursor_on
692
+ Whether to show the cursor after the animation.
693
+
694
+ .. tip::
695
+ This is currently only possible for class:`~.Text` and not for class:`~.MathTex`.
696
+
697
+
698
+ Examples
699
+ --------
700
+
701
+ .. manim:: InsertingTextExample
702
+ :ref_classes: Blink
703
+
704
+ class InsertingTextExample(Scene):
705
+ def construct(self):
706
+ text = Text("Inserting", color=PURPLE).scale(1.5).to_edge(LEFT)
707
+ cursor = Rectangle(
708
+ color = GREY_A,
709
+ fill_color = GREY_A,
710
+ fill_opacity = 1.0,
711
+ height = 1.1,
712
+ width = 0.5,
713
+ ).move_to(text[0]) # Position the cursor
714
+
715
+ self.play(TypeWithCursor(text, cursor))
716
+ self.play(Blink(cursor, blinks=2))
717
+
718
+ """
719
+
720
+ def __init__(
721
+ self,
722
+ text: Text,
723
+ cursor: Mobject,
724
+ buff: float = 0.1,
725
+ keep_cursor_y: bool = True,
726
+ leave_cursor_on: bool = True,
727
+ time_per_char: float = 0.1,
728
+ reverse_rate_function=False,
729
+ introducer=True,
730
+ **kwargs,
731
+ ) -> None:
732
+ self.cursor = cursor
733
+ self.buff = buff
734
+ self.keep_cursor_y = keep_cursor_y
735
+ self.leave_cursor_on = leave_cursor_on
736
+ super().__init__(
737
+ text,
738
+ time_per_char=time_per_char,
739
+ reverse_rate_function=reverse_rate_function,
740
+ introducer=introducer,
741
+ **kwargs,
742
+ )
743
+
744
+ def begin(self) -> None:
745
+ self.y_cursor = self.cursor.get_y()
746
+ self.cursor.initial_position = self.mobject.get_center()
747
+ if self.keep_cursor_y:
748
+ self.cursor.set_y(self.y_cursor)
749
+
750
+ self.cursor.set_opacity(0)
751
+ self.mobject.add(self.cursor)
752
+ super().begin()
753
+
754
+ def finish(self) -> None:
755
+ if self.leave_cursor_on:
756
+ self.cursor.set_opacity(1)
757
+ else:
758
+ self.cursor.set_opacity(0)
759
+ self.mobject.remove(self.cursor)
760
+ super().finish()
761
+
762
+ def clean_up_from_scene(self, scene: Scene) -> None:
763
+ if not self.leave_cursor_on:
764
+ scene.remove(self.cursor)
765
+ super().clean_up_from_scene(scene)
766
+
767
+ def update_submobject_list(self, index: int) -> None:
768
+ for mobj in self.all_submobs[:index]:
769
+ mobj.set_opacity(1)
770
+
771
+ for mobj in self.all_submobs[index:]:
772
+ mobj.set_opacity(0)
773
+
774
+ if index != 0:
775
+ self.cursor.next_to(
776
+ self.all_submobs[index - 1], RIGHT, buff=self.buff
777
+ ).set_y(self.cursor.initial_position[1])
778
+ else:
779
+ self.cursor.move_to(self.all_submobs[0]).set_y(
780
+ self.cursor.initial_position[1]
781
+ )
782
+
783
+ if self.keep_cursor_y:
784
+ self.cursor.set_y(self.y_cursor)
785
+ self.cursor.set_opacity(1)
786
+
787
+
788
+ class UntypeWithCursor(TypeWithCursor):
789
+ """Similar to :class:`~.RemoveTextLetterByLetter` , but with an additional cursor mobject at the end.
790
+
791
+ Parameters
792
+ ----------
793
+ time_per_char
794
+ Frequency of appearance of the letters.
795
+ cursor
796
+ :class:`~.Mobject` shown after the last added letter.
797
+ buff
798
+ Controls how far away the cursor is to the right of the last added letter.
799
+ keep_cursor_y
800
+ If ``True``, the cursor's y-coordinate is set to the center of the ``Text`` and remains the same throughout the animation. Otherwise, it is set to the center of the last added letter.
801
+ leave_cursor_on
802
+ Whether to show the cursor after the animation.
803
+
804
+ .. tip::
805
+ This is currently only possible for class:`~.Text` and not for class:`~.MathTex`.
806
+
807
+
808
+ Examples
809
+ --------
810
+
811
+ .. manim:: DeletingTextExample
812
+ :ref_classes: Blink
813
+
814
+ class DeletingTextExample(Scene):
815
+ def construct(self):
816
+ text = Text("Deleting", color=PURPLE).scale(1.5).to_edge(LEFT)
817
+ cursor = Rectangle(
818
+ color = GREY_A,
819
+ fill_color = GREY_A,
820
+ fill_opacity = 1.0,
821
+ height = 1.1,
822
+ width = 0.5,
823
+ ).move_to(text[0]) # Position the cursor
824
+
825
+ self.play(UntypeWithCursor(text, cursor))
826
+ self.play(Blink(cursor, blinks=2))
827
+
828
+ """
829
+
830
+ def __init__(
831
+ self,
832
+ text: Text,
833
+ cursor: VMobject | None = None,
834
+ time_per_char: float = 0.1,
835
+ reverse_rate_function=True,
836
+ introducer=False,
837
+ remover=True,
838
+ **kwargs,
839
+ ) -> None:
840
+ super().__init__(
841
+ text,
842
+ cursor=cursor,
843
+ time_per_char=time_per_char,
844
+ reverse_rate_function=reverse_rate_function,
845
+ introducer=introducer,
846
+ remover=remover,
847
+ **kwargs,
848
+ )
manim/animation/fading.py CHANGED
@@ -12,7 +12,6 @@
12
12
 
13
13
  """
14
14
 
15
-
16
15
  from __future__ import annotations
17
16
 
18
17
  __all__ = [
@@ -20,6 +19,8 @@ __all__ = [
20
19
  "FadeIn",
21
20
  ]
22
21
 
22
+ from typing import Any
23
+
23
24
  import numpy as np
24
25
 
25
26
  from manim.mobject.opengl.opengl_mobject import OpenGLMobject
@@ -54,14 +55,11 @@ class _Fade(Transform):
54
55
  shift: np.ndarray | None = None,
55
56
  target_position: np.ndarray | Mobject | None = None,
56
57
  scale: float = 1,
57
- **kwargs,
58
+ **kwargs: Any,
58
59
  ) -> None:
59
60
  if not mobjects:
60
61
  raise ValueError("At least one mobject must be passed.")
61
- if len(mobjects) == 1:
62
- mobject = mobjects[0]
63
- else:
64
- mobject = Group(*mobjects)
62
+ mobject = mobjects[0] if len(mobjects) == 1 else Group(*mobjects)
65
63
 
66
64
  self.point_target = False
67
65
  if shift is None:
@@ -89,7 +87,7 @@ class _Fade(Transform):
89
87
  Mobject
90
88
  The faded, shifted and scaled copy of the mobject.
91
89
  """
92
- faded_mobject = self.mobject.copy()
90
+ faded_mobject: Mobject = self.mobject.copy() # type: ignore[assignment]
93
91
  faded_mobject.fade(1)
94
92
  direction_modifier = -1 if fadeIn and not self.point_target else 1
95
93
  faded_mobject.shift(self.shift_vector * direction_modifier)
@@ -98,7 +96,7 @@ class _Fade(Transform):
98
96
 
99
97
 
100
98
  class FadeIn(_Fade):
101
- """Fade in :class:`~.Mobject` s.
99
+ r"""Fade in :class:`~.Mobject` s.
102
100
 
103
101
  Parameters
104
102
  ----------
@@ -123,7 +121,7 @@ class FadeIn(_Fade):
123
121
  dot = Dot(UP * 2 + LEFT)
124
122
  self.add(dot)
125
123
  tex = Tex(
126
- "FadeIn with ", "shift ", " or target\\_position", " and scale"
124
+ "FadeIn with ", "shift ", r" or target\_position", " and scale"
127
125
  ).scale(1)
128
126
  animations = [
129
127
  FadeIn(tex[0]),
@@ -135,18 +133,18 @@ class FadeIn(_Fade):
135
133
 
136
134
  """
137
135
 
138
- def __init__(self, *mobjects: Mobject, **kwargs) -> None:
136
+ def __init__(self, *mobjects: Mobject, **kwargs: Any) -> None:
139
137
  super().__init__(*mobjects, introducer=True, **kwargs)
140
138
 
141
- def create_target(self):
142
- return self.mobject
139
+ def create_target(self) -> Mobject:
140
+ return self.mobject # type: ignore[return-value]
143
141
 
144
- def create_starting_mobject(self):
142
+ def create_starting_mobject(self) -> Mobject:
145
143
  return self._create_faded_mobject(fadeIn=True)
146
144
 
147
145
 
148
146
  class FadeOut(_Fade):
149
- """Fade out :class:`~.Mobject` s.
147
+ r"""Fade out :class:`~.Mobject` s.
150
148
 
151
149
  Parameters
152
150
  ----------
@@ -170,7 +168,7 @@ class FadeOut(_Fade):
170
168
  dot = Dot(UP * 2 + LEFT)
171
169
  self.add(dot)
172
170
  tex = Tex(
173
- "FadeOut with ", "shift ", " or target\\_position", " and scale"
171
+ "FadeOut with ", "shift ", r" or target\_position", " and scale"
174
172
  ).scale(1)
175
173
  animations = [
176
174
  FadeOut(tex[0]),
@@ -183,12 +181,12 @@ class FadeOut(_Fade):
183
181
 
184
182
  """
185
183
 
186
- def __init__(self, *mobjects: Mobject, **kwargs) -> None:
184
+ def __init__(self, *mobjects: Mobject, **kwargs: Any) -> None:
187
185
  super().__init__(*mobjects, remover=True, **kwargs)
188
186
 
189
- def create_target(self):
187
+ def create_target(self) -> Mobject:
190
188
  return self._create_faded_mobject(fadeIn=False)
191
189
 
192
- def clean_up_from_scene(self, scene: Scene = None) -> None:
190
+ def clean_up_from_scene(self, scene: Scene) -> None:
193
191
  super().clean_up_from_scene(scene)
194
192
  self.interpolate(0)
@@ -31,16 +31,17 @@ __all__ = [
31
31
  "SpinInFromNothing",
32
32
  ]
33
33
 
34
- import typing
35
-
36
- import numpy as np
34
+ from typing import TYPE_CHECKING, Any
37
35
 
38
36
  from ..animation.transform import Transform
39
37
  from ..constants import PI
40
38
  from ..utils.paths import spiral_path
41
39
 
42
- if typing.TYPE_CHECKING:
40
+ if TYPE_CHECKING:
43
41
  from manim.mobject.geometry.line import Arrow
42
+ from manim.mobject.opengl.opengl_mobject import OpenGLMobject
43
+ from manim.typing import Point3DLike, Vector3DLike
44
+ from manim.utils.color import ParsableManimColor
44
45
 
45
46
  from ..mobject.mobject import Mobject
46
47
 
@@ -76,16 +77,20 @@ class GrowFromPoint(Transform):
76
77
  """
77
78
 
78
79
  def __init__(
79
- self, mobject: Mobject, point: np.ndarray, point_color: str = None, **kwargs
80
- ) -> None:
80
+ self,
81
+ mobject: Mobject,
82
+ point: Point3DLike,
83
+ point_color: ParsableManimColor | None = None,
84
+ **kwargs: Any,
85
+ ):
81
86
  self.point = point
82
87
  self.point_color = point_color
83
88
  super().__init__(mobject, introducer=True, **kwargs)
84
89
 
85
- def create_target(self) -> Mobject:
90
+ def create_target(self) -> Mobject | OpenGLMobject:
86
91
  return self.mobject
87
92
 
88
- def create_starting_mobject(self) -> Mobject:
93
+ def create_starting_mobject(self) -> Mobject | OpenGLMobject:
89
94
  start = super().create_starting_mobject()
90
95
  start.scale(0)
91
96
  start.move_to(self.point)
@@ -118,7 +123,12 @@ class GrowFromCenter(GrowFromPoint):
118
123
 
119
124
  """
120
125
 
121
- def __init__(self, mobject: Mobject, point_color: str = None, **kwargs) -> None:
126
+ def __init__(
127
+ self,
128
+ mobject: Mobject,
129
+ point_color: ParsableManimColor | None = None,
130
+ **kwargs: Any,
131
+ ):
122
132
  point = mobject.get_center()
123
133
  super().__init__(mobject, point, point_color=point_color, **kwargs)
124
134
 
@@ -153,8 +163,12 @@ class GrowFromEdge(GrowFromPoint):
153
163
  """
154
164
 
155
165
  def __init__(
156
- self, mobject: Mobject, edge: np.ndarray, point_color: str = None, **kwargs
157
- ) -> None:
166
+ self,
167
+ mobject: Mobject,
168
+ edge: Vector3DLike,
169
+ point_color: ParsableManimColor | None = None,
170
+ **kwargs: Any,
171
+ ):
158
172
  point = mobject.get_critical_point(edge)
159
173
  super().__init__(mobject, point, point_color=point_color, **kwargs)
160
174
 
@@ -183,11 +197,13 @@ class GrowArrow(GrowFromPoint):
183
197
 
184
198
  """
185
199
 
186
- def __init__(self, arrow: Arrow, point_color: str = None, **kwargs) -> None:
200
+ def __init__(
201
+ self, arrow: Arrow, point_color: ParsableManimColor | None = None, **kwargs: Any
202
+ ):
187
203
  point = arrow.get_start()
188
204
  super().__init__(arrow, point, point_color=point_color, **kwargs)
189
205
 
190
- def create_starting_mobject(self) -> Mobject:
206
+ def create_starting_mobject(self) -> Mobject | OpenGLMobject:
191
207
  start_arrow = self.mobject.copy()
192
208
  start_arrow.scale(0, scale_tips=True, about_point=self.point)
193
209
  if self.point_color:
@@ -224,8 +240,12 @@ class SpinInFromNothing(GrowFromCenter):
224
240
  """
225
241
 
226
242
  def __init__(
227
- self, mobject: Mobject, angle: float = PI / 2, point_color: str = None, **kwargs
228
- ) -> None:
243
+ self,
244
+ mobject: Mobject,
245
+ angle: float = PI / 2,
246
+ point_color: ParsableManimColor | None = None,
247
+ **kwargs: Any,
248
+ ):
229
249
  self.angle = angle
230
250
  super().__init__(
231
251
  mobject, path_func=spiral_path(angle), point_color=point_color, **kwargs