def set_submobjects_from_number(self, number: float | complex) -> None: self.number = number self.set_submobjects([]) self.text_config["font_size"] = self.get_font_size() num_string = self.num_string = self.get_num_string(number) self.add(*(Text(ns, **self.text_config) for ns in num_string)) # Add non-numerical bits if self.show_ellipsis: dots = Text("...", **self.text_config) dots.arrange(RIGHT, buff=2 * dots[0].get_width()) self.add(dots) if self.unit is not None: self.unit_sign = SingleStringTex(self.unit, font_size=self.get_font_size()) self.add(self.unit_sign) self.arrange(buff=self.digit_buff_per_font_unit * self.get_font_size(), aligned_edge=DOWN) # Handle alignment of parts that should be aligned # to the bottom for i, c in enumerate(num_string): if c == "–" and len(num_string) > i + 1: self[i].align_to(self[i + 1], UP) self[i].shift(self[i + 1].get_height() * DOWN / 2) elif c == ",": self[i].shift(self[i].get_height() * DOWN / 2) if self.unit and self.unit.startswith("^"): self.unit_sign.align_to(self, UP) if self.include_background_rectangle: self.add_background_rectangle()
def __init__(self, *text, **kwargs): Text.__init__(self, *text, **kwargs) self.scale(self.scale_factor) self.to_edge(UP) if self.include_underline: underline = Line(LEFT, RIGHT) underline.next_to(self, DOWN, buff=self.underline_buff) if self.match_underline_width_to_text: underline.match_width(self) else: underline.set_width(self.underline_width) self.add(underline) self.underline = underline
def __init__(self, *controls, **kwargs): digest_config(self, kwargs) self.panel = Rectangle(**self.panel_kwargs) self.panel.to_corner(UP + LEFT, buff=0) self.panel.shift(self.panel.get_height() * UP) self.panel.add_mouse_scroll_listner(self.panel_on_mouse_scroll) self.panel_opener_rect = Rectangle(**self.opener_kwargs) self.panel_info_text = Text(**self.opener_text_kwargs) self.panel_info_text.move_to(self.panel_opener_rect) self.panel_opener = Group(self.panel_opener_rect, self.panel_info_text) self.panel_opener.next_to(self.panel, DOWN, aligned_edge=DOWN) self.panel_opener.add_mouse_drag_listner( self.panel_opener_on_mouse_drag) self.controls = Group(*controls) self.controls.arrange(DOWN, center=False, aligned_edge=ORIGIN) self.controls.move_to(self.panel) super().__init__(self.panel, self.panel_opener, self.controls, **kwargs) self.move_panel_and_controls_to_panel_opener() self.fix_in_frame()
def get_new_font_texs(self, replace_dict): for i in range(len(self.tex_strings)): tex = self.tex_strings[i] color = self.get_color_by_tex(tex) if tex in replace_dict: tex = replace_dict[tex] tex_new = Text(tex, font=self.default_font, color=color) tex_new.set_height(self[i].get_height()) # if tex == '-' or tex == '=': # tex_new.set_width(self[i].get_width(), stretch=True) if tex == '-': tex_new.set_width(self[i].get_width(), stretch=True).scale([0.8, 2.4, 1]) elif tex == '=': tex_new.set_width(self[i].get_width(), stretch=True).scale([0.9, 1.35, 1]) tex_new.scale(self.tex_scale_factor) tex_new.move_to(self[i]) if tex == '-': tex_new.shift(UP * 0.5 * tex_new.get_height()) elif tex == '=': tex_new.shift(UP * 0.15 * tex_new.get_height()) self.new_font_texs.add(tex_new) return self.new_font_texs
def paste_selection(self): clipboard_str = pyperclip.paste() # Try pasting a mobject try: ids = map(int, clipboard_str.split(",")) mobs = map(self.id_to_mobject, ids) mob_copies = [m.copy() for m in mobs if m is not None] self.clear_selection() self.add_to_selection(*mob_copies) self.play(*( FadeIn(mc, run_time=0.5, scale=1.5) for mc in mob_copies )) return except ValueError: pass # Otherwise, treat as tex or text if set("\\^=+").intersection(clipboard_str): # Proxy to text for LaTeX try: new_mob = Tex(clipboard_str) except LatexError: return else: new_mob = Text(clipboard_str) self.clear_selection() self.add(new_mob) self.add_to_selection(new_mob)
def on_key_press(self, symbol, modifiers): try: char = chr(symbol) except OverflowError: print(" Warning: The value of the pressed key is too large.") return event_data = {"symbol": symbol, "modifiers": modifiers} propagate_event = EVENT_DISPATCHER.dispatch(EventType.KeyPressEvent, **event_data) if propagate_event is not None and propagate_event is False: return frame = self.camera.frame if char == "r": frame.to_default_state() elif char == "q": self.quit_interaction = True elif char == "p": theta, phi, gamma = frame.get_euler_angles() * 180 / PI if hasattr(self, "info"): self.remove(self.info) self.info = Text( f"(theta,phi,gamma)=({round(theta, 2)},{round(phi, 2)},{round(gamma, 2)})" f"\n\nCenter:{frame.get_center()}" f"\n\nScale:{frame.scale_factor}").scale(0.5) self.info.fix_in_frame() self.info.to_edge(UL) self.add(self.info)
def __init__(self, value="", **kwargs): digest_config(self, kwargs) self.isActive = self.isInitiallyActive self.box = Rectangle(**self.box_kwargs) self.text = Text(value, **self.text_kwargs) super().__init__(value, self.box, self.text, **kwargs) self.update_text(value) self.active_anim(self.isActive)
def create_label(self): for tex, value in zip(self.labels, self.values): i = self.labels.index(tex) r = self.inner_radius + self.outer_radius_func(self.values[i]) size = TAU * r / len(self.values) * 0.2 tex_i = Text(tex, font=self.label_font, color=WHITE, plot_depth=1).set_height(size) value_i = Text(str(value), font=self.label_font, color=WHITE, plot_depth=1).set_height(size).next_to(tex_i, DOWN * 0.64 * size) if not self.unit == None: unit_i = Text(self.unit, font=self.label_font, color=WHITE, plot_depth=1).set_height(size).next_to(value_i, RIGHT * 0.2 * size) VGroup(value_i, unit_i).next_to(tex_i, DOWN * 0.64 * size) label_i = VGroup(tex_i, value_i, unit_i) else: label_i = VGroup(tex_i, value_i) angle = TAU/len(self.values) start_a = np.angle(complex(*self.start_direction[0:2])) self.labels_group.add(label_i.shift(self.center + complex_to_R3((r-size * 1.2-r*0.05) * np.exp(1j * (start_a + (i + 0.5) * TAU/len(self.values)))))) return self.labels_group
def __init__(self, value="", **kwargs): digest_config(self, kwargs) self.isActive = self.isInitiallyActive self.box = Rectangle(**self.box_kwargs) self.box.add_mouse_press_listner(self.box_on_mouse_press) self.text = Text(value, **self.text_kwargs) super().__init__(value, self.box, self.text, **kwargs) self.update_text(value) self.active_anim(self.isActive) self.add_key_press_listner(self.on_key_press)
def __init__(self, value="", **kwargs): digest_config(self, kwargs) self.isActive = self.isInitiallyActive self.box = Rectangle(**self.box_kwargs) self.box.listen_to_events = True self.box.on_mouse_press = self.box_on_mouse_press self.text = Text(value, **self.text_kwargs) super().__init__(value, self.box, self.text, **kwargs) self.update_text(value) self.active_anim(self.isActive)
def Countdown_anim(self, time=5): num = VGroup(*[ Text(str(i), font='思源黑体 Bold', color=GREEN).set_height(1) for i in range(time, 0, -1) ]).to_corner(RIGHT * 1.2 + UP * 1.2, buff=1) circle = Circle(radius=0.9).move_to(num).set_stroke(GREEN, 12) for i in range(time): self.add(num[i]) self.play(WiggleOutThenIn(num[i]), ShowCreationThenDestruction(circle), run_time=1) self.remove(num[i])
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 = Text(content) else: content_mob = content 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 get_text(self, text: str, **kwargs) -> Text: buff = kwargs.pop("buff", SMALL_BUFF) text_mob = Text(text, **kwargs) self.put_at_tip(text_mob, buff=buff) return text_mob
def get_indices(self, mob): for index in range(len(mob)): direction = UP if index == 0 or index % 2 == 0 else DOWN self.play(Write(Text(f"{index}", size=0.19,opacity=0.3)\ .next_to(mob[index], direction)))
def get_indices(self, mob,size=0.19): for index in range(len(mob)): direction = UP if index == 0 or index % 2 == 0 else DOWN self.play(Write(Text(f"{index}", size=size, opacity=0.3,stroke_width=0.3,color=RED) .next_to(mob[index], direction)))
def get_text(self, text, **kwargs): text_mob = Text(text) self.put_at_tip(text_mob, **kwargs) return text_mob