Added Transform.create_target to make implementation of subclasses cleaner

This commit is contained in:
Grant Sanderson 2019-02-09 09:25:13 -08:00
parent 88b35c45b8
commit 22eab68e2a

View file

@ -9,7 +9,6 @@ from manimlib.constants import PI
from manimlib.mobject.mobject import Group from manimlib.mobject.mobject import Group
from manimlib.mobject.mobject import Mobject from manimlib.mobject.mobject import Mobject
from manimlib.utils.config_ops import digest_config from manimlib.utils.config_ops import digest_config
from manimlib.utils.iterables import adjacent_pairs
from manimlib.utils.paths import path_along_arc from manimlib.utils.paths import path_along_arc
from manimlib.utils.paths import straight_path from manimlib.utils.paths import straight_path
from manimlib.utils.rate_functions import smooth from manimlib.utils.rate_functions import smooth
@ -24,7 +23,7 @@ class Transform(Animation):
"replace_mobject_with_target_in_scene": False, "replace_mobject_with_target_in_scene": False,
} }
def __init__(self, mobject, target_mobject, **kwargs): def __init__(self, mobject, target_mobject=None, **kwargs):
Animation.__init__(self, mobject, **kwargs) Animation.__init__(self, mobject, **kwargs)
self.target_mobject = target_mobject self.target_mobject = target_mobject
self.init_path_func() self.init_path_func()
@ -50,12 +49,26 @@ class Transform(Animation):
# Use a copy of target_mobject for the align_data # Use a copy of target_mobject for the align_data
# call so that the actual target_mobject stays # call so that the actual target_mobject stays
# preserved. # preserved.
self.target_mobject = self.create_target()
self.check_target_mobject_validity()
self.target_copy = self.target_mobject.copy() self.target_copy = self.target_mobject.copy()
# Note, this potentially changes the structure # Note, this potentially changes the structure
# of both mobject and target_mobject # of both mobject and target_mobject
self.mobject.align_data(self.target_copy) self.mobject.align_data(self.target_copy)
super().begin() super().begin()
def create_target(self):
# Has no meaningful effect here, but may be useful
# in subclasses
return self.target_mobject
def check_target_mobject_validity(self):
if self.target_mobject is None:
message = "{}.create_target not properly implemented"
raise Exception(
message.format(self.__class__.__name__)
)
def clean_up_from_scene(self, scene): def clean_up_from_scene(self, scene):
super().clean_up_from_scene(scene) super().clean_up_from_scene(scene)
if self.replace_mobject_with_target_in_scene: if self.replace_mobject_with_target_in_scene:
@ -144,9 +157,7 @@ class ApplyMethod(Transform):
self.check_validity_of_input(method) self.check_validity_of_input(method)
self.method = method self.method = method
self.method_args = args self.method_args = args
# This will be replaced Transform.__init__(self, method.__self__, **kwargs)
temp_target = method.__self__
Transform.__init__(self, method.__self__, temp_target, **kwargs)
def check_validity_of_input(self, method): def check_validity_of_input(self, method):
if not inspect.ismethod(method): if not inspect.ismethod(method):
@ -156,10 +167,6 @@ class ApplyMethod(Transform):
) )
assert(isinstance(method.__self__, Mobject)) assert(isinstance(method.__self__, Mobject))
def begin(self):
self.target_mobject = self.create_target()
super().begin()
def create_target(self): def create_target(self):
method = self.method method = self.method
# Make sure it's a list so that args.pop() works # Make sure it's a list so that args.pop() works
@ -219,16 +226,10 @@ class Restore(ApplyMethod):
class ApplyFunction(Transform): class ApplyFunction(Transform):
def __init__(self, function, mobject, **kwargs): def __init__(self, function, mobject, **kwargs):
self.function = function self.function = function
temp_target = mobject Transform.__init__(self, mobject, **kwargs)
Transform.__init__(
self, mobject, temp_target, **kwargs
)
def begin(self): def create_target(self):
self.target_mobject = self.function( return self.function(self.mobject.copy())
self.mobject.copy()
)
super().begin()
class ApplyMatrix(ApplyPointwiseFunction): class ApplyMatrix(ApplyPointwiseFunction):
@ -277,19 +278,15 @@ class CyclicReplace(Transform):
} }
def __init__(self, *mobjects, **kwargs): def __init__(self, *mobjects, **kwargs):
group = Group(*mobjects) self.group = Group(*mobjects)
temp_target = group Transform.__init__(self, self.group, **kwargs)
Transform.__init__(self, group, temp_target, **kwargs)
def begin(self): def create_target(self):
self.target_mobject = self.mobject.copy() target = self.group.copy()
cycled_targets = [ cycled_targets = [target[-1], *target[:-1]]
self.target_mobject[-1], for m1, m2 in zip(cycled_targets, self.group):
*self.target_mobject[:-1],
]
for m1, m2 in zip(cycled_targets, self.mobject):
m1.move_to(m2) m1.move_to(m2)
super().begin() return target
class Swap(CyclicReplace): class Swap(CyclicReplace):