Kill CONFIG in indication.py

This commit is contained in:
Grant Sanderson 2022-12-14 14:40:05 -08:00
parent a901704b31
commit 7dcf5eff8e

View file

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import math import math
from os import remove
import numpy as np import numpy as np
from manimlib.animation.animation import Animation from manimlib.animation.animation import Animation
@ -15,6 +16,7 @@ from manimlib.animation.transform import Transform
from manimlib.constants import FRAME_X_RADIUS, FRAME_Y_RADIUS from manimlib.constants import FRAME_X_RADIUS, FRAME_Y_RADIUS
from manimlib.constants import ORIGIN, RIGHT, UP from manimlib.constants import ORIGIN, RIGHT, UP
from manimlib.constants import SMALL_BUFF from manimlib.constants import SMALL_BUFF
from manimlib.constants import DEGREES
from manimlib.constants import TAU from manimlib.constants import TAU
from manimlib.constants import GREY, YELLOW from manimlib.constants import GREY, YELLOW
from manimlib.mobject.geometry import Circle from manimlib.mobject.geometry import Circle
@ -34,30 +36,32 @@ from manimlib.utils.rate_functions import wiggle
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Callable
from manimlib.constants import ManimColor from manimlib.constants import ManimColor
from manimlib.mobject.mobject import Mobject from manimlib.mobject.mobject import Mobject
class FocusOn(Transform): class FocusOn(Transform):
CONFIG = { def __init__(
"opacity": 0.2, self,
"color": GREY, focus_point: np.ndarray | Mobject,
"run_time": 2, opacity: float = 0.2,
"remover": True, color: ManimColor = GREY,
} run_time: float = 2,
remover: bool = True,
def __init__(self, focus_point: np.ndarray, **kwargs): **kwargs
):
self.focus_point = focus_point self.focus_point = focus_point
self.opacity = opacity
self.color = color
# Initialize with blank mobject, while create_target # Initialize with blank mobject, while create_target
# and create_starting_mobject handle the meat # and create_starting_mobject handle the meat
super().__init__(VMobject(), **kwargs) super().__init__(VMobject(), run_time=run_time, remover=remover, **kwargs)
def create_target(self) -> Dot: def create_target(self) -> Dot:
little_dot = Dot(radius=0) little_dot = Dot(radius=0)
little_dot.set_fill(self.color, opacity=self.opacity) little_dot.set_fill(self.color, opacity=self.opacity)
little_dot.add_updater( little_dot.add_updater(lambda d: d.move_to(self.focus_point))
lambda d: d.move_to(self.focus_point)
)
return little_dot return little_dot
def create_starting_mobject(self) -> Dot: def create_starting_mobject(self) -> Dot:
@ -70,11 +74,17 @@ class FocusOn(Transform):
class Indicate(Transform): class Indicate(Transform):
CONFIG = { def __init__(
"rate_func": there_and_back, self,
"scale_factor": 1.2, mobject: Mobject,
"color": YELLOW, scale_factor: float = 1.2,
} color: ManimColor = YELLOW,
rate_func: Callable[[float], float] = there_and_back,
**kwargs
):
self.scale_factor = scale_factor
self.color = color
super().__init__(mobject, rate_func=rate_func, **kwargs)
def create_target(self) -> Mobject: def create_target(self) -> Mobject:
target = self.mobject.copy() target = self.mobject.copy()
@ -84,28 +94,30 @@ class Indicate(Transform):
class Flash(AnimationGroup): class Flash(AnimationGroup):
CONFIG = {
"line_length": 0.2,
"num_lines": 12,
"flash_radius": 0.3,
"line_stroke_width": 3,
"run_time": 1,
}
def __init__( def __init__(
self, self,
point: np.ndarray, point: np.ndarray | Mobject,
color: ManimColor = YELLOW, color: ManimColor = YELLOW,
line_length: float = 0.2,
num_lines: int = 12,
flash_radius: float = 0.3,
line_stroke_width: float = 3.0,
run_time: float = 1.0,
**kwargs **kwargs
): ):
self.point = point self.point = point
self.color = color self.color = color
digest_config(self, kwargs) self.line_length = line_length
self.num_lines = num_lines
self.flash_radius = flash_radius
self.line_stroke_width = line_stroke_width
self.lines = self.create_lines() self.lines = self.create_lines()
animations = self.create_line_anims() animations = self.create_line_anims()
super().__init__( super().__init__(
*animations, *animations,
group=self.lines, group=self.lines,
run_time=run_time,
**kwargs, **kwargs,
) )
@ -130,35 +142,43 @@ class Flash(AnimationGroup):
] ]
class CircleIndicate(Indicate): class CircleIndicate(Transform):
CONFIG = { def __init__(
"rate_func": there_and_back, self,
"remover": True, mobject: Mobject,
"circle_config": { scale_factor: float = 1.2,
"color": YELLOW, rate_func: Callable[[float], float] = there_and_back,
}, stroke_color: ManimColor = YELLOW,
} stroke_width: float = 3.0,
remover: bool = True,
def __init__(self, mobject: Mobject, **kwargs): **kwargs
digest_config(self, kwargs) ):
circle = self.get_circle(mobject) circle = Circle(stroke_color=stroke_color, stroke_width=stroke_width)
super().__init__(circle, **kwargs) circle.surround(mobject)
pre_circle = circle.copy().set_stroke(width=0)
def get_circle(self, mobject: Mobject) -> Circle: pre_circle.scale(1 / scale_factor)
circle = Circle(**self.circle_config) super().__init__(
circle.add_updater(lambda c: c.surround(mobject)) pre_circle, circle,
return circle rate_func=rate_func,
remover=remover,
def interpolate_mobject(self, alpha: float) -> None: **kwargs
super().interpolate_mobject(alpha) )
self.mobject.set_stroke(opacity=alpha)
class ShowPassingFlash(ShowPartial): class ShowPassingFlash(ShowPartial):
CONFIG = { def __init__(
"time_width": 0.1, self,
"remover": True, mobject: Mobject,
} time_width: float = 0.1,
remover: bool = True,
**kwargs
):
self.time_width = time_width
super().__init__(
mobject,
remover=remover,
**kwargs
)
def get_bounds(self, alpha: float) -> tuple[float, float]: def get_bounds(self, alpha: float) -> tuple[float, float]:
tw = self.time_width tw = self.time_width
@ -175,11 +195,17 @@ class ShowPassingFlash(ShowPartial):
class VShowPassingFlash(Animation): class VShowPassingFlash(Animation):
CONFIG = { def __init__(
"time_width": 0.3, self,
"taper_width": 0.02, vmobject: VMobject,
"remover": True, time_width: float = 0.3,
} taper_width: float = 0.02,
remover: bool = True,
**kwargs
):
self.time_width = time_width
self.taper_width = taper_width
super().__init__(vmobject, remover=remover, **kwargs)
def begin(self) -> None: def begin(self) -> None:
self.mobject.align_stroke_width_data_to_points() self.mobject.align_stroke_width_data_to_points()
@ -235,112 +261,94 @@ class VShowPassingFlash(Animation):
class FlashAround(VShowPassingFlash): class FlashAround(VShowPassingFlash):
CONFIG = { def __init__(
"stroke_width": 4.0, self,
"color": YELLOW, mobject: Mobject,
"buff": SMALL_BUFF, time_width: float = 1.0,
"time_width": 1.0, stroke_width: float = 4.0,
"n_inserted_curves": 20, color: ManimColor = YELLOW,
} buff: float = SMALL_BUFF,
n_inserted_curves: int = 20,
def __init__(self, mobject: Mobject, **kwargs): **kwargs
digest_config(self, kwargs) ):
path = self.get_path(mobject) path = self.get_path(mobject, buff)
if mobject.is_fixed_in_frame: if mobject.is_fixed_in_frame:
path.fix_in_frame() path.fix_in_frame()
path.insert_n_curves(self.n_inserted_curves) path.insert_n_curves(n_inserted_curves)
path.set_points(path.get_points_without_null_curves()) path.set_points(path.get_points_without_null_curves())
path.set_stroke(self.color, self.stroke_width) path.set_stroke(color, stroke_width)
super().__init__(path, **kwargs) super().__init__(path, time_width=time_width, **kwargs)
def get_path(self, mobject: Mobject) -> SurroundingRectangle: def get_path(self, mobject: Mobject, buff: float) -> SurroundingRectangle:
return SurroundingRectangle(mobject, buff=self.buff) return SurroundingRectangle(mobject, buff=buff)
class FlashUnder(FlashAround): class FlashUnder(FlashAround):
def get_path(self, mobject: Mobject) -> Underline: def get_path(self, mobject: Mobject, buff: float) -> Underline:
return Underline(mobject, buff=self.buff) return Underline(mobject, buff=buff)
class ShowCreationThenDestruction(ShowPassingFlash): class ShowCreationThenDestruction(ShowPassingFlash):
CONFIG = { def __init__(self, vmobject: VMobject, time_width: float = 2.0, **kwargs):
"time_width": 2.0, super().__init__(vmobject, time_width=time_width, **kwargs)
"run_time": 1,
}
class ShowCreationThenFadeOut(Succession): class ShowCreationThenFadeOut(Succession):
CONFIG = { def __init__(self, mobject: Mobject, remover: bool = True, **kwargs):
"remover": True,
}
def __init__(self, mobject: Mobject, **kwargs):
super().__init__( super().__init__(
ShowCreation(mobject), ShowCreation(mobject),
FadeOut(mobject), FadeOut(mobject),
remover=remover,
**kwargs **kwargs
) )
class AnimationOnSurroundingRectangle(AnimationGroup): class AnimationOnSurroundingRectangle(AnimationGroup):
CONFIG = { RectAnimationType: type = Animation
"surrounding_rectangle_config": {},
# Function which takes in a rectangle, and spits
# out some animation. Could be some animation class,
# could be something more
"rect_animation": Animation
}
def __init__(self, mobject: Mobject, **kwargs): def __init__(
digest_config(self, kwargs) self,
if "surrounding_rectangle_config" in kwargs: mobject: Mobject,
kwargs.pop("surrounding_rectangle_config") stroke_width: float = 2.0,
self.mobject_to_surround = mobject stroke_color: ManimColor = YELLOW,
buff: float = SMALL_BUFF,
rect = self.get_rect() **kwargs
):
rect = SurroundingRectangle(
mobject,
stroke_width=stroke_width,
stroke_color=stroke_color,
buff=buff,
)
rect.add_updater(lambda r: r.move_to(mobject)) rect.add_updater(lambda r: r.move_to(mobject))
super().__init__(self.RectAnimationType(rect, **kwargs))
super().__init__(
self.rect_animation(rect, **kwargs),
)
def get_rect(self) -> SurroundingRectangle:
return SurroundingRectangle(
self.mobject_to_surround,
**self.surrounding_rectangle_config
)
class ShowPassingFlashAround(AnimationOnSurroundingRectangle): class ShowPassingFlashAround(AnimationOnSurroundingRectangle):
CONFIG = { RectAnimationType = ShowPassingFlash
"rect_animation": ShowPassingFlash
}
class ShowCreationThenDestructionAround(AnimationOnSurroundingRectangle): class ShowCreationThenDestructionAround(AnimationOnSurroundingRectangle):
CONFIG = { RectAnimationType = ShowCreationThenDestruction
"rect_animation": ShowCreationThenDestruction
}
class ShowCreationThenFadeAround(AnimationOnSurroundingRectangle): class ShowCreationThenFadeAround(AnimationOnSurroundingRectangle):
CONFIG = { RectAnimationType = ShowCreationThenFadeOut
"rect_animation": ShowCreationThenFadeOut
}
class ApplyWave(Homotopy): class ApplyWave(Homotopy):
CONFIG = { def __init__(
"direction": UP, self,
"amplitude": 0.2, mobject: Mobject,
"run_time": 1, direction: np.ndarray = UP,
} amplitude: float = 0.2,
run_time: float = 1.0,
**kwargs
):
def __init__(self, mobject: Mobject, **kwargs):
digest_config(self, kwargs, locals())
left_x = mobject.get_left()[0] left_x = mobject.get_left()[0]
right_x = mobject.get_right()[0] right_x = mobject.get_right()[0]
vect = self.amplitude * self.direction vect = amplitude * direction
def homotopy(x, y, z, t): def homotopy(x, y, z, t):
alpha = (x - left_x) / (right_x - left_x) alpha = (x - left_x) / (right_x - left_x)
@ -352,22 +360,29 @@ class ApplyWave(Homotopy):
class WiggleOutThenIn(Animation): class WiggleOutThenIn(Animation):
CONFIG = { def __init__(
"scale_value": 1.1, self,
"rotation_angle": 0.01 * TAU, mobject: Mobject,
"n_wiggles": 6, scale_value: float = 1.1,
"run_time": 2, rotation_angle: float = 0.01 * TAU,
"scale_about_point": None, n_wiggles: int = 6,
"rotate_about_point": None, scale_about_point: np.ndarray | None = None,
} rotate_about_point: np.ndarray | None = None,
run_time: float = 2,
**kwargs
):
self.scale_value = scale_value
self.rotation_angle = rotation_angle
self.n_wiggles = n_wiggles
self.scale_about_point = scale_about_point
self.rotate_about_point = rotate_about_point
super().__init__(mobject, run_time=run_time, **kwargs)
def get_scale_about_point(self) -> np.ndarray: def get_scale_about_point(self) -> np.ndarray:
if self.scale_about_point is None: return self.scale_about_point or self.mobject.get_center()
return self.mobject.get_center()
def get_rotate_about_point(self) -> np.ndarray: def get_rotate_about_point(self) -> np.ndarray:
if self.rotate_about_point is None: return self.rotate_about_point or self.mobject.get_center()
return self.mobject.get_center()
def interpolate_submobject( def interpolate_submobject(
self, self,
@ -387,28 +402,32 @@ class WiggleOutThenIn(Animation):
class TurnInsideOut(Transform): class TurnInsideOut(Transform):
CONFIG = { def __init__(self, mobject: Mobject, path_arc: float = 90 * DEGREES, **kwargs):
"path_arc": TAU / 4, super().__init__(mobject, path_arc=path_arc, **kwargs)
}
def create_target(self) -> Mobject: def create_target(self) -> Mobject:
return self.mobject.copy().reverse_points() result = self.mobject.copy().reverse_points()
if isinstance(result, VMobject):
result.refresh_unit_normal()
result.refresh_triangulation()
return result
class FlashyFadeIn(AnimationGroup): class FlashyFadeIn(AnimationGroup):
CONFIG = { def __init__(self,
"fade_lag": 0, vmobject: VMobject,
} stroke_width: float = 2.0,
fade_lag: float = 0.0,
def __init__(self, vmobject: VMobject, stroke_width: float = 2, **kwargs): time_width: float = 1.0,
digest_config(self, kwargs) **kwargs
):
outline = vmobject.copy() outline = vmobject.copy()
outline.set_fill(opacity=0) outline.set_fill(opacity=0)
outline.set_stroke(width=stroke_width, opacity=1) outline.set_stroke(width=stroke_width, opacity=1)
rate_func = kwargs.get("rate_func", smooth) rate_func = kwargs.get("rate_func", smooth)
super().__init__( super().__init__(
FadeIn(vmobject, rate_func=squish_rate_func(rate_func, self.fade_lag, 1)), FadeIn(vmobject, rate_func=squish_rate_func(rate_func, fade_lag, 1)),
VShowPassingFlash(outline, time_width=1), VShowPassingFlash(outline, time_width=time_width),
**kwargs **kwargs
) )