def create_pi_creatures(self): self.teacher = Mortimer(color=self.teacher_color) self.teacher.to_corner(DOWN + RIGHT) self.teacher.look(DOWN + LEFT) self.students = VGroup( *[Randolph(color=c) for c in self.student_colors]) self.students.arrange(RIGHT) self.students.scale(self.student_scale_factor) self.students.to_corner(DOWN + LEFT) self.teacher.look_at(self.students[-1].eyes) for student in self.students: student.look_at(self.teacher.eyes) return [self.teacher] + list(self.students)
def construct(self): morty = Mortimer() morty.next_to(ORIGIN, DOWN) patreon_logo = PatreonLogo() patreon_logo.to_edge(UP) patrons = list(map(TextMobject, self.specific_patronds)) num_groups = float(len(patrons)) / self.max_patron_group_size proportion_range = np.linspace(0, 1, num_groups + 1) indices = (len(patrons) * proportion_range).astype('int') patron_groups = [ VGroup(*patrons[i:j]) for i, j in zip(indices, indices[1:]) ] for i, group in enumerate(patron_groups): left_group = VGroup(*group[:len(group) / 2]) right_group = VGroup(*group[len(group) / 2:]) for subgroup, vect in (left_group, LEFT), (right_group, RIGHT): subgroup.arrange(DOWN, aligned_edge=LEFT) subgroup.scale(self.patron_scale_val) subgroup.to_edge(vect) last_group = None for i, group in enumerate(patron_groups): anims = [] if last_group is not None: self.play( FadeOut(last_group), morty.look, UP + LEFT ) else: anims += [ DrawBorderThenFill(patreon_logo), ] self.play( LaggedStartMap( FadeIn, group, run_time=2, ), morty.change, "gracious", group.get_corner(UP + LEFT), *anims ) self.play(morty.look_at, group.get_corner(DOWN + LEFT)) self.play(morty.look_at, group.get_corner(UP + RIGHT)) self.play(morty.look_at, group.get_corner(DOWN + RIGHT)) self.play(Blink(morty)) last_group = group
def get_pis(self): return VGroup( Randolph(color=BLUE_E, mode="pondering"), Randolph(color=BLUE_D, mode="hooray"), Randolph(color=BLUE_C, mode="sassy"), Mortimer(color=GREY_BROWN, mode="thinking") )
def create_pi_creatures(self): title = self.title = TextMobject("Clicky Stuffs") title.scale(1.5) title.to_edge(UP, buff=MED_SMALL_BUFF) randy, morty = self.pi_creatures = VGroup(Randolph(), Mortimer()) for pi, vect in (randy, LEFT), (morty, RIGHT): pi.set_height(title.get_height()) pi.change_mode("thinking") pi.look(DOWN) pi.next_to(title, vect, buff=MED_LARGE_BUFF) self.add_foreground_mobjects(title, randy, morty) return self.pi_creatures
def create_pi_creatures(self): self.teacher = Mortimer(color=self.teacher_color) self.teacher.to_corner(DOWN + RIGHT) self.teacher.look(DOWN + LEFT) self.students = VGroup(*[ Randolph(color=c) for c in self.student_colors ]) self.students.arrange(RIGHT) self.students.scale(self.student_scale_factor) self.students.to_corner(DOWN + LEFT) self.teacher.look_at(self.students[-1].eyes) for student in self.students: student.look_at(self.teacher.eyes) return [self.teacher] + list(self.students)
class TeacherStudentsScene(PiCreatureScene): CONFIG = { "student_colors": [BLUE_D, BLUE_E, BLUE_C], "teacher_color": GREY_BROWN, "student_scale_factor": 0.8, "seconds_to_blink": 2, "screen_height": 3, "camera_config": { "background_color": DARKER_GREY, }, } def setup(self): PiCreatureScene.setup(self) self.screen = ScreenRectangle(height=self.screen_height) self.screen.to_corner(UP + LEFT) self.hold_up_spot = self.teacher.get_corner(UP + LEFT) + MED_LARGE_BUFF * UP def create_pi_creatures(self): self.teacher = Mortimer(color=self.teacher_color) self.teacher.to_corner(DOWN + RIGHT) self.teacher.look(DOWN + LEFT) self.students = VGroup( *[Randolph(color=c) for c in self.student_colors]) self.students.arrange(RIGHT) self.students.scale(self.student_scale_factor) self.students.to_corner(DOWN + LEFT) self.teacher.look_at(self.students[-1].eyes) for student in self.students: student.look_at(self.teacher.eyes) return [self.teacher] + list(self.students) def get_teacher(self): return self.teacher def get_students(self): return self.students def teacher_says(self, *content, **kwargs): return self.pi_creature_says(self.get_teacher(), *content, **kwargs) def student_says(self, *content, **kwargs): if "target_mode" not in kwargs: target_mode = random.choice([ "raise_right_hand", "raise_left_hand", ]) kwargs["target_mode"] = target_mode if "bubble_kwargs" not in kwargs: kwargs["bubble_kwargs"] = {"direction": LEFT} student = self.get_students()[kwargs.get("student_index", 2)] return self.pi_creature_says(student, *content, **kwargs) def teacher_thinks(self, *content, **kwargs): return self.pi_creature_thinks(self.get_teacher(), *content, **kwargs) def student_thinks(self, *content, **kwargs): student = self.get_students()[kwargs.get("student_index", 2)] return self.pi_creature_thinks(student, *content, **kwargs) def change_all_student_modes(self, mode, **kwargs): self.change_student_modes(*[mode] * len(self.students), **kwargs) def change_student_modes(self, *modes, **kwargs): added_anims = kwargs.pop("added_anims", []) self.play(self.get_student_changes(*modes, **kwargs), *added_anims) def get_student_changes(self, *modes, **kwargs): pairs = list(zip(self.get_students(), modes)) pairs = [(s, m) for s, m in pairs if m is not None] start = VGroup(*[s for s, m in pairs]) target = VGroup(*[s.copy().change_mode(m) for s, m in pairs]) if "look_at_arg" in kwargs: for pi in target: pi.look_at(kwargs["look_at_arg"]) anims = [Transform(s, t) for s, t in zip(start, target)] return LaggedStart( *anims, lag_ratio=kwargs.get("lag_ratio", 0.5), run_time=1, ) # return Transform( # start, target, # lag_ratio=lag_ratio, # run_time=2 # ) def zoom_in_on_thought_bubble(self, bubble=None, radius=FRAME_Y_RADIUS + FRAME_X_RADIUS): if bubble is None: for pi in self.get_pi_creatures(): if hasattr(pi, "bubble") and isinstance( pi.bubble, ThoughtBubble): bubble = pi.bubble break if bubble is None: raise Exception("No pi creatures have a thought bubble") vect = -bubble.get_bubble_center() def func(point): centered = point + vect return radius * centered / get_norm(centered) self.play( * [ApplyPointwiseFunction(func, mob) for mob in self.get_mobjects()]) def teacher_holds_up(self, mobject, target_mode="raise_right_hand", added_anims=None, **kwargs): mobject.move_to(self.hold_up_spot, DOWN) mobject.shift_onto_screen() mobject_copy = mobject.copy() mobject_copy.shift(DOWN) mobject_copy.fade(1) added_anims = added_anims or [] self.play(ReplacementTransform(mobject_copy, mobject), self.teacher.change, target_mode, *added_anims)
class TeacherStudentsScene(PiCreatureScene): CONFIG = { "student_colors": [BLUE_D, BLUE_E, BLUE_C], "teacher_color": GREY_BROWN, "student_scale_factor": 0.8, "seconds_to_blink": 2, "screen_height": 3, } def setup(self): PiCreatureScene.setup(self) self.screen = ScreenRectangle(height=self.screen_height) self.screen.to_corner(UP + LEFT) self.hold_up_spot = self.teacher.get_corner(UP + LEFT) + MED_LARGE_BUFF * UP def create_pi_creatures(self): self.teacher = Mortimer(color=self.teacher_color) self.teacher.to_corner(DOWN + RIGHT) self.teacher.look(DOWN + LEFT) self.students = VGroup(*[ Randolph(color=c) for c in self.student_colors ]) self.students.arrange(RIGHT) self.students.scale(self.student_scale_factor) self.students.to_corner(DOWN + LEFT) self.teacher.look_at(self.students[-1].eyes) for student in self.students: student.look_at(self.teacher.eyes) return [self.teacher] + list(self.students) def get_teacher(self): return self.teacher def get_students(self): return self.students def teacher_says(self, *content, **kwargs): return self.pi_creature_says( self.get_teacher(), *content, **kwargs ) def student_says(self, *content, **kwargs): if "target_mode" not in kwargs: target_mode = random.choice([ "raise_right_hand", "raise_left_hand", ]) kwargs["target_mode"] = target_mode if "bubble_kwargs" not in kwargs: kwargs["bubble_kwargs"] = {"direction": LEFT} student = self.get_students()[kwargs.get("student_index", 2)] return self.pi_creature_says( student, *content, **kwargs ) def teacher_thinks(self, *content, **kwargs): return self.pi_creature_thinks( self.get_teacher(), *content, **kwargs ) def student_thinks(self, *content, **kwargs): student = self.get_students()[kwargs.get("student_index", 2)] return self.pi_creature_thinks(student, *content, **kwargs) def change_all_student_modes(self, mode, **kwargs): self.change_student_modes(*[mode] * len(self.students), **kwargs) def change_student_modes(self, *modes, **kwargs): added_anims = kwargs.pop("added_anims", []) self.play( self.get_student_changes(*modes, **kwargs), *added_anims ) def get_student_changes(self, *modes, **kwargs): pairs = list(zip(self.get_students(), modes)) pairs = [(s, m) for s, m in pairs if m is not None] start = VGroup(*[s for s, m in pairs]) target = VGroup(*[s.copy().change_mode(m) for s, m in pairs]) if "look_at_arg" in kwargs: for pi in target: pi.look_at(kwargs["look_at_arg"]) anims = [ Transform(s, t) for s, t in zip(start, target) ] return LaggedStart( *anims, lag_ratio=kwargs.get("lag_ratio", 0.5), run_time=1, ) # return Transform( # start, target, # lag_ratio=lag_ratio, # run_time=2 # ) def zoom_in_on_thought_bubble(self, bubble=None, radius=FRAME_Y_RADIUS + FRAME_X_RADIUS): if bubble is None: for pi in self.get_pi_creatures(): if hasattr(pi, "bubble") and isinstance(pi.bubble, ThoughtBubble): bubble = pi.bubble break if bubble is None: raise Exception("No pi creatures have a thought bubble") vect = -bubble.get_bubble_center() def func(point): centered = point + vect return radius * centered / get_norm(centered) self.play(*[ ApplyPointwiseFunction(func, mob) for mob in self.get_mobjects() ]) def teacher_holds_up(self, mobject, target_mode="raise_right_hand", added_anims=None, **kwargs): mobject.move_to(self.hold_up_spot, DOWN) mobject.shift_onto_screen() mobject_copy = mobject.copy() mobject_copy.shift(DOWN) mobject_copy.fade(1) added_anims = added_anims or [] self.play( ReplacementTransform(mobject_copy, mobject), self.teacher.change, target_mode, *added_anims )