mirror of
https://github.com/3b1b/manim.git
synced 2025-08-01 08:54:38 +08:00
Fixed Succession animation, while changing its syntax a bit
This commit is contained in:
@ -3,12 +3,12 @@ import itertools as it
|
|||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
from mobject import Mobject
|
from mobject import Mobject, Group
|
||||||
from mobject.vectorized_mobject import VMobject
|
from mobject.vectorized_mobject import VMobject
|
||||||
from mobject.tex_mobject import TextMobject
|
from mobject.tex_mobject import TextMobject
|
||||||
from animation import Animation
|
from animation import Animation
|
||||||
from animation import sync_animation_run_times_and_rate_funcs
|
from animation import sync_animation_run_times_and_rate_funcs
|
||||||
|
from transform import Transform
|
||||||
|
|
||||||
class Rotating(Animation):
|
class Rotating(Animation):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
@ -333,67 +333,83 @@ class LaggedStart(Animation):
|
|||||||
for anim in self.subanimations:
|
for anim in self.subanimations:
|
||||||
anim.clean_up(*args, **kwargs)
|
anim.clean_up(*args, **kwargs)
|
||||||
|
|
||||||
class DelayByOrder(Animation):
|
|
||||||
"""
|
|
||||||
Modifier of animation.
|
|
||||||
|
|
||||||
Warning: This will not work on all animation types.
|
|
||||||
"""
|
|
||||||
CONFIG = {
|
|
||||||
"max_power" : 5
|
|
||||||
}
|
|
||||||
def __init__(self, animation, **kwargs):
|
|
||||||
digest_locals(self)
|
|
||||||
self.num_mobject_points = animation.mobject.get_num_points()
|
|
||||||
kwargs.update(dict([
|
|
||||||
(attr, getattr(animation, attr))
|
|
||||||
for attr in Animation.CONFIG
|
|
||||||
]))
|
|
||||||
Animation.__init__(self, animation.mobject, **kwargs)
|
|
||||||
self.name = str(self) + str(self.animation)
|
|
||||||
|
|
||||||
def update_mobject(self, alpha):
|
|
||||||
dim = self.mobject.DIM
|
|
||||||
alpha_array = np.array([
|
|
||||||
[alpha**power]*dim
|
|
||||||
for n in range(self.num_mobject_points)
|
|
||||||
for prop in [(n+1.0)/self.num_mobject_points]
|
|
||||||
for power in [1+prop*(self.max_power-1)]
|
|
||||||
])
|
|
||||||
self.animation.update_mobject(alpha_array)
|
|
||||||
|
|
||||||
class Succession(Animation):
|
class Succession(Animation):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"rate_func" : None,
|
"rate_func" : None,
|
||||||
}
|
}
|
||||||
def __init__(self, *animations, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Each arg will either be an animation, or an animation class
|
||||||
|
followed by its arguments (and potentially a dict for
|
||||||
|
configuraiton).
|
||||||
|
|
||||||
|
For example,
|
||||||
|
Succession(
|
||||||
|
ShowCreation(circle),
|
||||||
|
Transform, circle, square,
|
||||||
|
Transform, circle, triangle,
|
||||||
|
ApplyMethod, circle.shift, 2*UP, {"run_time" : 2},
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
animations = []
|
||||||
|
state = {
|
||||||
|
"animations" : animations,
|
||||||
|
"curr_class" : None,
|
||||||
|
"curr_class_args" : [],
|
||||||
|
"curr_class_config" : {},
|
||||||
|
}
|
||||||
|
def invoke_curr_class(state):
|
||||||
|
if state["curr_class"] is None:
|
||||||
|
return
|
||||||
|
anim = state["curr_class"](
|
||||||
|
*state["curr_class_args"],
|
||||||
|
**state["curr_class_config"]
|
||||||
|
)
|
||||||
|
state["animations"].append(anim)
|
||||||
|
anim.update(1)
|
||||||
|
state["curr_class"] = None
|
||||||
|
state["curr_class_args"] = []
|
||||||
|
state["curr_class_config"] = {}
|
||||||
|
|
||||||
|
for arg in args:
|
||||||
|
if isinstance(arg, Animation):
|
||||||
|
animations.append(arg)
|
||||||
|
arg.update(1)
|
||||||
|
invoke_curr_class(state)
|
||||||
|
elif isinstance(arg, type) and issubclass(arg, Animation):
|
||||||
|
invoke_curr_class(state)
|
||||||
|
state["curr_class"] = arg
|
||||||
|
elif isinstance(arg, dict):
|
||||||
|
state["curr_class_config"] = arg
|
||||||
|
else:
|
||||||
|
state["curr_class_args"].append(arg)
|
||||||
|
invoke_curr_class(state)
|
||||||
|
for anim in animations:
|
||||||
|
anim.update(0)
|
||||||
|
|
||||||
|
self.run_times = [anim.run_time for anim in animations]
|
||||||
if "run_time" in kwargs:
|
if "run_time" in kwargs:
|
||||||
run_time = kwargs.pop("run_time")
|
run_time = kwargs.pop("run_time")
|
||||||
else:
|
else:
|
||||||
run_time = sum([anim.run_time for anim in animations])
|
run_time = sum(self.run_times)
|
||||||
self.num_anims = len(animations)
|
self.num_anims = len(animations)
|
||||||
self.anims = (animations)
|
self.animations = animations
|
||||||
mobject = Mobject(*[anim.mobject for anim in self.anims])
|
|
||||||
self.last_index = 0
|
mobject = Group(*[anim.mobject for anim in self.animations])
|
||||||
Animation.__init__(self, mobject, run_time = run_time, **kwargs)
|
Animation.__init__(self, mobject, run_time = run_time, **kwargs)
|
||||||
|
|
||||||
def update_mobject(self, alpha):
|
def update_mobject(self, alpha):
|
||||||
scaled_alpha = alpha*self.num_anims
|
if alpha >= 1.0:
|
||||||
index = min(int(scaled_alpha), len(self.anims)-1)
|
self.animations[-1].update(1)
|
||||||
curr_anim = self.anims[index]
|
return
|
||||||
if index != self.last_index:
|
run_times = self.run_times
|
||||||
last_anim = self.anims[self.last_index]
|
index = 0
|
||||||
last_anim.clean_up()
|
time = alpha*self.run_time
|
||||||
if last_anim.mobject is curr_anim.mobject:
|
while sum(run_times[:index+1]) < time:
|
||||||
#TODO, is there a way to do this that doesn't
|
index += 1
|
||||||
#require leveraging implementation details of
|
curr_anim = self.animations[index]
|
||||||
#Animations, and knowing about the different
|
sub_alpha = (time - sum(run_times[:index]))/run_times[index]
|
||||||
#struction of Transform?
|
curr_anim.update(sub_alpha)
|
||||||
if hasattr(curr_anim, "target_mobject"):
|
|
||||||
curr_anim.mobject.align_data(curr_anim.target_mobject)
|
|
||||||
curr_anim.starting_mobject = curr_anim.mobject.copy()
|
|
||||||
curr_anim.update(scaled_alpha - index)
|
|
||||||
self.last_index = index
|
|
||||||
|
|
||||||
class AnimationGroup(Animation):
|
class AnimationGroup(Animation):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
|
@ -7,7 +7,6 @@ import warnings
|
|||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
from animation import Animation
|
from animation import Animation
|
||||||
from simple_animations import DelayByOrder
|
|
||||||
from mobject import Mobject, Point, VMobject, Group
|
from mobject import Mobject, Point, VMobject, Group
|
||||||
from topics.geometry import Dot
|
from topics.geometry import Dot
|
||||||
|
|
||||||
@ -48,6 +47,7 @@ class Transform(Animation):
|
|||||||
self.path_arc,
|
self.path_arc,
|
||||||
self.path_arc_axis,
|
self.path_arc_axis,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_all_mobjects(self):
|
def get_all_mobjects(self):
|
||||||
return self.mobject, self.starting_mobject, self.target_mobject
|
return self.mobject, self.starting_mobject, self.target_mobject
|
||||||
|
|
||||||
@ -173,11 +173,6 @@ class FadeIn(Transform):
|
|||||||
self.starting_mobject.set_stroke(width = 0)
|
self.starting_mobject.set_stroke(width = 0)
|
||||||
self.starting_mobject.set_fill(opacity = 0)
|
self.starting_mobject.set_fill(opacity = 0)
|
||||||
|
|
||||||
class ShimmerIn(DelayByOrder):
|
|
||||||
def __init__(self, mobject, **kwargs):
|
|
||||||
mobject.sort_points(lambda p : np.dot(p, DOWN+RIGHT))
|
|
||||||
DelayByOrder.__init__(self, FadeIn(mobject, **kwargs))
|
|
||||||
|
|
||||||
class FocusOn(Transform):
|
class FocusOn(Transform):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"opacity" : 0.2,
|
"opacity" : 0.2,
|
||||||
|
Reference in New Issue
Block a user