Animation engine for explanatory math videos.
—
Scene classes and animation orchestration system for managing the animation lifecycle, mobject placement, and rendering coordination. Scenes serve as the main canvas where mathematical objects are added, animated, and removed to create cohesive mathematical visualizations.
The fundamental scene class that provides the core animation framework, mobject management, and rendering coordination for all Manim animations.
class Scene:
"""
Base scene class for all animations providing the main canvas and orchestration system.
Attributes:
- mobjects: list[Mobject] - Current mobjects on screen
- camera: Camera - Scene camera for rendering
- renderer: Renderer - Backend rendering engine
"""
def __init__(
renderer: str = None,
camera_class: type = Camera,
always_update_mobjects: bool = False,
random_seed: int = None,
skip_animations: bool = False
) -> None:
"""
Initialize scene with rendering and camera configuration.
Parameters:
- renderer: Rendering backend ('cairo' or 'opengl')
- camera_class: Camera class to use for the scene
- always_update_mobjects: Whether to update mobjects every frame
- random_seed: Seed for random number generation
- skip_animations: Skip animations for faster rendering
"""
def construct(self) -> None:
"""
Add content to the scene. Override this method with your animation code.
This is the main method where scene content is defined. All mobject
creation, positioning, and animation calls should be placed here.
"""
def setup(self) -> None:
"""
Setup code run before construct(). Override for initialization.
Used for common setup tasks that should run before the main
scene construction, such as configuring camera settings or
initializing reusable objects.
"""
def tear_down(self) -> None:
"""
Cleanup code run after construct(). Override for finalization.
Used for cleanup tasks that should run after scene construction
is complete, such as saving state or releasing resources.
"""
def render(preview: bool = False) -> None:
"""
Render the complete scene by calling setup(), construct(), and tear_down().
Parameters:
- preview: If true, opens scene in file viewer after rendering
"""
# Mobject Management
def add(*mobjects: Mobject) -> None:
"""
Add mobjects to the scene. Mobjects are displayed from background to foreground
in the order they are added.
Parameters:
- *mobjects: Variable number of mobjects to add to scene
"""
def remove(*mobjects: Mobject) -> None:
"""
Remove mobjects from the scene and stop displaying them.
Parameters:
- *mobjects: Variable number of mobjects to remove from scene
"""
def add_foreground_mobjects(*mobjects: Mobject) -> None:
"""
Add mobjects to foreground layer, ensuring they appear on top of all other objects.
Parameters:
- *mobjects: Variable number of mobjects to add to foreground
"""
def remove_foreground_mobjects(*mobjects: Mobject) -> None:
"""
Remove mobjects from the foreground layer.
Parameters:
- *mobjects: Variable number of mobjects to remove from foreground
"""
# Animation Control
def play(
*animations: Animation | Mobject,
subcaption: str = None,
subcaption_duration: float = None,
subcaption_offset: float = 0
) -> None:
"""
Play animations simultaneously with precise timing control.
Parameters:
- *animations: Animation objects or mobjects with .animate transformations
- subcaption: Text to display as subtitle during animation
- subcaption_duration: Duration to display subtitle
- subcaption_offset: Time offset for subtitle display
"""
def wait(
duration: float = 1.0,
stop_condition: Callable[[], bool] = None,
frozen_frame: bool = True
) -> None:
"""
Pause animation for specified duration or until condition is met.
Parameters:
- duration: Time to wait in seconds
- stop_condition: Function returning True when wait should end
- frozen_frame: Whether to continue updating during wait
"""
def wait_until(
stop_condition: Callable[[], bool],
max_time: float = 60
) -> None:
"""
Wait until condition is satisfied, up to maximum duration.
Parameters:
- stop_condition: Function returning True when wait should end
- max_time: Maximum time to wait in seconds
"""
# Scene State
def clear() -> None:
"""Remove all mobjects from the scene."""
def get_mobjects() -> list[Mobject]:
"""Get list of all mobjects currently in the scene."""
def get_mobject_family_members() -> list[Mobject]:
"""Get all mobjects including submobjects in flattened list."""
# Updaters
def add_updater(func: Callable[[float], None]) -> None:
"""
Add function to be called every frame with delta time.
Parameters:
- func: Function taking dt (delta time) parameter
"""
def remove_updater(func: Callable[[float], None]) -> None:
"""
Remove previously added updater function.
Parameters:
- func: Function to remove from updater list
"""
# Media Integration
def add_subcaption(
content: str,
duration: float = 1,
offset: float = 0
) -> None:
"""
Add subtitle text to be displayed during animation.
Parameters:
- content: Subtitle text content
- duration: Duration to display subtitle in seconds
- offset: Time offset from current animation time
"""
def add_sound(
sound_file: str,
time_offset: float = 0,
gain: float = None,
**kwargs
) -> None:
"""
Add audio file to be played during animation.
Parameters:
- sound_file: Path to audio file
- time_offset: Time offset from current animation time
- gain: Audio volume adjustment
"""Scene class with movable and zoomable camera for creating dynamic perspectives and following objects during animations.
class MovingCameraScene(Scene):
"""
Scene with camera that can move, zoom, and change perspective dynamically.
The camera frame can be animated like any other mobject, allowing for
cinematic camera movements and focus changes during animations.
"""
def setup() -> None:
"""Initialize moving camera with appropriate camera class."""
# Camera frame is accessible as self.camera.frame
# Can be animated like: self.play(self.camera.frame.animate.move_to(target))Scene class optimized for 3D animations with camera controls for 3D perspective, rotation, and fixed-orientation objects.
class ThreeDScene(Scene):
"""
Scene specialized for 3D animations with enhanced camera controls.
Provides methods for setting camera orientation, managing 3D perspective,
and handling objects that should maintain fixed orientation relative to camera.
"""
def set_camera_orientation(
phi: float = None,
theta: float = None,
gamma: float = None,
zoom: float = None
) -> None:
"""
Set 3D camera orientation using spherical coordinates.
Parameters:
- phi: Angle from z-axis (inclination) in radians
- theta: Angle from x-axis (azimuth) in radians
- gamma: Roll angle around camera's forward axis
- zoom: Camera zoom level
"""
def begin_ambient_camera_rotation(rate: float = 0.02) -> None:
"""
Start continuous camera rotation around the scene.
Parameters:
- rate: Rotation speed in radians per second
"""
def stop_ambient_camera_rotation() -> None:
"""Stop ambient camera rotation."""
def begin_3dillusion_camera_rotation(
rate: float = 1,
origin_theta: float = None,
origin_phi: float = None
) -> None:
"""
Start camera rotation that creates 3D illusion effect.
Parameters:
- rate: Rotation speed multiplier
- origin_theta: Starting theta angle
- origin_phi: Starting phi angle
"""
def stop_3dillusion_camera_rotation() -> None:
"""Stop 3D illusion camera rotation."""
def move_camera(
phi: float = None,
theta: float = None,
gamma: float = None,
zoom: float = None,
frame_center: np.ndarray = None,
**kwargs
) -> Animation:
"""
Animate camera to new orientation and position.
Parameters:
- phi: Target inclination angle
- theta: Target azimuth angle
- gamma: Target roll angle
- zoom: Target zoom level
- frame_center: Target center point for camera
Returns:
- Animation that moves camera to target state
"""
def get_moving_mobjects(*animations: Animation) -> list[Mobject]:
"""Get list of mobjects that will be moved by given animations."""
def add_fixed_orientation_mobjects(*mobjects: Mobject) -> None:
"""
Add mobjects that maintain fixed orientation relative to camera.
These mobjects will always face the camera regardless of camera rotation,
useful for text labels and 2D objects in 3D scenes.
Parameters:
- *mobjects: Mobjects to maintain fixed camera-relative orientation
"""
def add_fixed_in_frame_mobjects(*mobjects: Mobject) -> None:
"""
Add mobjects fixed in camera frame (like UI elements).
These mobjects remain in fixed screen positions regardless of
camera movement, useful for legends, titles, and UI elements.
Parameters:
- *mobjects: Mobjects to fix in camera frame
"""
def remove_fixed_orientation_mobjects(*mobjects: Mobject) -> None:
"""Remove mobjects from fixed orientation tracking."""
def remove_fixed_in_frame_mobjects(*mobjects: Mobject) -> None:
"""Remove mobjects from fixed frame positioning."""Specialized scene for linear algebra visualizations with coordinate systems and vector operations.
class VectorScene(Scene):
"""
Scene optimized for vector and linear algebra visualizations.
Includes coordinate system setup and utilities for vector operations,
transformations, and mathematical demonstrations.
"""
def setup() -> None:
"""Setup coordinate plane and vector visualization tools."""
def add_plane(animate: bool = False, **plane_config) -> NumberPlane:
"""
Add coordinate plane to scene.
Parameters:
- animate: Whether to animate plane creation
- **plane_config: Configuration options for NumberPlane
Returns:
- NumberPlane object added to scene
"""
def add_vector(
vector: np.ndarray,
color: str = YELLOW,
animate: bool = True,
**kwargs
) -> Arrow:
"""
Add vector arrow to scene.
Parameters:
- vector: Vector coordinates as numpy array
- color: Vector arrow color
- animate: Whether to animate vector creation
Returns:
- Arrow object representing the vector
"""
class LinearTransformationScene(VectorScene):
"""
Scene for demonstrating linear transformations with coordinate grids.
Provides tools for applying and visualizing matrix transformations
on coordinate systems and vector objects.
"""
def setup() -> None:
"""Setup transformation scene with basis vectors and grid."""
def apply_matrix(
matrix: np.ndarray,
run_time: float = 2,
**kwargs
) -> None:
"""
Apply linear transformation matrix to all scene objects.
Parameters:
- matrix: 2x2 transformation matrix
- run_time: Duration of transformation animation
"""
def apply_transposed_matrix(
matrix: np.ndarray,
run_time: float = 2,
**kwargs
) -> None:
"""
Apply transposed linear transformation.
Parameters:
- matrix: 2x2 matrix to transpose and apply
- run_time: Duration of transformation animation
"""
def apply_nonlinear_transformation(
function: Callable,
run_time: float = 3,
**kwargs
) -> None:
"""
Apply nonlinear transformation function to scene objects.
Parameters:
- function: Function mapping (x,y) coordinates to new positions
- run_time: Duration of transformation animation
"""Additional scene classes for specific use cases and advanced functionality.
class ZoomedScene(MovingCameraScene):
"""
Scene with zoomed inset view capabilities.
Allows creating zoomed-in regions that display detailed views
of specific scene areas while maintaining the main view.
"""
def setup() -> None:
"""Setup zoomed scene with zoom camera and display."""
def get_zoomed_display_pop_out_animation(**kwargs) -> AnimationGroup:
"""Get animation for zoomed display appearing with pop-out effect."""
def get_zoomed_display_pop_in_animation(**kwargs) -> AnimationGroup:
"""Get animation for zoomed display disappearing with pop-in effect."""
class SpecialThreeDScene(ThreeDScene):
"""
Enhanced 3D scene with additional specialized features.
Extends ThreeDScene with extra utilities for complex 3D
visualizations and advanced camera behaviors.
"""
def setup() -> None:
"""Setup special 3D scene with enhanced capabilities."""from manim import *
class MyScene(Scene):
def construct(self):
# Create objects
circle = Circle(radius=2, color=BLUE)
square = Square(side_length=3, color=RED)
# Add to scene
self.add(circle, square)
# Animate
self.play(Create(circle))
self.play(Transform(circle, square))
self.wait(2)class CameraExample(MovingCameraScene):
def construct(self):
square = Square()
self.add(square)
# Move camera to focus on square
self.play(
self.camera.frame.animate.move_to(square).scale(0.5)
)
self.wait(1)
# Return to original view
self.play(
self.camera.frame.animate.move_to(ORIGIN).scale(2)
)class ThreeDExample(ThreeDScene):
def construct(self):
# Set initial camera angle
self.set_camera_orientation(phi=75*DEGREES, theta=45*DEGREES)
# Create 3D objects
cube = Cube(side_length=2, fill_color=BLUE)
sphere = Sphere(radius=1, fill_color=RED)
self.add(cube, sphere)
# Rotate camera around scene
self.begin_ambient_camera_rotation(rate=0.1)
self.wait(5)
self.stop_ambient_camera_rotation()Install with Tessl CLI
npx tessl i tessl/pypi-manim