Files
manim/topics/common_scenes.py
2017-11-02 22:58:54 -07:00

146 lines
4.3 KiB
Python

from helpers import *
from scene.scene import Scene
from animation.simple_animations import Write, DrawBorderThenFill, LaggedStart
from animation.transform import FadeIn, FadeOut, ApplyMethod
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 = {
"quote" : [],
"quote_arg_separator" : " ",
"highlighted_quote_terms" : {},
"author" : "",
"fade_in_kwargs" : {
"submobject_mode" : "lagged_start",
"rate_func" : None,
"lag_factor" : 4,
"run_time" : 5,
},
}
def construct(self):
self.quote = self.get_quote()
self.author = self.get_author(self.quote)
self.play(FadeIn(self.quote, **self.fade_in_kwargs))
self.dither(2)
self.play(Write(self.author, run_time = 3))
self.dither()
def get_quote(self, max_width = 2*SPACE_WIDTH-1):
text_mobject_kwargs = {
"alignment" : "",
"arg_separator" : self.quote_arg_separator,
}
if isinstance(self.quote, str):
quote = TextMobject("``%s''"%self.quote.strip(), **text_mobject_kwargs)
else:
words = ["\\Large ``"] + list(self.quote) + ["''"]
quote = TextMobject(*words, **text_mobject_kwargs)
##TODO, make less hacky
if self.quote_arg_separator == " ":
quote[0].shift(0.2*RIGHT)
quote[-1].shift(0.2*LEFT)
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)
author.next_to(quote, DOWN)
author.highlight(YELLOW)
return author
class PatreonThanks(Scene):
CONFIG = {
"specific_patrons" : [],
"max_patron_group_size" : 20,
"patron_scale_val" : 0.8,
}
def construct(self):
morty = Mortimer()
morty.next_to(ORIGIN, DOWN)
patreon_logo = PatreonLogo()
patreon_logo.to_edge(UP)
n_patrons = len(self.specific_patrons)
patrons = map(TextMobject, self.specific_patrons)
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_submobjects(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(
LaggedStart(
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
class ExternallyAnimatedScene(Scene):
def construct(self):
raise Exception("Don't actually run this class.")
class TODOStub(Scene):
CONFIG = {
"message" : ""
}
def construct(self):
self.add(TextMobject("TODO: %s"%self.message))
self.dither()