diff --git a/big_ol_pile_of_manim_imports.py b/big_ol_pile_of_manim_imports.py index 746936c2..0b7334ec 100644 --- a/big_ol_pile_of_manim_imports.py +++ b/big_ol_pile_of_manim_imports.py @@ -35,6 +35,7 @@ from manimlib.camera.moving_camera import * from manimlib.camera.three_d_camera import * from manimlib.mobject.coordinate_systems import * +from manimlib.mobject.changing import * from manimlib.mobject.frame import * from manimlib.mobject.functions import * from manimlib.mobject.geometry import * diff --git a/manimlib/mobject/changing.py b/manimlib/mobject/changing.py new file mode 100644 index 00000000..185026e9 --- /dev/null +++ b/manimlib/mobject/changing.py @@ -0,0 +1,60 @@ +import warnings + +from manimlib.constants import * +from manimlib.mobject.types.vectorized_mobject import VGroup +from manimlib.mobject.types.vectorized_mobject import VMobject +from manimlib.utils.rate_functions import smooth + +POINTLESS_VMOBJECT_WARNING = """ + +Calling AnimatedBoundary on a VMobject with no points. +""" + + +class AnimatedBoundary(VGroup): + CONFIG = { + "colors": [BLUE_D, BLUE_B, BLUE_E, GREY_BROWN], + "max_stroke_width": 3, + "cycle_rate": 0.5, + } + + def __init__(self, vmobject, **kwargs): + super().__init__(**kwargs) + if len(vmobject.points) == 0: + warnings.warn(POINTLESS_VMOBJECT_WARNING) + self.vmobject = vmobject + self.boundary_copies = [ + VMobject(stroke_width=0, fill_opacity=0) + for x in range(2) + ] + self.add(*self.boundary_copies) + self.total_time = 0 + self.add_updater(lambda m, dt: self.update(dt)) + + def update(self, dt): + # Not actual time, but something which passes at + # an altered rate to make the implementation below + # cleaner + time = self.total_time * self.cycle_rate + growing, fading = self.boundary_copies + colors = self.colors + msw = self.max_stroke_width + + index = int(time % len(colors)) + alpha = smooth(time % 1) + + if int(time) % 2 == 0: + bounds = (0, alpha) + else: + bounds = (1 - alpha, 1) + growing.pointwise_become_partial(self.vmobject, *bounds) + growing.set_stroke(colors[index], width=msw) + + if time > 1: + fading.pointwise_become_partial(self.vmobject, 0, 1) + fading.set_stroke( + color=colors[index - 1], + width=(1 - alpha) * msw + ) + + self.total_time += dt