Core Objects
- - Circle, Square, Rectangle, Line, Arrow, Dot, Polygon, RegularPolygon
- - Text, Tex, MathTex
- - ImageMobject, SVGMobject
- - Group and VGroup
Runnable examples for the currently supported feature set. Previews are lazy and only compile when you click Render preview, so opening this page does not trigger a flood of compile requests.
Show a world-space label and a HUD pinned to the viewport with an updater, then release it so the label becomes a normal scene object.
from manim import * class TwoDWorldVsFrameScene(MovingCameraScene): def construct(self): plane = NumberPlane().set_stroke(color=GREY_D, width=1) marker = Dot(point=LEFT * 2.6 + UP * 0.6, color=BLUE).scale(1.4) world_label = Text("World space", font_size=24, color=BLUE).next_to(marker, UP, buff=0.18) hud_title = Text("Frame HUD", font_size=28, color=YELLOW) hud_subtitle = Text("Pinned to the viewport", font_size=18, color=WHITE) hud = VGroup(hud_title, hud_subtitle).arrange(DOWN, aligned_edge=LEFT, buff=0.08) hud_offset = LEFT * 1.35 + DOWN * 0.7 hud.move_to(self.camera.frame.get_corner(UR) + hud_offset) def pin_to_frame(mob): mob.move_to(self.camera.frame.get_corner(UR) + hud_offset) hud.add_updater(pin_to_frame) self.add(plane, marker, world_label, hud) base_width = self.camera.frame.width self.play(self.camera.frame.animate.shift(RIGHT * 2.2).set(width=base_width / 1.2), run_time=1.1) self.wait(0.2) hud.remove_updater(pin_to_frame) self.play(hud.animate.move_to(RIGHT * 2.8 + UP * 1.4), run_time=0.55) self.play(self.camera.frame.animate.shift(LEFT * 1.4 + DOWN * 0.3).set(width=base_width), run_time=0.95) self.wait(0.2) scene = TwoDWorldVsFrameScene()scene.construct()Pan and zoom the frame.
from manim import * class SimpleCameraMove(MovingCameraScene): def construct(self): self.camera.background_color = BLACK grid = NumberPlane() self.add(grid) base_width = self.camera.frame.width self.play(self.camera.frame.animate.move_to(LEFT * 2).set(width=base_width / 1.3), run_time=1.5, rate_func=smooth) self.wait(0.5) self.play(self.camera.frame.animate.move_to(RIGHT * 2).set(width=base_width / 0.9), run_time=1.5, rate_func=smooth) self.wait(0.5) scene = SimpleCameraMove()scene.construct()Use the 2D camera frame animate proxy to pan and zoom around a layout.
from manim import * class FrameAnimateScene(MovingCameraScene): def construct(self): self.camera.background_color = "#020617" plane = NumberPlane().set_stroke(color=GREY_D, width=1) left = Circle(color=BLUE).scale(1.2).shift(LEFT * 3) right = Square(color=YELLOW).scale(1.1).shift(RIGHT * 3) label = Text("Frame animate", font_size=36, color=WHITE).to_edge(UP) self.add(plane, left, right, label) base_width = self.camera.frame.width self.play(self.camera.frame.animate.move_to(LEFT * 3).set(width=base_width / 1.5), run_time=1.4) self.play(self.camera.frame.animate.move_to(RIGHT * 3).set(width=base_width / 1.3), run_time=1.4) self.play(self.camera.frame.animate.move_to(ORIGIN).set(width=base_width), run_time=1.2) self.wait(0.4) scene = FrameAnimateScene()scene.construct()Attach a live zoomed inset to a highlighted region in a 2D image scene.
from manim import *import numpy as np class ZoomedPixelsScene(ZoomedScene): def __init__(self, **kwargs): ZoomedScene.__init__( self, zoom_factor=0.35, zoomed_display_height=2.1, zoomed_display_width=3.8, image_frame_stroke_width=6, zoomed_camera_config={"default_frame_stroke_width": 3}, **kwargs ) def construct(self): pixels = np.uint8([ [0, 40, 80, 120, 160, 200], [30, 80, 130, 180, 220, 255], [255, 210, 170, 120, 70, 20], [60, 110, 160, 210, 240, 255], ]) image = ImageMobject(pixels) image.height = 5.8 marker = Dot(LEFT * 2.1 + UP * 0.9, color=YELLOW) caption = Text("2D zoomed inset", font_size=30, color=WHITE).to_edge(UP) frame = self.zoomed_camera.frame frame.move_to(marker) frame.set_color(PURPLE) self.zoomed_display.display_frame.set_color(RED) self.zoomed_display.to_corner(UR, buff=0.45) self.add(image, marker, caption) self.activate_zooming() self.play(self.get_zoomed_display_pop_out_animation(), run_time=0.8) self.play( marker.animate.shift(RIGHT * 2.0 + DOWN * 1.1), frame.animate.shift(RIGHT * 2.0 + DOWN * 1.1), run_time=1.6, rate_func=smooth, ) self.wait(0.4) scene = ZoomedPixelsScene()scene.construct()
Zoom into a public PNG region, then move the focus frame and inset together.
from manim import * class ZoomedPngScene(ZoomedScene): def __init__(self, **kwargs): ZoomedScene.__init__( self, zoom_factor=0.45, zoomed_display_height=2.2, zoomed_display_width=2.2, image_frame_stroke_width=4, zoomed_camera_config={"default_frame_stroke_width": 2}, **kwargs ) def construct(self): image = ImageMobject("/demo-icon.png") image.set_width(3.0) image.rotate(12 * DEGREES) image.shift(LEFT * 2.2 + UP * 0.3) overlay = Text("PNG", font_size=30, color=WHITE).move_to(image) caption = Text("aligned edge", font_size=24, color=YELLOW).next_to(image, DOWN, buff=0.22).align_to(image, LEFT) frame = self.zoomed_camera.frame frame.set_color(PURPLE) frame.scale(0.32) frame.move_to(image.get_center() + RIGHT * 0.42 + UP * 0.1) frame.rotate(-8 * DEGREES) zoomed_display = self.zoomed_display zoomed_display.next_to(image, RIGHT, buff=0.9) zoomed_display.align_to(image, UP) zoomed_display.display_frame.set_color(RED) zoom_label = Text("zoom detail", font_size=24, color=RED) zoom_label.next_to(zoomed_display.display_frame, DOWN, buff=0.16) zoom_label.align_to(zoomed_display.display_frame, LEFT) self.add(image, overlay, caption) self.activate_zooming() self.add(frame, zoomed_display, zoom_label) self.play(self.get_zoomed_display_pop_out_animation(), run_time=0.8) focus = Group(image, overlay) self.play( focus.animate.scale(1.15).rotate(18 * DEGREES).shift(RIGHT * 0.55 + DOWN * 0.3), frame.animate.scale(0.82).rotate(14 * DEGREES).shift(RIGHT * 0.24 + DOWN * 0.2), zoomed_display.animate.scale(1.1).shift(RIGHT * 0.2 + DOWN * 0.16), caption.animate.shift(RIGHT * 0.56 + DOWN * 0.28), zoom_label.animate.shift(RIGHT * 0.2 + DOWN * 0.16), run_time=1.0, ) self.wait(0.2) scene = ZoomedPngScene()scene.construct()