def overview(scene): title = PangoText( """ Manim is a Python library used to generate videos, and Code Video Generator provides a base scene that makes it easy to generate code walkthrough videos ... in fact, it is what was used to generate this video! """, font="Helvetica", line_spacing=0.5, ).scale(0.7) scene.play(ShowCreation(title, run_time=10, rate_func=linear)) scene.wait(3) sub = (PangoText( """ Here is an example: """, font="Helvetica", ).scale(0.7).next_to(title, direction=DOWN, buff=MED_LARGE_BUFF, aligned_edge=LEFT)) scene.play(ShowCreation(sub)) scene.wait(2) scene.clear()
def demo_boxes(scene: CodeScene): scene.add_background(f"{example_dir}/resources/blackboard.jpg") title = Text("examples/boxes.py", font=DEFAULT_FONT) title.to_edge(UP) scene.add(title) comp1 = TextBox("Component A", shadow=False) comp2 = TextBox("Component B", shadow=False) comp3 = TextBox("Component C", shadow=False) comp1.next_to(title, DOWN, buff=2) comp1.to_edge(LEFT) comp2.next_to(comp1, DOWN, buff=1) comp3.next_to(comp1, RIGHT, buff=4) arrow1 = Connection(comp2, comp1, "Do something") arrow2 = Connection(comp1, comp3, "Do another thing") scene.play(FadeIn(comp2)) scene.wait_until_beat(1) scene.play(ShowCreation(arrow1)) scene.play(FadeIn(comp1)) scene.wait_until_beat(1) scene.play(ShowCreation(arrow2)) scene.play(FadeIn(comp3)) scene.wait_until_beat(4) scene.clear()
def demo_highlighting(scene: CodeScene): title = PangoText( """ If you want more control, you can create code blocks and highlight them manually. """, font="Helvetica", line_spacing=0.5, ).scale(0.7) scene.play(ShowCreation(title, run_time=3, rate_func=linear)) scene.wait(2) scene.clear() scene.add_background(f"{example_dir}/resources/blackboard.jpg") tex = scene.create_code(f"{example_dir}/highlights.py") scene.play(ShowCreation(tex)) scene.highlight_line( tex, 11, caption= "Create code blocks yourself and pass in any arguments the Code class supports to do things " "like change the theme or font", ) scene.highlight_lines( tex, 13, 19, caption= "Highlight code with a caption to give extra information. A wait is" " automatically added for a time based on the length of the caption", ) scene.highlight_line(tex, 21, caption="Reset highlighting and positioning") scene.highlight_none(tex) scene.play(FadeOut(tex)) scene.clear()
def construct(self): expr2 = self.expr.subs(e, math.e) f = lambdify(x, expr2, 'numpy') domains = continuous_domain(self.expr, x, Interval(self.x_min, self.x_max)) if type(domains) is Union: domains = domains.args else: domains = [domains] self.setup_axes(animate=True) func_graph = VGroup() for domain in domains: graph = self.get_graph(f, self.function_color, get_left_bound(domain), get_right_bound(domain)) func_graph.add(graph) graph_lab = self.get_graph_label(func_graph[0], label=latex(self.expr)) self.play(ShowCreation(func_graph, run_time=3)) self.play(ShowCreation(graph_lab)) self.wait(5)
def demo_sequence(scene: CodeScene): title = PangoText( """ You can use Code Video Generator to also illustrate high-level concepts through sequence diagrams, or if you want more control, your own block diagrams: """, font="Helvetica", line_spacing=0.5, ).scale(0.7) scene.play(ShowCreation(title, run_time=4, rate_func=linear)) scene.wait(3) scene.clear() scene.add_background(f"{example_dir}/resources/blackboard.jpg") diagram = SequenceDiagram() browser, web, app = diagram.add_objects("Browser", "Web", "App") with browser: with web.text("Make a request"): web.to_target("Do a quick thing", app) with app.text("Retrieve a json object"): app.to_self("Calls itself") app.note("Do lots and lots and lots of thinking") app.ret("Value from db") web.ret("HTML response") diagram.animate(scene) scene.wait(3) scene.play(FadeOut(diagram)) scene.clear()
def construct(self): comp1 = TextBox("Component A", shadow=False) comp2 = TextBox("Component B", shadow=False) comp3 = TextBox("Component C", shadow=False) comp1.to_edge(LEFT) comp2.next_to(comp1, DOWN, buff=1) comp3.next_to(comp1, RIGHT, buff=4) arrow1 = Connection(comp2, comp1, "Do something") arrow2 = Connection(comp1, comp3, "Another thing") self.play(FadeIn(comp2)) self.play(ShowCreation(arrow1)) self.play(FadeIn(comp1)) self.play(ShowCreation(arrow2)) self.play(FadeIn(comp3)) self.wait(5)
def title_scene(scene): scene.add_background(f"{example_dir}/resources/blackboard.jpg") title = PangoText("How to use Code Video Generator", font="Helvetica") scene.play(ShowCreation(title)) scene.play( FadeIn( PangoText("A code walkthrough", font="Helvetica").scale(0.6).next_to(title, direction=DOWN, buff=LARGE_BUFF))) scene.wait(3) scene.clear()
def animate_code_comments( self, path: str, title: str = None, keep_comments: bool = False, start_line: int = 1, end_line: Optional[int] = None, reset_at_end: bool = True, ) -> Code: """ Parses a code file, displays it or a section of it, and animates comments Args: path: The source code file path title: The title or file path if not provided keep_comments: Whether to keep comments or strip them when displaying start_line: The start line number, used for displaying only a partial file end_line: The end line number, defaults to the end of the file reset_at_end: Whether to reset the code to full screen at the end or not """ code, comments = comment_parser.parse(path, keep_comments=keep_comments, start_line=start_line, end_line=end_line) tex = AutoScaled( PartialCode(code=code, start_line=start_line, style=self.code_theme)) if title is None: title = path title = Text(title, color=WHITE).to_edge(edge=UP) self.add(title) tex.next_to(title, DOWN) self.play(ShowCreation(tex)) self.wait() for comment in comments: self.highlight_lines(tex, comment.start, comment.end, comment.caption) if self.caption: self.play(FadeOut(self.caption)) self.caption = None if reset_at_end: self.play(HighlightNone(tex)) self.play(ApplyMethod(tex.full_size)) return tex
def demo_sequence(scene: CodeScene): title = Text( """ You can use Code Video Generator to also illustrate high-level concepts through sequence diagrams, or if you want more control, your own block diagrams: """, font=DEFAULT_FONT, line_spacing=0.5, ).scale(0.7) scene.play(ShowCreation(title, run_time=4, rate_func=linear)) scene.wait(3) scene.clear() scene.add_background(f"{example_dir}/resources/blackboard.jpg") title = Text("examples/sequence-diagrams.py", font=DEFAULT_FONT) title.to_edge(UP) scene.add(title) diagram = AutoScaled(SequenceDiagram()) browser, web, app = diagram.add_objects("Browser", "Web", "App") browser.to(web, "Make a request") web.to(app, "Request with no response") web.to(app, "Retrieve a json object") app.to(app, "Calls itself") app.note("Do lots and lots and lots of thinking") app.to(web, "Value from db") web.to(browser, "HTML response") diagram.next_to(title, DOWN) scene.play(ShowCreation(diagram)) for interaction in diagram.get_interactions(): scene.play(ShowCreation(interaction)) scene.wait(3) scene.play(FadeOut(diagram), *[FadeOut(item) for item in diagram.interactions]) scene.clear()
def goodbye(scene: CodeScene): title = PangoText( """ Try Code Video Generator today at: https://github.com/sleuth-io/code-video-generator Thanks for watching!""", font="Helvetica", line_spacing=0.5, ).scale(0.7) scene.play(ShowCreation(title, run_time=4, rate_func=linear)) scene.wait(5) scene.play(FadeOut(title))
def demo_boxes(scene: CodeScene): scene.add_background(f"{example_dir}/resources/blackboard.jpg") lib = Library() comp1 = lib.text_box("Component A", shadow=False) comp2 = lib.text_box("Component B", shadow=False) comp3 = lib.text_box("Component C", shadow=False) comp1.to_edge(LEFT) comp2.next_to(comp1, DOWN, buff=1) comp3.next_to(comp1, RIGHT, buff=4) arrow1 = lib.connect(comp2, comp1, "Do something") arrow2 = lib.connect(comp1, comp3, "Do another thing") scene.play(FadeIn(comp2)) scene.wait_until_beat(1) scene.play(ShowCreation(arrow1)) scene.play(FadeIn(comp1)) scene.wait_until_beat(1) scene.play(ShowCreation(arrow2)) scene.play(FadeIn(comp3)) scene.wait_until_beat(4) scene.clear()
def animate(self, scene: Scene): for actor in self.actors.values(): actor.stretch( sum(item.get_height() + 0.5 for item in self.interactions)) if scene.renderer.camera.frame_height < self.get_height() + 1.5: height_scale = scene.renderer.camera.frame_height / ( self.get_height() + 1.5) else: height_scale = 1 if scene.renderer.camera.frame_width < self.get_width() + 5: width_scale = scene.renderer.camera.frame_width / ( self.get_width() + 5) else: width_scale = 1 scale = min(1, height_scale, width_scale) self.scale(scale) self.to_edge(UP) self.to_edge(LEFT) start_y = self.get_edge_center(UP)[1] - 1.5 * scale scene.play(ShowCreation(self)) last: Interaction = None for interaction in [item for item in self.interactions if item.target]: interaction.scale(scale) if not last: interaction.set_y(start_y, direction=UP) else: interaction.set_y(last.get_y(DOWN) - 0.5 * scale, direction=UP) scene.play(ShowCreation(interaction)) last = interaction
def construct(self): example_dir = dirname(__file__) self.add_background(f"{example_dir}/resources/blackboard.jpg") diagram = AutoScaled(SequenceDiagram()) browser, web, app = diagram.add_objects("Browser", "Web", "App") browser.to(web, "Make a request") web.to(app, "Do a quick thing") web.to(app, "Retrieve a json object") app.to(app, "Call itself") app.note("Do lots and lots and lots of thinking") app.to(web, "Value from db") web.to(browser, "HTML response") title = Text("Sequence Diagram", font=DEFAULT_FONT, size=0.8) title.to_edge(UP) self.add(title) diagram.next_to(title, DOWN) self.play(ShowCreation(diagram)) for interaction in diagram.get_interactions(): self.play(ShowCreation(interaction)) self.wait(5)
def title_scene(scene): scene.add_background(f"{example_dir}/resources/blackboard.jpg") title = Text("How to use Code Video Generator", font="Helvetica") scene.play(ShowCreation(title)) scene.play( FadeIn( Text(f"Code and examples from version {__version__}", font="Helvetica") .scale(0.6) .next_to(title, direction=DOWN, buff=LARGE_BUFF) ) ) scene.wait(3) scene.clear()
def construct(self): diagram: SequenceDiagram = AutoScaled(SequenceDiagram()) test, browser, database = diagram.add_objects("Test", "Browser", "Database") self.wait() test.to(database, "Set up initial data") test.to(browser, "Starts a Chrome instance,\noften headless") test.to(browser, "Issues commands") browser.to(test, "Returns element data") test.to(database, "Run SQL queries") test.to(test, "Asserts based on the data") test.to(test, "Another go") diagram.to_edge(UR) self.play(ShowCreation(diagram)) for interaction in diagram.get_interactions(): self.play(ShowCreation(interaction)) self.wait() self.play_movie( "/home/mrdon/Videos/browser-tests/02-test-notifications.mkv") self.clear() notif_code: PartialCode = AutoScaled( PartialCode( path= "/home/mrdon/dev/sleuth/sleuth/apps/account/tests/selenium/test_notifications.py", start_line=29, end_line=43)) self.play(ShowCreation(notif_code)) self.wait() self.play(HighlightLine(notif_code, 30)) self.wait() self.play(HighlightLines(notif_code, 31)) self.wait() self.play_movie("/home/mrdon/Videos/browser-tests/02-login.mkv") self.clear() login_code: PartialCode = AutoScaled( PartialCode( path= "/home/mrdon/dev/sleuth/sleuth/apps/account/tests/selenium/login_page.py", start_line=18, end_line=27)) self.play(ShowCreation(login_code)) self.wait() self.play(HighlightLines(login_code, start=19, end=27)) self.wait() self.play_movie( "/home/mrdon/Videos/browser-tests/02-login-to-test-notifications.mkv" ) self.clear() notif_code: PartialCode = AutoScaled( PartialCode( path= "/home/mrdon/dev/sleuth/sleuth/apps/account/tests/selenium/test_notifications.py", start_line=29, end_line=43)) self.add(notif_code) self.highlight_line(notif_code, 32) self.wait() self.highlight_lines(notif_code, 36, 38) self.wait() self.highlight_line(notif_code, 40) self.wait() # add voiceover bits self.clear() ui_code: PartialCode = AutoScaled( PartialCode( path= "/home/mrdon/dev/sleuth/sleuth/apps/account/tests/selenium/login_page.py", start_line=74, end_line=81)) self.play(ShowCreation(ui_code)) self.wait()