diff --git a/manim/renderer/cairo_renderer.py b/manim/renderer/cairo_renderer.py index 7cb7ae4690..dc97effbb7 100644 --- a/manim/renderer/cairo_renderer.py +++ b/manim/renderer/cairo_renderer.py @@ -76,7 +76,6 @@ def __init__(self, camera_class=None, **kwargs): self.animations_hashes = [] self.num_plays = 0 self.time = 0 - self.static_mobject_data = None def init(self, scene): self.file_writer = SceneFileWriter( @@ -102,6 +101,7 @@ def update_frame( # TODO Description in Docstring self, scene, mobjects=None, + background=None, include_submobjects=True, ignore_skipping=True, **kwargs, @@ -130,8 +130,8 @@ def update_frame( # TODO Description in Docstring scene.mobjects, scene.foreground_mobjects, ) - if self.static_mobject_data is not None: - self.camera.set_frame_to_background(self.static_mobject_data) + if background is not None: + self.camera.set_frame_to_background(background) else: self.camera.reset() @@ -150,10 +150,6 @@ def get_frame(self): """ return np.array(self.camera.pixel_array) - def save_static_mobject_data(self, scene, static_mobjects): - self.update_frame(scene, static_mobjects) - self.static_mobject_data = self.get_frame() - def add_frame(self, frame, num_frames=1): """ Adds a frame to the video_file_stream diff --git a/manim/scene/scene.py b/manim/scene/scene.py index cd07925218..e6be703986 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -21,7 +21,7 @@ from ..container import Container from ..mobject.mobject import Mobject from ..scene.scene_file_writer import SceneFileWriter -from ..utils.iterables import list_update +from ..utils.iterables import list_update, list_difference_update from ..utils.hashing import get_hash_from_play_call, get_hash_from_wait_call from ..utils.family import extract_mobject_family_members from ..renderer.cairo_renderer import CairoRenderer @@ -530,7 +530,8 @@ def get_moving_mobjects(self, *animations): return mobjects[i:] return [] - def get_moving_and_static_mobjects(self, animations): + def get_moving_and_stationary_mobjects(self, animations): + moving_mobjects = self.get_moving_mobjects(*animations) all_mobjects = list_update(self.mobjects, self.foreground_mobjects) all_mobject_families = extract_mobject_family_members( all_mobjects, @@ -542,10 +543,10 @@ def get_moving_and_static_mobjects(self, animations): moving_mobjects, use_z_index=self.renderer.camera.use_z_index, ) - static_mobjects = filter( - lambda m: m not in all_moving_mobject_families, all_mobject_families + stationary_mobjects = list_difference_update( + all_mobject_families, all_moving_mobject_families ) - return all_moving_mobject_families, static_mobjects + return all_moving_mobject_families, stationary_mobjects def get_time_progression( self, run_time, n_iterations=None, override_skip_animations=False @@ -720,12 +721,12 @@ def compile_method(state): return animations - def play(self, *args, **kwargs): - self.renderer.play(self, *args, **kwargs) - def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None): self.renderer.wait(self, duration=duration, stop_condition=stop_condition) + def play(self, *args, **kwargs): + self.renderer.play(self, *args, **kwargs) + def play_internal(self, *args, **kwargs): """ This method is used to prep the animations for rendering, @@ -749,10 +750,11 @@ def play_internal(self, *args, **kwargs): # Paint all non-moving objects onto the screen, so they don't # have to be rendered every frame - moving_mobjects, static_mobjects = self.get_moving_and_static_mobjects( + moving_mobjects, stationary_mobjects = self.get_moving_and_stationary_mobjects( animations ) - self.renderer.save_static_mobject_data(self, static_mobjects) + self.renderer.update_frame(self, mobjects=stationary_mobjects) + self.static_image = self.renderer.get_frame() last_t = 0 for t in self.get_animation_time_progression(animations): @@ -763,7 +765,7 @@ def play_internal(self, *args, **kwargs): alpha = t / animation.run_time animation.interpolate(alpha) self.update_mobjects(dt) - self.renderer.update_frame(self, moving_mobjects) + self.renderer.update_frame(self, moving_mobjects, self.static_image) self.renderer.add_frame(self.renderer.get_frame()) for animation in animations: diff --git a/tests/control_data/graphical_units_data/transform/FadeInAndOutTest.npz b/tests/control_data/graphical_units_data/transform/FadeInAndOutTest.npz new file mode 100644 index 0000000000..881f1fbcdb Binary files /dev/null and b/tests/control_data/graphical_units_data/transform/FadeInAndOutTest.npz differ diff --git a/tests/test_graphical_units/test_transform.py b/tests/test_graphical_units/test_transform.py index 98e7aae18c..84a6c4285b 100644 --- a/tests/test_graphical_units/test_transform.py +++ b/tests/test_graphical_units/test_transform.py @@ -119,6 +119,18 @@ def construct(self): self.play(CyclicReplace(square, circle)) +class FadeInAndOutTest(Scene): + def construct(self): + square = Square(color=BLUE).shift(2 * UP) + annotation = Square(color=BLUE) + self.add(annotation) + self.play(FadeIn(square)) + + annotation.become(Square(color=RED).rotate(PI / 4)) + self.add(annotation) + self.play(FadeOut(square)) + + MODULE_NAME = "transform"