3b1b-manim/topics/common_scenes.py

169 lines
4.9 KiB
Python
Raw Normal View History

2017-03-08 15:18:09 -08:00
from helpers import *
from scene.scene import Scene
from animation.simple_animations import Write, DrawBorderThenFill, LaggedStart
2017-04-14 23:30:29 -07:00
from animation.transform import FadeIn, FadeOut, ApplyMethod
2017-03-08 15:18:09 -08:00
from mobject.vectorized_mobject import VGroup
from mobject.tex_mobject import TexMobject, TextMobject
from topics.characters import Mortimer, Blink
from topics.objects import PatreonLogo
class OpeningQuote(Scene):
CONFIG = {
2017-03-29 16:06:10 -07:00
"quote" : [],
2017-03-22 15:06:17 -07:00
"quote_arg_separator" : " ",
2017-03-29 16:06:10 -07:00
"highlighted_quote_terms" : {},
"author" : "",
2017-03-08 15:18:09 -08:00
"fade_in_kwargs" : {
"submobject_mode" : "lagged_start",
"rate_func" : None,
2017-03-22 15:06:17 -07:00
"lag_factor" : 4,
2017-03-08 15:18:09 -08:00
"run_time" : 5,
},
}
def construct(self):
2017-04-12 09:06:04 -07:00
self.quote = self.get_quote()
self.author = self.get_author(self.quote)
2017-03-08 15:18:09 -08:00
2017-04-12 09:06:04 -07:00
self.play(FadeIn(self.quote, **self.fade_in_kwargs))
2017-03-08 15:18:09 -08:00
self.dither(2)
2017-04-12 09:06:04 -07:00
self.play(Write(self.author, run_time = 3))
2017-03-08 15:18:09 -08:00
self.dither()
def get_quote(self, max_width = 2*SPACE_WIDTH-1):
2017-03-22 15:06:17 -07:00
text_mobject_kwargs = {
"alignment" : "",
"arg_separator" : self.quote_arg_separator,
}
2017-03-08 15:18:09 -08:00
if isinstance(self.quote, str):
2017-03-22 15:06:17 -07:00
quote = TextMobject("``%s''"%self.quote.strip(), **text_mobject_kwargs)
2017-03-08 15:18:09 -08:00
else:
words = ["\\Large ``"] + list(self.quote) + ["''"]
2017-03-22 15:06:17 -07:00
quote = TextMobject(*words, **text_mobject_kwargs)
2017-03-08 15:18:09 -08:00
##TODO, make less hacky
if self.quote_arg_separator == " ":
quote[0].shift(0.2*RIGHT)
quote[-1].shift(0.2*LEFT)
2017-03-08 15:18:09 -08:00
for term, color in self.highlighted_quote_terms.items():
quote.highlight_by_tex(term, color)
quote.to_edge(UP)
if quote.get_width() > max_width:
quote.scale_to_fit_width(max_width)
return quote
def get_author(self, quote):
author = TextMobject("\\Large -" + self.author)
2017-03-08 15:18:09 -08:00
author.next_to(quote, DOWN)
author.highlight(YELLOW)
return author
class PatreonThanks(Scene):
CONFIG = {
"specific_patrons" : [
"Ali Yahya",
2017-08-02 11:58:54 -07:00
"Meshal Alshammari",
2017-03-08 15:18:09 -08:00
"CrypticSwarm ",
"Justin Helps",
"Ankit Agarwal",
2017-08-02 11:58:54 -07:00
"Yu Jun",
"Shelby Doolittle",
"Dave Nicponski",
"Damion Kistler",
"Juan Benet",
"Othman Alikhan",
"Markus Persson",
2017-03-08 15:18:09 -08:00
"Dan Buchoff",
"Derek Dai",
2017-08-02 11:58:54 -07:00
"Joseph John Cox",
2017-03-08 15:18:09 -08:00
"Luc Ritchie",
"Nils Schneider",
"Mathew Bramson",
2017-08-02 11:58:54 -07:00
"Guido Gambardella",
"Jerry Ling",
"Mark Govea",
2017-03-08 15:18:09 -08:00
"Vecht",
"Shimin Kuang",
2017-08-02 11:58:54 -07:00
"Rish Kundalia",
2017-03-08 15:18:09 -08:00
"Achille Brighton",
2017-08-02 11:58:54 -07:00
"Kirk Werklund",
"Ripta Pasay",
"Felipe Diniz",
2017-03-08 15:18:09 -08:00
],
"max_patron_group_size" : 20,
2017-07-05 19:21:24 -07:00
"patron_scale_val" : 0.8,
2017-04-14 23:30:29 -07:00
2017-03-08 15:18:09 -08:00
}
def construct(self):
morty = Mortimer()
morty.next_to(ORIGIN, DOWN)
patreon_logo = PatreonLogo()
patreon_logo.to_edge(UP)
2017-03-08 15:18:09 -08:00
n_patrons = len(self.specific_patrons)
2017-04-14 23:30:29 -07:00
patrons = map(TextMobject, self.specific_patrons)
num_groups = float(len(patrons)) / self.max_patron_group_size
2017-04-20 13:30:51 -07:00
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_submobjects(DOWN, aligned_edge = LEFT)
subgroup.scale(self.patron_scale_val)
subgroup.to_edge(vect)
last_group = None
2017-04-14 23:30:29 -07:00
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(
LaggedStart(
FadeIn, group,
run_time = 2,
2017-04-14 23:30:29 -07:00
),
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))
2017-04-14 23:30:29 -07:00
self.play(Blink(morty))
last_group = group
2017-03-08 15:18:09 -08:00
2017-06-20 14:05:48 -07:00
class ExternallyAnimatedScene(Scene):
def construct(self):
raise Exception("Don't actually run this class.")
2017-03-08 15:18:09 -08:00