def __init__(self, file_name=None, **kwargs): Container.__init__(self, **kwargs) self.file_name = file_name or self.file_name self.ensure_valid_file() self.style = self.style.lower() self.gen_html_string() strati = self.html_string.find("background:") self.background_color = self.html_string[strati + 12:strati + 19] self.gen_code_json() self.code = self.gen_colored_lines() if self.insert_line_no: self.line_numbers = self.gen_line_numbers() self.line_numbers.next_to(self.code, direction=LEFT, buff=self.line_no_buff) if self.background == "rectangle": if self.insert_line_no: forground = VGroup(self.code, self.line_numbers) else: forground = self.code self.background_mobject = SurroundingRectangle(forground, buff=self.margin, color=self.background_color, fill_color=self.background_color, stroke_width=0, fill_opacity=1, ) self.background_mobject.round_corners(self.corner_radius) else: if self.insert_line_no: forground = VGroup(self.code, self.line_numbers) else: forground = self.code height = forground.get_height() + 0.1 * 3 + 2 * self.margin width = forground.get_width() + 0.1 * 3 + 2 * self.margin rrect = RoundedRectangle(corner_radius=self.corner_radius, height=height, width=width, stroke_width=0, color=self.background_color, fill_opacity=1) button_radius = 0.09 red_button = Dot(radius=button_radius, stroke_width=0, color='#ff5f56') red_button.shift(LEFT * button_radius * 3) yellow_button = Dot(radius=button_radius, stroke_width=0, color='#ffbd2e') green_button = Dot(radius=button_radius, stroke_width=0, color='#27c93f') green_button.shift(RIGHT * button_radius * 3) buttons = VGroup(red_button, yellow_button, green_button) buttons.shift( UP * (height / 2 - 0.1 * 2 - 0.05) + LEFT * (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05)) self.background_mobject = VGroup(rrect, buttons) x = (height - forground.get_height()) / 2 - 0.1 * 3 self.background_mobject.shift(forground.get_center()) self.background_mobject.shift(UP * x) if self.insert_line_no: VGroup.__init__(self, self.background_mobject, self.line_numbers, *self.code, **kwargs) else: VGroup.__init__(self, self.background_mobject, Dot(fill_opacity=0, stroke_opacity=0), *self.code, **kwargs) self.move_to(np.array([0, 0, 0]))
def create_eyes(self, mode=None, thing_to_look_at=None): if mode is None: mode = self.mode if thing_to_look_at is None: thing_to_look_at = self.thing_to_look_at self.thing_to_look_at = thing_to_look_at self.mode = mode looking_direction = None pi = PiCreature(mode=mode) eyes = VGroup(pi.eyes, pi.pupils) if self.submobjects: eyes.match_height(self) eyes.move_to(self, DOWN) looking_direction = self[1].get_center() - self[0].get_center() else: eyes.set_height(self.height) eyes.move_to(self.body.get_top(), DOWN) height = eyes.get_height() if thing_to_look_at is not None: pi.look_at(thing_to_look_at) elif looking_direction is not None: pi.look(looking_direction) eyes.set_height(height) return eyes
def create_eyes(self, mode=None, thing_to_look_at=None): if mode is None: mode = self.mode if thing_to_look_at is None: thing_to_look_at = self.thing_to_look_at self.thing_to_look_at = thing_to_look_at self.mode = mode looking_direction = None pi = PiCreature(mode=mode) eyes = VGroup(pi.eyes, pi.pupils) if self.submobjects: eyes.match_height(self) eyes.move_to(self, DOWN) looking_direction = self[1].get_center() - self[0].get_center() else: eyes.set_height(self.height) eyes.move_to(self.body.get_top(), DOWN) height = eyes.get_height() if thing_to_look_at is not None: pi.look_at(thing_to_look_at) elif looking_direction is not None: pi.look(looking_direction) eyes.set_height(height) return eyes
def get_secant_slope_group( self, x, graph, dx=None, dx_line_color=None, df_line_color=None, dx_label=None, df_label=None, include_secant_line=True, secant_line_color=None, secant_line_length=10, ): """ This method returns a VGroup of (two lines representing dx and df, the labels for dx and df, and the Secant to the Graph/curve at a particular x value. Parameters ---------- x (Union[float, int]) The x value at which the secant enters, and intersects the graph for the first time. graph (ParametricFunction) The curve/graph for which the secant must be found. dx (Union[float, int]) The change in x after which the secant exits. dx_line_color (str) The line color for the line that indicates the change in x. df_line_color (str) The line color for the line that indicates the change in y. dx_label (str) The label to be provided for the change in x. df_label (str) The label to be provided for the change in y. include_secant_line (bool=True) Whether or not to include the secant line in the graph, or just have the df and dx lines and labels. secant_line_color (str) The color of the secant line. secant_line_length (Union[float,int=10]) How long the secant line should be. Returns: -------- VGroup Resulting group is of the form VGroup( dx_line, df_line, dx_label, (if applicable) df_label, (if applicable) secant_line, (if applicable) ) with attributes of those names. """ kwargs = locals() kwargs.pop("self") group = VGroup() group.kwargs = kwargs dx = dx or float(self.x_max - self.x_min) / 10 dx_line_color = dx_line_color or self.default_input_color df_line_color = df_line_color or graph.get_color() p1 = self.input_to_graph_point(x, graph) p2 = self.input_to_graph_point(x + dx, graph) interim_point = p2[0] * RIGHT + p1[1] * UP group.dx_line = Line(p1, interim_point, color=dx_line_color) group.df_line = Line(interim_point, p2, color=df_line_color) group.add(group.dx_line, group.df_line) labels = VGroup() if dx_label is not None: group.dx_label = TexMobject(dx_label) labels.add(group.dx_label) group.add(group.dx_label) if df_label is not None: group.df_label = TexMobject(df_label) labels.add(group.df_label) group.add(group.df_label) if len(labels) > 0: max_width = 0.8 * group.dx_line.get_width() max_height = 0.8 * group.df_line.get_height() if labels.get_width() > max_width: labels.set_width(max_width) if labels.get_height() > max_height: labels.set_height(max_height) if dx_label is not None: group.dx_label.next_to(group.dx_line, np.sign(dx) * DOWN, buff=group.dx_label.get_height() / 2) group.dx_label.set_color(group.dx_line.get_color()) if df_label is not None: group.df_label.next_to(group.df_line, np.sign(dx) * RIGHT, buff=group.df_label.get_height() / 2) group.df_label.set_color(group.df_line.get_color()) if include_secant_line: secant_line_color = secant_line_color or self.default_derivative_color group.secant_line = Line(p1, p2, color=secant_line_color) group.secant_line.scale_in_place(secant_line_length / group.secant_line.get_length()) group.add(group.secant_line) return group
def get_secant_slope_group( self, x, graph, dx=None, dx_line_color=None, df_line_color=None, dx_label=None, df_label=None, include_secant_line=True, secant_line_color=None, secant_line_length=10, ): """ Resulting group is of the form VGroup( dx_line, df_line, dx_label, (if applicable) df_label, (if applicable) secant_line, (if applicable) ) with attributes of those names. """ kwargs = locals() kwargs.pop("self") group = VGroup() group.kwargs = kwargs dx = dx or float(self.x_max - self.x_min) / 10 dx_line_color = dx_line_color or self.default_input_color df_line_color = df_line_color or graph.get_color() p1 = self.input_to_graph_point(x, graph) p2 = self.input_to_graph_point(x + dx, graph) interim_point = p2[0] * RIGHT + p1[1] * UP group.dx_line = Line(p1, interim_point, color=dx_line_color) group.df_line = Line(interim_point, p2, color=df_line_color) group.add(group.dx_line, group.df_line) labels = VGroup() if dx_label is not None: group.dx_label = TexMobject(dx_label) labels.add(group.dx_label) group.add(group.dx_label) if df_label is not None: group.df_label = TexMobject(df_label) labels.add(group.df_label) group.add(group.df_label) if len(labels) > 0: max_width = 0.8 * group.dx_line.get_width() max_height = 0.8 * group.df_line.get_height() if labels.get_width() > max_width: labels.set_width(max_width) if labels.get_height() > max_height: labels.set_height(max_height) if dx_label is not None: group.dx_label.next_to(group.dx_line, np.sign(dx) * DOWN, buff=group.dx_label.get_height() / 2) group.dx_label.set_color(group.dx_line.get_color()) if df_label is not None: group.df_label.next_to(group.df_line, np.sign(dx) * RIGHT, buff=group.df_label.get_height() / 2) group.df_label.set_color(group.df_line.get_color()) if include_secant_line: secant_line_color = secant_line_color or self.default_derivative_color group.secant_line = Line(p1, p2, color=secant_line_color) group.secant_line.scale_in_place(secant_line_length / group.secant_line.get_length()) group.add(group.secant_line) return group
def construct(self): # Add title title = self.title = TextMobject("Clicky Stuffs") title.scale(1.5) title.to_edge(UP, buff=MED_SMALL_BUFF) pi_creatures = VGroup(Randolph(), Mortimer()) for pi, vect in zip(pi_creatures, [LEFT, 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(title, pi_creatures) # Set the top of the screen logo_box = Square(side_length=2.5) logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF) black_rect = Rectangle( fill_color=BLACK, fill_opacity=1, stroke_width=3, stroke_color=BLACK, 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) # Add thanks thanks = TextMobject(self.thanks_words) thanks.scale(0.9) thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF) thanks.set_color(YELLOW) underline = Line(LEFT, RIGHT) underline.match_width(thanks) underline.scale(1.1) underline.next_to(thanks, DOWN, SMALL_BUFF) thanks.add(underline) # Build name list file_name = os.path.join(get_directories()["data"], "patrons.txt") with open(file_name, "r") as fp: names = [ self.modify_patron_name(name.strip()) for name in fp.readlines() ] if self.randomize_order: random.shuffle(names) else: names.sort() name_labels = VGroup(*map(TextMobject, names)) name_labels.scale(self.patron_scale_val) for label in name_labels: if label.get_width() > self.max_patron_width: label.set_width(self.max_patron_width) columns = VGroup(*[ VGroup(*name_labels[i::self.n_patron_columns]) for i in range(self.n_patron_columns) ]) column_x_spacing = 0.5 + max([c.get_width() for c in columns]) for i, column in enumerate(columns): for n, name in enumerate(column): name.shift(n * self.name_y_spacing * DOWN) name.align_to(ORIGIN, LEFT) column.move_to(i * column_x_spacing * RIGHT, UL) columns.center() max_width = FRAME_WIDTH - 1 if columns.get_width() > max_width: columns.set_width(max_width) underline.match_width(columns) columns.next_to(underline, DOWN, buff=3) # Set movement columns.generate_target() distance = columns.get_height() + 2 wait_time = self.scroll_time frame = self.camera.frame frame_shift = ApplyMethod( frame.shift, distance * DOWN, run_time=wait_time, rate_func=linear, ) blink_anims = [] blank_mob = Mobject() for x in range(wait_time): if random.random() < 0.25: blink_anims.append(Blink(random.choice(pi_creatures))) else: blink_anims.append(Animation(blank_mob)) blinks = Succession(*blink_anims) static_group = VGroup(black_rect, line, thanks, pi_creatures, title) static_group.fix_in_frame() self.add(columns, static_group) self.play(frame_shift, blinks)
def get_secant_slope_group( self, x, graph, dx=None, dx_line_color=None, df_line_color=None, dx_label=None, df_label=None, include_secant_line=True, secant_line_color=None, secant_line_length=10, ): """ Resulting group is of the form VGroup( dx_line, df_line, dx_label, (if applicable) df_label, (if applicable) secant_line, (if applicable) ) with attributes of those names. """ kwargs = locals() kwargs.pop("self") group = VGroup() group.kwargs = kwargs dx = dx or float(self.x_max - self.x_min) / 10 dx_line_color = dx_line_color or self.default_input_color df_line_color = df_line_color or graph.get_color() p1 = self.input_to_graph_point(x, graph) p2 = self.input_to_graph_point(x + dx, graph) interim_point = p2[0] * RIGHT + p1[1] * UP group.dx_line = Line( p1, interim_point, color=dx_line_color ) group.df_line = Line( interim_point, p2, color=df_line_color ) group.add(group.dx_line, group.df_line) labels = VGroup() if dx_label is not None: group.dx_label = TexMobject(dx_label) labels.add(group.dx_label) group.add(group.dx_label) if df_label is not None: group.df_label = TexMobject(df_label) labels.add(group.df_label) group.add(group.df_label) if len(labels) > 0: max_width = 0.8 * group.dx_line.get_width() max_height = 0.8 * group.df_line.get_height() if labels.get_width() > max_width: labels.set_width(max_width) if labels.get_height() > max_height: labels.set_height(max_height) if dx_label is not None: group.dx_label.next_to( group.dx_line, np.sign(dx) * DOWN, buff=group.dx_label.get_height() / 2 ) group.dx_label.set_color(group.dx_line.get_color()) if df_label is not None: group.df_label.next_to( group.df_line, np.sign(dx) * RIGHT, buff=group.df_label.get_height() / 2 ) group.df_label.set_color(group.df_line.get_color()) if include_secant_line: secant_line_color = secant_line_color or self.default_derivative_color group.secant_line = Line(p1, p2, color=secant_line_color) group.secant_line.scale_in_place( secant_line_length / group.secant_line.get_length() ) group.add(group.secant_line) return group
class Code(VGroup): CONFIG = { "tab_width": 1, "line_spacing": 0.3, # space between the lines "scale_factor": 0.4, "run_time": 1, #"font": 'Monospac821 BT', #"font": 'Arial', #"font": "DejaVu Sans Mono", "font": "Courier New", #"font": 'Courier New', "font_size": 48, 'stroke_width': 0, 'margin': 0.3, 'indentation_char': " ", "background": "window", #rectangle or window "corner_radius": 0.2, 'insert_line_no': True, 'line_no_from': 1, "line_no_buff": 0.4, 'style': 'railscasts', #white based:railscasts, vim , material, native; black based: tango, xcode ; #pink-based: paraiso-light; styles not highlithing print() and list(): monokai, fruity, paraiso-dark #grey-based: arduino, solarized-dark, solarized-light #beige-based: inkpot, zenburn 'language': 'python', 'generate_html_file': False, 'adapting_x': False, 'adapting_y': False, 'center_y': True, } def __init__(self, file_name=None, code_str=None, **kwargs): Container.__init__(self, **kwargs) self.file_name = file_name self.code_str = code_str self.ensure_valid_file() self.style = self.style.lower() self.gen_html_string() strati = self.html_string.find("background:") self.background_color = self.html_string[strati + 12:strati + 19] self.gen_code_json() self.code = self.gen_colored_lines() if self.insert_line_no: self.line_numbers = self.gen_line_numbers() self.line_numbers.next_to(self.code, direction=LEFT, buff=self.line_no_buff) if self.background == "rectangle": if self.insert_line_no: forground = VGroup(self.code, self.line_numbers) else: forground = self.code self.background_mobject = SurroundingRectangle( forground, buff=self.margin, color=self.background_color, fill_color=self.background_color, stroke_width=0, fill_opacity=1, ) self.background_mobject.round_corners(self.corner_radius) else: if self.insert_line_no: forground = VGroup(self.code, self.line_numbers) else: forground = self.code height = forground.get_height() + 0.1 * 3 + 2 * self.margin width = forground.get_width() + 0.1 * 3 + 2 * self.margin rrect = RoundedRectangle(corner_radius=self.corner_radius, height=height, width=width, stroke_width=0, color=GREY_E, fill_opacity=1) red_button = Dot(radius=0.1, stroke_width=0, color='#ff5f56') red_button.shift(LEFT * 0.1 * 3) yellow_button = Dot(radius=0.1, stroke_width=0, color='#ffbd2e') green_button = Dot(radius=0.1, stroke_width=0, color='#27c93f') green_button.shift(RIGHT * 0.1 * 3) buttons = VGroup(red_button, yellow_button, green_button) buttons.shift( UP * (height / 2 - 0.1 * 2 - 0.05) + LEFT * (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05)) self.background_mobject = VGroup(rrect, buttons) x = (height - forground.get_height()) / 2 - 0.1 * 3 self.background_mobject.shift(forground.get_center()) self.background_mobject.shift(UP * x) if self.insert_line_no: VGroup.__init__(self, self.background_mobject, self.line_numbers, *self.code, **kwargs) else: VGroup.__init__(self, self.background_mobject, Dot(fill_opacity=0, stroke_opacity=0), *self.code, **kwargs) window = RIGHT_SIDE[0] - LEFT_SIDE[0] width = self.background_mobject.get_width() print(width) scale_x = window / width * 0.96 window = TOP[1] - BOTTOM[1] print(window) width = self.background_mobject.get_height() scale_y = window / width * 0.96 if self.adapting_x and scale_x < scale_y: self.scale(scale_x) if self.adapting_y and scale_y <= scale_x: self.scale(scale_y) self.align_to(LEFT_SIDE + self.margin, LEFT) self.align_to( TOP - self.margin + 0.42 * (self.code.char_height + self.code.line_spacing) * self.scale_factor, UP) def FadeInWindow(self): return FadeIn(self.background_mobject), ''' def Write(self): write_code = [Write(line) for line in self.code.lines[0]] write_line_numbers = [Write(number) for number in self.line_numbers.lines[0]] write_all = [item for sublist in zip(write_line_numbers, write_code) for item in sublist] return write_all def ShowCreation(self): write_code = [ShowCreation(line, duration= 1) for line in self.code.lines[0]] write_line_numbers = [ShowCreation(number) for number in self.line_numbers.lines[0]] write_all = [item for sublist in zip(write_line_numbers, write_code) for item in sublist] return write_all ''' def center_to_code(self): if self.center_y: print(self.get_y() - self.code.lines[0][0].get_height() + self.code.line_spacing) self.set_y(self.get_y() + (self.code.char_height + self.code.line_spacing) * self.scale_factor) def apply_points_function_about_point(self, func, about_point=None, about_edge=None): if about_point is None: if about_edge is None: about_edge = self.get_corner(UP + LEFT) about_point = self.get_critical_point(about_edge) for mob in self.family_members_with_points(): mob.points -= about_point mob.points = func(mob.points) mob.points += about_point return self def ensure_valid_file(self): if not self.file_name is None: possible_paths = [ os.path.join(os.path.join("assets", "codes"), self.file_name), self.file_name, ] for path in possible_paths: if os.path.exists(path): self.file_path = path return raise IOError("No file matching %s in codes directory" % self.file_name) def gen_line_numbers(self): line_numbers_array = [] for line_no in range(0, self.code_json.__len__()): number = str(self.line_no_from + line_no) line_numbers_array.append(number) #color ="#E6E8E8" line_numbers = Paragraph( *[i for i in line_numbers_array], line_spacing=self.line_spacing, alignment="left", font=self.font, stroke_width=self.stroke_width, ).scale(self.scale_factor) return line_numbers def gen_colored_lines(self): lines_text = [] for line_no in range(0, self.code_json.__len__()): line_str = "" for word_index in range(self.code_json[line_no].__len__()): line_str = line_str + self.code_json[line_no][word_index][0] lines_text.append(self.tab_spaces[line_no] * "\t" + line_str) #print(lines_text) code = Paragraph(*[text for text in lines_text], line_spacing=self.line_spacing, tab_width=self.tab_width, alignment="left", font=self.font, stroke_width=self.stroke_width, unpack_groups=True).scale(self.scale_factor) for line_no in range(code.__len__()): line = code[line_no] line_char_index = self.tab_spaces[line_no] for word_index in range(self.code_json[line_no].__len__()): line[line_char_index:line_char_index + self. code_json[line_no][word_index][0].__len__()].set_color( self.code_json[line_no][word_index][1]) line_char_index += self.code_json[line_no][word_index][ 0].__len__() #print(self.code_json) return code def gen_html_string(self): if self.file_name: file = open(self.file_path, "r") code_str = file.read() file.close() if self.code_str: code_str = self.code_str self.html_string = hilite_me( code_str, self.language, {}, self.style, self.insert_line_no, "border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;" ) if self.generate_html_file: os.makedirs(os.path.join("assets", "codes", "generated_html_files"), exist_ok=True) file = open( os.path.join("assets", "codes", "generated_html_files", self.file_name + ".html"), "w") file.write(self.html_string) file.close() def gen_code_json(self): #print(self.html_string) if self.background_color == "#111111" or \ self.background_color == "#272822" or \ self.background_color == "#202020" or \ self.background_color == "#000000": self.default_color = "#ffffff" else: self.default_color = "#000000" for i in range(3, -1, -1): self.html_string = self.html_string.replace("</" + " " * i, "</") for i in range(10, -1, -1): self.html_string = self.html_string.replace( "</span>" + " " * i, " " * i + "</span>") self.html_string = self.html_string.replace("background-color:", "background:") if self.insert_line_no: start_point = self.html_string.find("</td><td><pre") start_point = start_point + 9 else: start_point = self.html_string.find("<pre") self.html_string = self.html_string[start_point:] # print(self.html_string) lines = self.html_string.split("\n") lines = lines[0:lines.__len__() - 2] start_point = lines[0].find(">") lines[0] = lines[0][start_point + 1:] # print(lines) self.code_json = [] self.tab_spaces = [] code_json_line_index = -1 #print(self.html_string) starting_string = "" for line_index in range(0, lines.__len__()): if lines[line_index].__len__() == 0: continue #print(lines[line_index]) self.code_json.append([]) code_json_line_index = code_json_line_index + 1 if lines[line_index].startswith(self.indentation_char): start_point = lines[line_index].find("<") starting_string = lines[line_index][:start_point] indentation_char_count = lines[line_index][:start_point].count( self.indentation_char) if starting_string.__len__( ) != indentation_char_count * self.indentation_char.__len__(): lines[line_index] = "\t" * indentation_char_count + starting_string[starting_string.rfind( self.indentation_char) + self.indentation_char.__len__():] + \ lines[line_index][start_point:] else: lines[line_index] = "\t" * indentation_char_count + lines[ line_index][start_point:] indentation_char_count = 0 while lines[line_index][indentation_char_count] == '\t': indentation_char_count = indentation_char_count + 1 self.tab_spaces.append(indentation_char_count) # print(lines[line_index]) lines[line_index] = self.correct_non_span(lines[line_index]) # print(lines[line_index]) words = lines[line_index].split("<span") for word_index in range(1, words.__len__()): color_index = words[word_index].find("color:") if color_index == -1: color = self.default_color else: starti = words[word_index][color_index:].find("#") color = words[word_index][color_index + starti:color_index + starti + 7] start_point = words[word_index].find(">") end_point = words[word_index].find("</span>") text = words[word_index][start_point + 1:end_point] text = html.unescape(text) if text != "": #print(text, "'" + color + "'") self.code_json[code_json_line_index].append([text, color]) #print(self.code_json) def correct_non_span(self, line_str): words = line_str.split("</span>") line_str = "" for i in range(0, words.__len__()): if i != words.__len__() - 1: j = words[i].find("<span") else: j = words[i].__len__() temp = "" starti = -1 for k in range(0, j): if words[i][k] == "\t" and starti == -1: continue else: if starti == -1: starti = k temp = temp + words[i][k] if temp != "": if i != words.__len__() - 1: temp = '<span style="color:' + self.default_color + '">' + words[ i][starti:j] + "</span>" else: temp = '<span style="color:' + self.default_color + '">' + words[ i][starti:j] temp = temp + words[i][j:] words[i] = temp if words[i] != "": line_str = line_str + words[i] + "</span>" return line_str
def __init__(self, file_name=None, code_str=None, **kwargs): Container.__init__(self, **kwargs) self.file_name = file_name self.code_str = code_str self.ensure_valid_file() self.style = self.style.lower() self.gen_html_string() strati = self.html_string.find("background:") self.background_color = self.html_string[strati + 12:strati + 19] self.gen_code_json() self.code = self.gen_colored_lines() if self.insert_line_no: self.line_numbers = self.gen_line_numbers() self.line_numbers.next_to(self.code, direction=LEFT, buff=self.line_no_buff) if self.background == "rectangle": if self.insert_line_no: forground = VGroup(self.code, self.line_numbers) else: forground = self.code self.background_mobject = SurroundingRectangle( forground, buff=self.margin, color=self.background_color, fill_color=self.background_color, stroke_width=0, fill_opacity=1, ) self.background_mobject.round_corners(self.corner_radius) else: if self.insert_line_no: forground = VGroup(self.code, self.line_numbers) else: forground = self.code height = forground.get_height() + 0.1 * 3 + 2 * self.margin width = forground.get_width() + 0.1 * 3 + 2 * self.margin rrect = RoundedRectangle(corner_radius=self.corner_radius, height=height, width=width, stroke_width=0, color=GREY_E, fill_opacity=1) red_button = Dot(radius=0.1, stroke_width=0, color='#ff5f56') red_button.shift(LEFT * 0.1 * 3) yellow_button = Dot(radius=0.1, stroke_width=0, color='#ffbd2e') green_button = Dot(radius=0.1, stroke_width=0, color='#27c93f') green_button.shift(RIGHT * 0.1 * 3) buttons = VGroup(red_button, yellow_button, green_button) buttons.shift( UP * (height / 2 - 0.1 * 2 - 0.05) + LEFT * (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05)) self.background_mobject = VGroup(rrect, buttons) x = (height - forground.get_height()) / 2 - 0.1 * 3 self.background_mobject.shift(forground.get_center()) self.background_mobject.shift(UP * x) if self.insert_line_no: VGroup.__init__(self, self.background_mobject, self.line_numbers, *self.code, **kwargs) else: VGroup.__init__(self, self.background_mobject, Dot(fill_opacity=0, stroke_opacity=0), *self.code, **kwargs) window = RIGHT_SIDE[0] - LEFT_SIDE[0] width = self.background_mobject.get_width() print(width) scale_x = window / width * 0.96 window = TOP[1] - BOTTOM[1] print(window) width = self.background_mobject.get_height() scale_y = window / width * 0.96 if self.adapting_x and scale_x < scale_y: self.scale(scale_x) if self.adapting_y and scale_y <= scale_x: self.scale(scale_y) self.align_to(LEFT_SIDE + self.margin, LEFT) self.align_to( TOP - self.margin + 0.42 * (self.code.char_height + self.code.line_spacing) * self.scale_factor, UP)
def __init__(self, parbs, anibs, sndbs, j_start=1, j_first=None, j_count=None, i_start=1, i_first=None, i_count=None, j_position=GeomPosition([-6.5, 3.3, 0]), j_width=[13], j_height=7, i_position=GeomPosition([0, 3.3, 0]), i_width=[6.75], i_height=7, mobjs=None, scene=None, **kwargs): if j_count is None: j_count = len(parbs[0]) if j_first is None: j_first = j_start if scene is None: scene = V.scene if mobjs is None: mobjs = AnimatedGroup().scale(0.2).post_to(scene) animations = AGroup() if 1 == 1: animations.add( AnimationGroup(Animation(Mobject()), sound=sndbs[0][0], xaction="sound")) animations.add( AnimationGroup(GrowTitle(parbs[0][0]), Freeze(4), anibs[0][0], foreground=True, xaction="post")) j_end = min((j_start + j_count), len(parbs[0]), len(anibs[0])) grpa = VGroup(j_position) OrderedGroup(grpa, ["/"] * (j_start - 1) + parbs[0][j_start:], width=j_width).post_to(scene) #["/"]*(i_start-1)+ blka = VGroup().save_state() blk = [grpa[j_first:j_first + i + 1] for i in range(j_count + 1)] blk[0].save_state() for j in range(j_start, j_end): print("j", j) grpa[j].add_to_group(blka) rcca = VGroup() while blka.get_height() > j_height: if len(blka) == 1: grpa[j].stretch_to_fit_height(j_height - 0.05) else: blka[0].add_to_group(rcca).remove_from_group(blka) if j >= j_first: animations.add( AnimationGroup(Animation(Mobject()), sound=sndbs[0][j], xaction="sound")) animations.add( AnimationGroup( PlayMobject(mobjs.copy().next_to(grpa[j]), grpa[j]), DiminishToSide(rcca), Write(grpa[j]), anibs[0][j], Freeze(2))) else: animations.add( AnimationGroup(DiminishToSide(rcca), Animation(grpa[j]), anibs[0][j], xaction="display")) if 1 == 1 and j >= j_first: animations.add( AnimationGroup(DiminishToEdge(blk[j - j_first].save_state()), run_time=0.5)) animations.add( *SlideShow01(parbs[j], anibs[j], sndbs[j], i_start, i_count, i_first).animations) animations.add( AnimationGroup(exclude_mobjs="foreground", xaction="fadeout")) if j < j_end - 1: animations.add( AnimationGroup(Restore(blk[j - j_first]), run_time=0.5)) super().__init__(*animations, )
def __init__(self, paras, anims, sound, i_start=1, i_count=None, i_first=None, position=GeomPosition([0, 3.3, 0]), width=[6.75], height=7, mobjs=None, scene=None, animate=True, **kwargs): if i_count is None: i_count = len(paras) if i_first is None: i_first = i_start if scene is None: scene = V.scene if mobjs is None: mobjs = AnimatedGroup().scale(0.2).post_to(scene) animations = AGroup() if 1 == 1 and paras[0] is not None: animations.add( AnimationGroup(Animation(Mobject()), sound=sound[0], xaction="sound")) animations.add( AnimationGroup(GrowTitle(paras[0]), Freeze(4), anims[0], foreground=True, xaction="post")) i_end = min((i_start + i_count), len(paras), len(anims)) print(i_end, i_start + i_count, len(paras), len(paras)) group = VGroup(position) OrderedGroup(group, ["/"] * (i_start - 1) + paras[i_start:i_end], width=width).post_to(scene) block = VGroup() print("i", anims[0].run_time) anim = Animation(Mobject()) for i in range(i_start, i_end): print("i", i, anims[i].run_time) group[i].add_to_group(block) recycle = VGroup() if animate: anim = anims[i] while block.get_height() > height: if len(block) == 1: group[i].stretch_to_fit_height(height - 0.05) else: block[0].add_to_group(recycle).remove_from_group(block) if i >= i_first: animations.add( AnimationGroup(Animation(Mobject()), sound=sound[i], time_offset=0.5, xaction="sound")) animations.add( AnimationGroup( anim, PlayMobject(mobjs.copy().next_to(group[i]), group[i]), DiminishToSide(recycle), Write(group[i]), )) else: animations.add( AnimationGroup(animDiminishToSide(recycle), Animation(group[i]), xaction="display")) #anim, super().__init__(*animations)