From e514bd66b5a41d0b9b55dbfdd2e56b57ad0bc25e Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Tue, 26 Jun 2018 14:40:20 -0700 Subject: [PATCH] Added simple featured creator wrapper animations --- active_projects/fc1.py | 272 +++++++++++++++++++++++++++++++++++++++++ old_projects/efvgt.py | 2 +- 2 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 active_projects/fc1.py diff --git a/active_projects/fc1.py b/active_projects/fc1.py new file mode 100644 index 00000000..312187cc --- /dev/null +++ b/active_projects/fc1.py @@ -0,0 +1,272 @@ +from big_ol_pile_of_manim_imports import * +from old_projects.efvgt import get_confetti_animations + + +class CrossingOneMillion(TeacherStudentsScene): + def construct(self): + self.increment_count() + self.comment_on_real_milestone() + self.reflect() + + def increment_count(self): + number = self.number = Integer(0) + number.move_to(UP, LEFT) + number.scale(3) + self.look_at(number, run_time=0) + + confetti_spirils = self.confetti_spirils = map( + NormalAnimationAsContinualAnimation, + get_confetti_animations(50) + ) + self.add(*confetti_spirils) + self.play( + ChangeDecimalToValue( + number, 10**6, + position_update_func=lambda m: m.move_to( + UP, LEFT + ), + rate_func=bezier([0, 0, 0, 1, 1, 1]), + run_time=5, + ), + LaggedStart( + ApplyMethod, self.get_pi_creatures(), + lambda m: (m.change, "hooray", number), + rate_func=squish_rate_func(smooth, 0, 0.5), + run_time=4, + ), + ) + self.wait() + + def comment_on_real_milestone(self): + number = self.number + remainder = Integer(2**20 - 10**6) + words = TextMobject( + "Just", + "{:,}".format(remainder.number), + "to go \\\\ before the real milestone", + ) + self.student_says( + words, + added_anims=[ + ApplyMethod(self.teacher.change, "hesitant"), + self.get_student_changes( + "sassy", "speaking", "happy" + ), + number.scale, 0.5, + number.center, + number.to_edge, UP, + ] + ) + self.wait() + self.remove(*self.confetti_spirils) + remainder.replace(words[1]) + words.submobjects[1] = remainder + self.play( + ChangeDecimalToValue(number, 2**20, run_time=3), + ChangeDecimalToValue(remainder, 0.1, run_time=3), + self.teacher.change, "pondering", number, + self.get_student_changes( + *["pondering"] * 3, + look_at_arg=number + ), + ) + self.play( + FadeOut(self.students[1].bubble), + FadeOut(self.students[1].bubble.content), + ) + self.wait(2) + + def reflect(self): + bubble = ThoughtBubble( + direction=RIGHT, + height=4, + width=7, + ) + bubble.pin_to(self.teacher) + q_marks = TexMobject("???") + q_marks.scale(2) + q_marks.set_color_by_gradient(BLUE_D, BLUE_B) + q_marks.next_to(bubble[-1].get_top(), DOWN) + arrow = Vector(0.5 * DOWN, color=WHITE) + arrow.next_to(q_marks, DOWN) + number = self.number + number.generate_target() + number.target.next_to(arrow, DOWN) + + self.play( + ShowCreation( + bubble, + rate_func=squish_rate_func(smooth, 0, 0.3) + ), + Write(q_marks), + GrowArrow(arrow), + MoveToTarget(number), + run_time=3 + ) + self.wait() + + +class ShareWithFriends(PiCreatureScene): + def construct(self): + randy, morty = self.pi_creatures + + self.pi_creature_says( + randy, + "Wanna see why \\\\" + + "$1 - \\frac{1}{3} + \\frac{1}{5}" + + "- \\frac{1}{7} + \\cdots = \\frac{\\pi}{4}$?", + target_mode="tease", + added_anims=[morty.look, UP] + ) + self.play(morty.change, "maybe", UP) + self.wait() + + def create_pi_creatures(self): + randy = Randolph(color=GREEN) + morty = Mortimer(color=RED_E) + randy.to_edge(DOWN).shift(4 * LEFT) + morty.to_edge(DOWN) + return randy, morty + + +class AllFeaturedCreators(MortyPiCreatureScene): + def construct(self): + morty = self.pi_creature + title = Title("Featured creators") + + dots = VGroup(*[Dot(color=WHITE) for x in range(4)]) + dots.arrange_submobjects(DOWN, buff=LARGE_BUFF) + dots.to_edge(LEFT, buff=2) + + creators = VGroup(*map(TextMobject, [ + "Think Twice", + "LeiosOS", + "Welch Labs", + "Infinity plus one", + ])) + + for creator, dot in zip(creators, dots): + creator.next_to(dot, RIGHT) + dot.save_state() + dot.scale(4) + dot.set_fill(opacity=0) + + rects = VGroup(*map(SurroundingRectangle, creators)) + rects.set_stroke(WHITE, 2) + rects.set_fill(BLUE_E, 1) + + think_words = VGroup(*map(TextMobject, [ + "(thinks visually)", + "(thinks in terms of communities)", + "(thinks in terms of series)", + "(thinks playfully)", + ])) + for word, creator in zip(think_words, creators): + # word.move_to(creator, RIGHT) + # word.align_to(RIGHT, LEFT) + word.next_to(creator, RIGHT) + word.set_color(YELLOW) + + self.play( + morty.change, "raise_right_hand", + Write(title) + ) + self.wait() + self.play(LaggedStart( + ApplyMethod, dots, + lambda m: (m.restore,) + )) + self.play( + LaggedStart(FadeIn, rects, lag_ratio=0.7), + morty.change, "happy" + ) + self.add(creators, rects) + self.wait() + + modes = ["hooray", "tease", "raise_right_hand", "hooray"] + for rect, word, mode in zip(rects, think_words, modes): + self.play( + self.get_rect_removal(rect), + morty.change, mode, + ) + self.wait() + self.play(Write(word)) + self.wait() + + self.add(think_words) + + def get_rect_removal(self, rect): + rect.generate_target() + rect.target.stretch(0, 0, about_edge=LEFT) + rect.target.set_stroke(width=0) + return MoveToTarget(rect) + + +class GeneralWrapper(Scene): + CONFIG = { + "title_text": "" + } + + def construct(self): + title = TextMobject(self.title_text) + title.to_edge(UP) + rect = ScreenRectangle(height=6.5) + rect.next_to(title, DOWN) + self.play(Write(title), ShowCreation(rect)) + self.wait() + + +class ThinkTwiceWrapper(GeneralWrapper): + CONFIG = {"title_text": "Think Twice"} + + +class LeiosOSWrapper(GeneralWrapper): + CONFIG = {"title_text": "LeiosOS"} + + +class WelchLabsWrapper(GeneralWrapper): + CONFIG = {"title_text": "Welch Labs"} + + +class InfinityPlusOneWrapper(GeneralWrapper): + CONFIG = {"title_text": "Infinity Plus One"} + + +class EndScreen(PiCreatureScene): + CONFIG = { + "seconds_to_blink": 3, + } + + def construct(self): + words = TextMobject("Clicky stuffs") + words.scale(1.5) + words.next_to(self.pi_creature, UP) + words.to_edge(UP) + + self.play( + FadeIn( + words, + run_time=2, + submobject_mode="lagged_start" + ), + self.pi_creature.change_mode, "hooray" + ) + self.wait() + mode_point_pairs = [ + ("raise_left_hand", 5 * LEFT + 3 * UP), + ("raise_right_hand", 5 * RIGHT + 3 * UP), + ("thinking", 5 * LEFT + 2 * DOWN), + ("thinking", 5 * RIGHT + 2 * DOWN), + ("thinking", 5 * RIGHT + 2 * DOWN), + ("happy", 5 * LEFT + 3 * UP), + ("raise_right_hand", 5 * RIGHT + 3 * UP), + ] + for mode, point in mode_point_pairs: + self.play(self.pi_creature.change, mode, point) + self.wait() + self.wait(3) + + def create_pi_creature(self): + self.pi_creature = Randolph() + self.pi_creature.shift(2 * DOWN + 1.5 * LEFT) + return self.pi_creature diff --git a/old_projects/efvgt.py b/old_projects/efvgt.py index 19bf1ea5..dcb22615 100644 --- a/old_projects/efvgt.py +++ b/old_projects/efvgt.py @@ -3326,7 +3326,7 @@ class ECLPromo(PiCreatureScene): class ExpTransformation(ComplexTransformationScene): CONFIG = { - "camera_class": CameraWithPerspective, + "camera_class": ThreeDCamera, } def construct(self): self.camera.camera_distance = 10,