From 59355909f2de9236af8168a26c70bcf6caa3b285 Mon Sep 17 00:00:00 2001 From: Elvis Claros Castro Date: Sat, 26 Sep 2026 20:21:47 -0300 Subject: Import video pipeline as it was --- scenes/v1_montyhall.py | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 scenes/v1_montyhall.py (limited to 'scenes/v1_montyhall.py') diff --git a/scenes/v1_montyhall.py b/scenes/v1_montyhall.py new file mode 100644 index 0000000..bdaf6c5 --- /dev/null +++ b/scenes/v1_montyhall.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +import sys, os +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from manim import * +from tiktok import * + +DOOR_Y, DW, DH = 4.0, 2.5, 3.7 +XS = [-2.85, 0.0, 2.85] + + +class MontyHall(TikTok): + NAME = "montyhall" + + def door(self, n, x): + face = RoundedRectangle(corner_radius=0.18, width=DW, height=DH, + stroke_color="#2E3A55", stroke_width=6, + fill_color="#16203A", fill_opacity=1) + num = Text(str(n), font=FONT, font_size=104, weight=BOLD, color="#5B6B8C") + knob = Dot(radius=0.1, color="#5B6B8C").move_to(face.get_right() + LEFT * 0.36) + d = VGroup(face, num, knob).move_to([x, DOOR_Y, 0]) + d.face, d.num, d.knob = face, num, knob + return d + + def badge(self, text, color, fs=30): + t = Text(text, font=FONT, font_size=fs, weight=BOLD, color="#0B0F1A") + box = RoundedRectangle(corner_radius=0.2, width=t.width + 0.5, height=t.height + 0.42, + stroke_width=0, fill_color=color, fill_opacity=1) + return VGroup(box, t) + + def car_icon(self, color=VERDE): + body = RoundedRectangle(corner_radius=0.14, width=1.6, height=0.6, + stroke_width=0, fill_color=color, fill_opacity=1) + roof = RoundedRectangle(corner_radius=0.12, width=0.92, height=0.48, + stroke_width=0, fill_color=color, fill_opacity=1) + roof.next_to(body, UP, buff=-0.08) + w1 = Dot(radius=0.19, color="#0B0F1A").move_to(body.get_bottom() + LEFT * 0.48) + w2 = Dot(radius=0.19, color="#0B0F1A").move_to(body.get_bottom() + RIGHT * 0.48) + return VGroup(roof, body, w1, w2) + + def goat_icon(self, color="#94A3B8"): + head = Ellipse(width=1.05, height=0.72, stroke_width=0, fill_color=color, fill_opacity=1) + snout = Ellipse(width=0.5, height=0.36, stroke_width=0, fill_color=color, fill_opacity=1) + snout.move_to(head.get_bottom() + DOWN * 0.1) + h1 = ArcBetweenPoints(head.get_top() + LEFT * 0.26, head.get_top() + LEFT * 0.62 + UP * 0.42, + angle=-1.1, stroke_width=8, color=color) + h2 = ArcBetweenPoints(head.get_top() + RIGHT * 0.26, head.get_top() + RIGHT * 0.62 + UP * 0.42, + angle=1.1, stroke_width=8, color=color) + e1 = Dot(radius=0.07, color="#0B0F1A").move_to(head.get_center() + LEFT * 0.22 + UP * 0.06) + e2 = Dot(radius=0.07, color="#0B0F1A").move_to(head.get_center() + RIGHT * 0.22 + UP * 0.06) + return VGroup(h1, h2, head, snout, e1, e2) + + def prize(self, kind, x): + if kind == "auto": + g = VGroup(self.car_icon(), self.badge("AUTO", VERDE)) + else: + g = VGroup(self.goat_icon(), self.badge("CABRA", "#94A3B8")) + g.arrange(DOWN, buff=0.3) + return g.move_to([x, DOOR_Y, 0]) + + def construct(self): + self.prepare() + chip = self.chip("¿Cambiarías de puerta?") + doors = VGroup(*[self.door(i + 1, XS[i]) for i in range(3)]) + + with self.beat(0) as b: + b.play(FadeIn(chip, shift=DOWN * 0.3), run_time=0.5) + b.play(LaggedStart(*[GrowFromCenter(d) for d in doors], lag_ratio=0.25), run_time=1.2) + h1 = VGroup(self.car_icon().scale(0.85), + Text("×1", font=FONT, font_size=46, weight=BOLD, color=VERDE) + ).arrange(RIGHT, buff=0.35).move_to(UP * 1.3) + b.play(FadeIn(h1, shift=UP * 0.2), run_time=0.5) + + with self.beat(1) as b: + h2 = VGroup(self.goat_icon().scale(0.85), + Text("×2", font=FONT, font_size=46, weight=BOLD, color="#94A3B8") + ).arrange(RIGHT, buff=0.35) + h2.next_to(h1, DOWN, buff=0.55) + b.play(FadeIn(h2, shift=UP * 0.2), run_time=0.6) + b.wait(0.5) + b.play(FadeOut(VGroup(h1, h2)), run_time=0.4) + + with self.beat(2) as b: + pick = Text("TU ELECCIÓN", font=FONT, font_size=38, weight=BOLD, color=AMBAR) + arrow = Arrow(doors[0].get_bottom() + DOWN * 1.3, doors[0].get_bottom() + DOWN * 0.12, + buff=0, color=AMBAR, stroke_width=10) + pick.next_to(arrow, DOWN, buff=0.18) + b.play(doors[0].face.animate.set_stroke(AMBAR, 11), + doors[0].num.animate.set_color(AMBAR), run_time=0.5) + b.play(GrowArrow(arrow), FadeIn(pick), run_time=0.5) + picked = VGroup(pick, arrow) + + with self.beat(3) as b: + goat = self.prize("cabra", XS[2]) + b.play(doors[2].face.animate.set_fill("#0E1526", 1).set_stroke("#2E3A55", 4), + FadeOut(doors[2].num), FadeOut(doors[2].knob), run_time=0.7) + b.play(FadeIn(goat, scale=0.75), run_time=0.7) + doors[2].remove(doors[2].num, doors[2].knob) + b.play(VGroup(doors[2], goat).animate.set_opacity(0.35), run_time=0.5) + + with self.beat(4) as b: + q = Text("¿1 o 2?", font=FONT, font_size=82, weight=BOLD, color=WHITE).move_to(UP * 1.0) + b.play(FadeOut(picked), run_time=0.3) + b.play(Write(q), doors[1].face.animate.set_stroke(CELESTE, 10), + doors[1].num.animate.set_color(CELESTE), run_time=1.0) + + with self.beat(5) as b: + fifty = Text("50% / 50%", font=FONT, font_size=68, weight=BOLD, color=GRIS) + fifty.move_to(DOWN * 1.5) + cross = VGroup( + Line(fifty.get_corner(UL), fifty.get_corner(DR), stroke_width=14, color=ROSA), + Line(fifty.get_corner(DL), fifty.get_corner(UR), stroke_width=14, color=ROSA), + ) + b.play(FadeIn(fifty), run_time=0.5) + b.wait(0.6) + b.play(Create(cross), run_time=0.6) + b.play(FadeOut(VGroup(fifty, cross, q)), run_time=0.5) + + with self.beat(6) as b: + f1 = MathTex(r"\tfrac{1}{3}", color=AMBAR).scale(2.6).next_to(doors[0], DOWN, buff=0.7) + cap1 = Text("lo que tenías al elegir", font=FONT, font_size=34, color=GRIS) + cap1.next_to(f1, DOWN, buff=0.45).set_x(0) + b.play(Write(f1), run_time=0.8) + b.play(FadeIn(cap1), run_time=0.5) + + with self.beat(7) as b: + brace = Brace(VGroup(doors[1], doors[2]), DOWN, color=CELESTE, buff=0.28) + f2 = MathTex(r"\tfrac{2}{3}", color=CELESTE).scale(2.6).next_to(brace, DOWN, buff=0.25) + b.play(FadeOut(cap1), run_time=0.25) + b.play(GrowFromCenter(brace), run_time=0.5) + b.play(Write(f2), run_time=0.7) + + with self.beat(8) as b: + dest = f1.get_center() + RIGHT * (XS[1] - XS[0]) + b.play(FadeOut(brace), run_time=0.3) + b.play(f2.animate.move_to(dest), run_time=1.2) + b.play(Flash(f2, color=CELESTE, line_length=0.6, num_lines=18, flash_radius=1.4), + doors[1].face.animate.set_fill("#123A57", 1), run_time=0.9) + + with self.beat(9) as b: + b.play(FadeOut(VGroup(doors, f1, f2, goat)), run_time=0.5) + rows = [] + for lbl, pct, col in (("QUEDARSE", 0.333, ROSA), ("CAMBIAR", 0.667, VERDE)): + name = Text(lbl, font=FONT, font_size=46, weight=BOLD, color=col) + track = RoundedRectangle(corner_radius=0.12, width=7.0, height=0.85, stroke_width=0, + fill_color="#1B2233", fill_opacity=1) + fill = RoundedRectangle(corner_radius=0.12, width=7.0 * pct, height=0.85, + stroke_width=0, fill_color=col, fill_opacity=1) + fill.move_to(track.get_left(), LEFT) + val = Text(f"{round(pct*100)}%", font=FONT, font_size=58, weight=BOLD, color=col) + rows.append(VGroup(name, VGroup(track, fill), val).arrange(DOWN, buff=0.25)) + board = VGroup(*rows).arrange(DOWN, buff=1.0).move_to(UP * 2.2) + b.play(*[FadeIn(r[0]) for r in rows], *[FadeIn(r[1][0]) for r in rows], run_time=0.5) + for r in rows: + f, w = r[1][1], r[1][1].width + f.stretch_to_fit_width(0.002).move_to(r[1][0].get_left(), LEFT) + b.play(f.animate.stretch_to_fit_width(w).move_to(r[1][0].get_left(), LEFT), + FadeIn(r[2]), run_time=0.8) + b.wait(0.3) + + with self.beat(10) as b: + cta = self.fit(Text("CAMBIÁ SIEMPRE", font=FONT, font_size=70, + weight=BOLD, color=AMBAR), 7.9).move_to(DOWN * 1.9) + b.play(Write(cta), run_time=0.9) + b.play(Circumscribe(cta, color=AMBAR, buff=0.35, stroke_width=8), run_time=1.1) + + self.finish() -- cgit v1.2.3