def __init__(self, mob_or_text, **kwargs): digest_config(self, kwargs) if isinstance(mob_or_text, str): mobject = TextMobject(mob_or_text) else: mobject = mob_or_text if "run_time" not in kwargs: self.establish_run_time(mobject) if "lag_factor" not in kwargs: if len(mobject.family_members_with_points()) < 4: min_lag_factor = 1 else: min_lag_factor = 2 self.lag_factor = max(self.run_time - 1, min_lag_factor) DrawBorderThenFill.__init__(self, mobject, **kwargs)
def get_corner_numbers(self, value, symbol): value_mob = TextMobject(value) width = self.get_width() / self.card_width_to_corner_num_width height = self.get_height() / self.card_height_to_corner_num_height value_mob.set_width(width) value_mob.stretch_to_fit_height(height) value_mob.next_to(self.get_corner(UP + LEFT), DOWN + RIGHT, buff=MED_LARGE_BUFF * width) value_mob.set_color(symbol.get_color()) corner_symbol = symbol.copy() corner_symbol.set_width(width) corner_symbol.next_to(value_mob, DOWN, buff=MED_SMALL_BUFF * width) corner_group = VGroup(value_mob, corner_symbol) opposite_corner_group = corner_group.copy() opposite_corner_group.rotate(np.pi, about_point=self.get_center()) return VGroup(corner_group, opposite_corner_group)
def setup(self): MovingCameraScene.setup(self) frame = self.camera_frame frame.shift(DOWN) self.logo = Logo() name = TextMobject("3Blue1Brown") name.scale(2.5) name.next_to(self.logo, DOWN, buff=MED_LARGE_BUFF) name.set_sheen(-0.2, DR) self.channel_name = name
def add_title(self, title="Sample space", buff=MED_SMALL_BUFF): # TODO, should this really exist in SampleSpaceScene title_mob = TextMobject(title) if title_mob.get_width() > self.get_width(): title_mob.set_width(self.get_width()) title_mob.next_to(self, UP, buff=buff) self.title = title_mob self.add(title_mob)
def add_title(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)
def get_bubble(self, *content, **kwargs): bubble_class = kwargs.get("bubble_class", ThoughtBubble) bubble = bubble_class(**kwargs) if len(content) > 0: if isinstance(content[0], str): content_mob = TextMobject(*content) else: content_mob = content[0] bubble.add_content(content_mob) if "height" not in kwargs and "width" not in kwargs: bubble.resize_to_content() bubble.pin_to(self) self.bubble = bubble return bubble
def add_title(self, title, scale_factor=1.5, animate=False): if not isinstance(title, Mobject): title = TextMobject(title).scale(scale_factor) title.to_edge(UP) title.add_background_rectangle() if animate: self.play(Write(title)) self.add_foreground_mobject(title) self.title = title return self
def get_det_text(matrix, determinant=None, background_rect=True, initial_scale_factor=2): parens = TexMobject(["(", ")"]) parens.scale(initial_scale_factor) parens.stretch_to_fit_height(matrix.get_height()) l_paren, r_paren = parens.split() l_paren.next_to(matrix, LEFT, buff=0.1) r_paren.next_to(matrix, RIGHT, buff=0.1) det = TextMobject("det") det.scale(initial_scale_factor) det.next_to(l_paren, LEFT, buff=0.1) if background_rect: det.add_background_rectangle() det_text = VMobject(det, l_paren, r_paren) if determinant is not None: eq = TexMobject("=") eq.next_to(r_paren, RIGHT, buff=0.1) result = TexMobject(str(determinant)) result.next_to(eq, RIGHT, buff=0.2) det_text.add(eq, result) return det_text
def setup_axes(self, animate=False): # TODO, once eoc is done, refactor this to be less redundant. x_num_range = float(self.x_max - self.x_min) self.space_unit_to_x = self.x_axis_width / x_num_range if self.x_labeled_nums is None: self.x_labeled_nums = [] if self.x_leftmost_tick is None: self.x_leftmost_tick = self.x_min x_axis = NumberLine(x_min=self.x_min, x_max=self.x_max, unit_size=self.space_unit_to_x, tick_frequency=self.x_tick_frequency, leftmost_tick=self.x_leftmost_tick, numbers_with_elongated_ticks=self.x_labeled_nums, color=self.axes_color) x_axis.shift(self.graph_origin - x_axis.number_to_point(0)) if len(self.x_labeled_nums) > 0: if self.exclude_zero_label: self.x_labeled_nums = [ x for x in self.x_labeled_nums if x != 0 ] x_axis.add_numbers(*self.x_labeled_nums) if self.x_axis_label: x_label = TextMobject(self.x_axis_label) x_label.next_to(x_axis.get_tick_marks(), UP + RIGHT, buff=SMALL_BUFF) x_label.shift_onto_screen() x_axis.add(x_label) self.x_axis_label_mob = x_label y_num_range = float(self.y_max - self.y_min) self.space_unit_to_y = self.y_axis_height / y_num_range if self.y_labeled_nums is None: self.y_labeled_nums = [] if self.y_bottom_tick is None: self.y_bottom_tick = self.y_min y_axis = NumberLine( x_min=self.y_min, x_max=self.y_max, unit_size=self.space_unit_to_y, tick_frequency=self.y_tick_frequency, leftmost_tick=self.y_bottom_tick, numbers_with_elongated_ticks=self.y_labeled_nums, color=self.axes_color, line_to_number_vect=LEFT, ) y_axis.shift(self.graph_origin - y_axis.number_to_point(0)) y_axis.rotate(np.pi / 2, about_point=y_axis.number_to_point(0)) if len(self.y_labeled_nums) > 0: if self.exclude_zero_label: self.y_labeled_nums = [ y for y in self.y_labeled_nums if y != 0 ] y_axis.add_numbers(*self.y_labeled_nums) if self.y_axis_label: y_label = TextMobject(self.y_axis_label) y_label.next_to(y_axis.get_tick_marks(), UP + RIGHT, buff=SMALL_BUFF) y_label.shift_onto_screen() y_axis.add(y_label) self.y_axis_label_mob = y_label if animate: self.play(Write(VGroup(x_axis, y_axis))) else: self.add(x_axis, y_axis) self.x_axis, self.y_axis = self.axes = VGroup(x_axis, y_axis) self.default_graph_colors = it.cycle(self.default_graph_colors)
def get_text(self, *text, **kwargs): text_mob = TextMobject(*text) self.put_at_tip(text_mob, **kwargs) return text_mob
def write(self, *text): self.add_content(TextMobject(*text)) return self
def get_author(self, quote): author = TextMobject(self.text_size + " --" + self.author) author.next_to(quote, DOWN, buff=self.author_buff) author.set_color(YELLOW) return author
def get_quote(self, max_width=FRAME_WIDTH - 1): text_mobject_kwargs = { "alignment": "", "arg_separator": self.quote_arg_separator, } if isinstance(self.quote, str): if self.use_quotation_marks: quote = TextMobject("``%s''" % self.quote.strip(), **text_mobject_kwargs) else: quote = TextMobject("%s" % self.quote.strip(), **text_mobject_kwargs) else: if self.use_quotation_marks: words = [self.text_size + " ``"] + list(self.quote) + ["''"] else: words = [self.text_size] + 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: quote.set_color_by_tex(term, color) quote.to_edge(UP, buff=self.top_buff) if quote.get_width() > max_width: quote.set_width(max_width) return quote
def construct(self): self.add(TextMobject("TODO: %s" % self.message)) self.wait()
def scroll_through_patrons(self): logo_box = Square(side_length=2.5) logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF) total_width = FRAME_X_RADIUS - logo_box.get_right()[0] black_rect = Rectangle( fill_color=BLACK, fill_opacity=1, stroke_width=0, width=FRAME_WIDTH, height=0.6 * FRAME_HEIGHT, ) black_rect.to_edge(UP, buff=0) line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT) line.move_to(ORIGIN) self.add(line) thanks = TextMobject( "Funded by the community, with special thanks to:") thanks.scale(0.9) thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF) thanks.set_color(YELLOW) underline = Line(LEFT, RIGHT) underline.set_width(thanks.get_width() + MED_SMALL_BUFF) underline.next_to(thanks, DOWN, SMALL_BUFF) thanks.add(underline) self.add(thanks) patrons = VGroup(*list(map(TextMobject, self.specific_patrons))) patrons.scale(self.patron_scale_val) for patron in patrons: if patron.get_width() > self.max_patron_width: patron.set_width(self.max_patron_width) columns = VGroup(*[ VGroup(*patrons[i::self.n_patron_columns]) for i in range(self.n_patron_columns) ]) for column in columns: for n, name in enumerate(column): name.shift(n * self.name_y_spacing * DOWN) columns.arrange_submobjects( RIGHT, buff=LARGE_BUFF, aligned_edge=UP, ) columns.set_width(total_width - 1) columns.next_to(black_rect, DOWN, 3 * LARGE_BUFF) columns.to_edge(RIGHT) thanks.align_to(columns, alignment_vect=RIGHT) self.play( columns.move_to, 2 * DOWN, DOWN, columns.to_edge, RIGHT, Animation(black_rect), Animation(line), Animation(thanks), rate_func=None, run_time=self.run_time, )