def zoom_out(self, board=Mobject()): def zoom_out(mob): mob.scale(1/3) mob.to_corner(UL) return mob self.play( LaggedStart( ApplyFunction(zoom_out, board), AnimationGroup( *[FadeInFrom(student) for student in self.students], FadeInFrom(self.teacher, RIGHT), ), lag_ratio = 0.1, run_time=2 ), )
def test_succession_in_succession_timing(): """Test timing of nested successions.""" line = Line() animation_1s = FadeInFrom(line, direction=DOWN, run_time=1.0) animation_4s = FadeOutAndShift(line, direction=DOWN, run_time=4.0) nested_succession = Succession(animation_1s, animation_4s) succession = Succession( FadeInFrom(line, direction=DOWN, run_time=4.0), nested_succession, FadeInFrom(line, direction=DOWN, run_time=1.0), ) assert nested_succession.get_run_time() == 5.0 assert succession.get_run_time() == 10.0 succession.begin() succession.interpolate(0.1) assert succession.active_index == 0 # The nested succession must not be active yet, and as a result hasn't set active_animation yet. assert not hasattr(nested_succession, "active_animation") succession.interpolate(0.39) assert succession.active_index == 0 assert not hasattr(nested_succession, "active_animation") # The nested succession starts at 40% of total run time succession.interpolate(0.4) assert succession.active_index == 1 assert nested_succession.active_index == 0 # The nested succession second animation starts at 50% of total run time. succession.interpolate(0.49) assert succession.active_index == 1 assert nested_succession.active_index == 0 succession.interpolate(0.5) assert succession.active_index == 1 assert nested_succession.active_index == 1 # The last animation starts at 90% of total run time. The nested succession must be finished at that time. succession.interpolate(0.89) assert succession.active_index == 1 assert nested_succession.active_index == 1 succession.interpolate(0.9) assert succession.active_index == 2 assert nested_succession.active_index == 2 assert nested_succession.active_animation is None # After 100%, nothing must be playing anymore. succession.interpolate(1.0) assert succession.active_index == 3 assert succession.active_animation is None assert nested_succession.active_index == 2 assert nested_succession.active_animation is None
def create_arrows(self, created): all_anims = [] overlay_objs = [] for (id1, (p11, p12), (d1x, d1y)), (id2, (p21, p22), (d2x, d2y)) in created: self.arrow_blocks[id1] = self._create_arrow( [((p11[0] + p12[0])/2 + 0.5) * self.scale, ((p11[1] + p12[1])/2 + 0.5) * self.scale, 0], [d1x, d1y], ) self.arrow_blocks[id2] = self._create_arrow( [((p21[0] + p22[0])/2 + 0.5) * self.scale, ((p21[1] + p22[1])/2 + 0.5) * self.scale, 0], [d2x, d2y], ) overlay_objs.extend([self.arrow_blocks[id1], self.arrow_blocks[id2]]) if self.ARROW_OVERLAY_COLOUR is not None: top = max(self.arrow_blocks[id1].get_top()[1], self.arrow_blocks[id2].get_top()[1]) right = max(self.arrow_blocks[id1].get_right()[0], self.arrow_blocks[id2].get_right()[0]) fade_square = Square(side_length=self.scale * 2, color=self.ARROW_OVERLAY_COLOUR) fade_square.set_opacity(self.ARROW_OVERLAY_STARTING_ALPHA) fade_square.move_to([right - self.scale, top - self.scale, 0]) overlay_objs.append(fade_square) if self.ARROW_CREATE_RUNTIME > 0: anims = [] if self.ARROW_OVERLAY_COLOUR is not None: anims.append(FadeOut(fade_square)) if self.ARROW_CREATE_ANIM is not None: if self.ARROW_CREATE_ANIM == FadeInFrom: anims.append(FadeInFrom(self.arrow_blocks[id1], direction=[-d1x * self.scale, -d1y * self.scale, 0])) anims.append(FadeInFrom(self.arrow_blocks[id2], direction=[-d2x * self.scale, -d2y * self.scale, 0])) else: anims.append(self.ARROW_CREATE_ANIM(self.arrow_blocks[id1])) anims.append(self.ARROW_CREATE_ANIM(self.arrow_blocks[id2])) else: # This adds them to the scene. anims.append(Transform(self.arrow_blocks[id1], self.arrow_blocks[id1])) anims.append(Transform(self.arrow_blocks[id2], self.arrow_blocks[id2])) all_anims.append(AnimationGroup(*anims)) if self.ARROW_CREATE_RUNTIME > 0 and len(all_anims) > 0: return overlay_objs, LaggedStart(*all_anims, lag_ratio=self.ARROW_LAG_RATIO) return overlay_objs, None
def test_succession_timing(): """Test timing of animations in a succession.""" line = Line() animation_1s = FadeInFrom(line, direction=DOWN, run_time=1.0) animation_4s = FadeOutAndShift(line, direction=DOWN, run_time=4.0) succession = Succession(animation_1s, animation_4s) assert succession.get_run_time() == 5.0 succession.begin() assert succession.active_index == 0 # The first animation takes 20% of the total run time. succession.interpolate(0.199) assert succession.active_index == 0 succession.interpolate(0.2) assert succession.active_index == 1 succession.interpolate(0.8) assert succession.active_index == 1 # At 100% and more, no animation must be active anymore. succession.interpolate(1.0) assert succession.active_index == 2 assert succession.active_animation is None succession.interpolate(1.2) assert succession.active_index == 2 assert succession.active_animation is None