Updates to (some) indication animations

This commit is contained in:
Grant Sanderson 2019-02-09 12:07:33 -08:00
parent 69cf682f07
commit 14b9db61b9

View file

@ -9,10 +9,13 @@ from manimlib.animation.composition import AnimationGroup
from manimlib.animation.composition import Succession
from manimlib.animation.creation import ShowCreation
from manimlib.animation.creation import ShowPartial
from manimlib.animation.fading import FadeIn
from manimlib.animation.fading import FadeOut
from manimlib.animation.transform import Transform
from manimlib.animation.update import UpdateFromAlphaFunc
from manimlib.mobject.updater import updating_mobject_from_func
from manimlib.mobject.mobject import Mobject
from manimlib.mobject.types.vectorized_mobject import VMobject
from manimlib.mobject.geometry import Circle
from manimlib.mobject.geometry import Dot
from manimlib.mobject.shape_matchers import SurroundingRectangle
@ -35,19 +38,27 @@ class FocusOn(Transform):
"remover": True,
}
def __init__(self, mobject_or_point, **kwargs):
digest_config(self, kwargs)
big_dot = Dot(
def __init__(self, focus_point, **kwargs):
self.focus_point = focus_point
# Initialize with blank mobject, while create_target
# and create_starting_mobject handle the meat
super().__init__(VMobject(), **kwargs)
def create_target(self):
little_dot = Dot(radius=0)
little_dot.set_fill(self.color, opacity=self.opacity)
little_dot.add_updater(
lambda d: d.move_to(self.focus_point)
)
return little_dot
def create_starting_mobject(self):
return Dot(
radius=FRAME_X_RADIUS + FRAME_Y_RADIUS,
stroke_width=0,
fill_color=self.color,
fill_opacity=0,
)
little_dot = Dot(radius=0)
little_dot.set_fill(self.color, opacity=self.opacity)
little_dot.move_to(mobject_or_point)
Transform.__init__(self, big_dot, little_dot, **kwargs)
class Indicate(Transform):
@ -57,12 +68,11 @@ class Indicate(Transform):
"color": YELLOW,
}
def __init__(self, mobject, **kwargs):
digest_config(self, kwargs)
target = mobject.copy()
def create_target(self):
target = self.mobject.copy()
target.scale_in_place(self.scale_factor)
target.set_color(self.color)
Transform.__init__(self, mobject, target, **kwargs)
return target
class Flash(AnimationGroup):
@ -71,51 +81,62 @@ class Flash(AnimationGroup):
"num_lines": 12,
"flash_radius": 0.3,
"line_stroke_width": 3,
"run_time": 1,
}
def __init__(self, point, color=YELLOW, **kwargs):
self.point = point
self.color = color
digest_config(self, kwargs)
self.lines = self.create_lines()
animations = self.create_line_anims()
super().__init__(
*animations,
group=self.lines,
**kwargs,
)
def create_lines(self):
lines = VGroup()
for angle in np.arange(0, TAU, TAU / self.num_lines):
line = Line(ORIGIN, self.line_length * RIGHT)
line.shift((self.flash_radius - self.line_length) * RIGHT)
line.rotate(angle, about_point=ORIGIN)
lines.add(line)
lines.move_to(point)
lines.set_color(color)
lines.set_color(self.color)
lines.set_stroke(width=3)
line_anims = [
ShowCreationThenDestruction(
line, rate_func=squish_rate_func(smooth, 0, 0.5)
)
for line in lines
]
fade_anims = [
UpdateFromAlphaFunc(
line, lambda m, a: m.set_stroke(
width=self.line_stroke_width * (1 - a)
),
rate_func=squish_rate_func(smooth, 0, 0.75)
)
for line in lines
]
lines.add_updater(lambda l: l.move_to(self.point))
return lines
AnimationGroup.__init__(
self, *line_anims + fade_anims, **kwargs
)
def create_line_anims(self):
return [
ShowCreationThenDestruction(line)
for line in self.lines
]
class CircleIndicate(Indicate):
CONFIG = {
"rate_func": squish_rate_func(there_and_back, 0, 0.8),
"remover": True
"rate_func": there_and_back,
"remover": True,
"circle_config": {
"color": YELLOW,
},
}
def __init__(self, mobject, **kwargs):
digest_config(self, kwargs)
circle = Circle(color=self.color, **kwargs)
circle.surround(mobject)
Indicate.__init__(self, circle, **kwargs)
circle = self.get_circle(mobject)
super().__init__(circle, **kwargs)
def get_circle(self, mobject):
circle = Circle(**self.circle_config)
circle.add_updater(lambda c: c.surround(mobject))
return circle
def interpolate_mobject(self, alpha):
super().interpolate_mobject(alpha)
self.mobject.set_stroke(opacity=alpha)
class ShowPassingFlash(ShowPartial):
@ -132,10 +153,10 @@ class ShowPassingFlash(ShowPartial):
lower = max(lower, 0)
return (lower, upper)
def clean_up_from_scene(self, *args, **kwargs):
ShowPartial.clean_up_from_scene(self, *args, **kwargs)
for submob, start_submob in self.get_all_families_zipped():
submob.pointwise_become_partial(start_submob, 0, 1)
def finish(self):
super().finish()
for submob, start in self.get_all_families_zipped():
submob.pointwise_become_partial(start, 0, 1)
class ShowCreationThenDestruction(ShowPassingFlash):
@ -151,10 +172,9 @@ class ShowCreationThenFadeOut(Succession):
}
def __init__(self, mobject, **kwargs):
Succession.__init__(
self,
ShowCreation, mobject,
FadeOut, mobject,
super().__init__(
ShowCreation(mobject),
FadeOut(mobject),
**kwargs
)
@ -165,34 +185,44 @@ class AnimationOnSurroundingRectangle(AnimationGroup):
# Function which takes in a rectangle, and spits
# out some animation. Could be some animation class,
# could be something more
"rect_to_animation": Animation
"rect_animation": Animation
}
def __init__(self, mobject, **kwargs):
digest_config(self, kwargs)
rect = SurroundingRectangle(
mobject, **self.surrounding_rectangle_config
)
if "surrounding_rectangle_config" in kwargs:
kwargs.pop("surrounding_rectangle_config")
AnimationGroup.__init__(self, self.rect_to_animation(rect, **kwargs))
self.mobject_to_surround = mobject
rect = self.get_rect()
rect.add_updater(lambda r: r.move_to(mobject))
super().__init__(
self.rect_animation(rect, **kwargs),
)
def get_rect(self):
return SurroundingRectangle(
self.mobject_to_surround,
**self.surrounding_rectangle_config
)
class ShowPassingFlashAround(AnimationOnSurroundingRectangle):
CONFIG = {
"rect_to_animation": ShowPassingFlash
"rect_animation": ShowPassingFlash
}
class ShowCreationThenDestructionAround(AnimationOnSurroundingRectangle):
CONFIG = {
"rect_to_animation": ShowCreationThenDestruction
"rect_animation": ShowCreationThenDestruction
}
class ShowCreationThenFadeAround(AnimationOnSurroundingRectangle):
CONFIG = {
"rect_to_animation": ShowCreationThenFadeOut
"rect_animation": ShowCreationThenFadeOut
}