ワンクリックで
camera-techniques
Camera manipulation including zoom, pan, save/restore state, line width compensation, and focus transitions.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Camera manipulation including zoom, pan, save/restore state, line width compensation, and focus transitions.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Core Manim concepts including Scene lifecycle, Mobject hierarchy, coordinate systems, animation lifecycle, and rate functions.
Mathematical rendering with MathTex, Tex, tex_to_color_map, custom equation classes, and formula animation patterns.
Production animation patterns including reveal, transform, progressive reveal, emphasis, and cleanup patterns.
Reusable component patterns including VGroup subclasses, helper methods, encapsulated visualizations, and always_redraw patterns.
3Blue1Brown-style production standards including color palettes, timing guidelines, positioning rules, cleanup patterns, and typography standards.
| name | camera-techniques |
| description | Camera manipulation including zoom, pan, save/restore state, line width compensation, and focus transitions. |
Cinematic camera techniques for Manim animations.
from manim import *
class MyScene(MovingCameraScene):
def construct(self):
# self.camera.frame is the camera
# It's a VMobject that can be animated
# Save initial state
self.camera.frame.save_state()
# ... scene content
# Get current properties
self.camera.frame.width # Frame width
self.camera.frame.height # Frame height
self.camera.frame.get_center() # Camera position
# Set properties
self.camera.frame.set(width=10)
self.camera.frame.set(height=6)
# Scale down frame = zoom in
self.play(
self.camera.frame.animate.scale(0.5), # 2x zoom
run_time=2
)
# Zoom to specific height
self.play(
self.camera.frame.animate.set(height=4),
run_time=2
)
# Scale up frame = zoom out
self.play(
self.camera.frame.animate.scale(2), # 0.5x zoom
run_time=2
)
# Fit object in frame with padding
target = some_mobject
self.play(
self.camera.frame.animate
.set(height=target.height * 1.5)
.move_to(target),
run_time=2
)
| Scale Factor | Effective Zoom | Use Case |
|---|---|---|
| 0.25 | 4x zoom in | Fine detail |
| 0.5 | 2x zoom in | Detail view |
| 1.0 | Normal | Overview |
| 2.0 | 0.5x zoom out | Wide shot |
self.play(
self.camera.frame.animate.move_to(target),
run_time=1.5
)
self.play(
self.camera.frame.animate.move_to([3, 2, 0]),
run_time=1.5
)
# Center slightly above target
self.play(
self.camera.frame.animate.move_to(target).shift(UP * 0.5),
run_time=1.5
)
# Zoom into specific element
self.play(
self.camera.frame.animate
.scale(0.3)
.move_to(detail_element),
run_time=2
)
# Step 1: Pan to area
self.play(
self.camera.frame.animate.move_to(area),
run_time=1
)
# Step 2: Zoom in
self.play(
self.camera.frame.animate.scale(0.5),
run_time=1.5
)
class MyScene(MovingCameraScene):
def construct(self):
# Setup
main_content = self.create_content()
# Save the overview state
self.camera.frame.save_state()
# Show overview
self.wait(2)
# Zoom to detail
self.play(
self.camera.frame.animate
.set(height=detail.height * 2)
.move_to(detail),
run_time=2
)
# Explain detail
self.wait(3)
# Return to overview
self.play(Restore(self.camera.frame), run_time=2)
# Save state 1 (overview)
self.camera.frame.save_state()
self.play(self.camera.frame.animate.scale(0.5).move_to(area1))
# Save state 2 (area1)
state_area1 = self.camera.frame.copy()
self.play(Restore(self.camera.frame)) # Back to overview
# Later, return to area1
self.play(self.camera.frame.animate.become(state_area1))
When zooming, line widths don't scale, causing:
class ConsistentLinesScene(MovingCameraScene):
def construct(self):
# Store initial values
INITIAL_LINE_WIDTH = self.camera.cairo_line_width_multiple
INITIAL_FRAME_WIDTH = config.frame_width
# Create updater
def maintain_line_width(m):
proportion = self.camera.frame.width / INITIAL_FRAME_WIDTH
self.camera.cairo_line_width_multiple = INITIAL_LINE_WIDTH * proportion
# Attach to dummy mobject
line_manager = Mobject()
line_manager.add_updater(maintain_line_width)
self.add(line_manager)
# Now zoom operations maintain consistent lines
# ... rest of scene
elements = [element_a, element_b, element_c]
self.camera.frame.save_state()
for element in elements:
# Zoom to element
self.play(
self.camera.frame.animate
.set(height=element.height * 2)
.move_to(element),
run_time=1.5
)
# Time to observe
self.wait(2)
# Return to overview
self.play(Restore(self.camera.frame), run_time=1.5)
tour_stops = [
(element_a, 1.5, 2.0), # (element, height_factor, wait_time)
(element_b, 2.0, 1.5),
(element_c, 1.2, 3.0),
]
self.camera.frame.save_state()
for element, height_factor, wait in tour_stops:
self.play(
self.camera.frame.animate
.set(height=element.height * height_factor)
.move_to(element),
run_time=1.5
)
self.wait(wait)
self.play(Restore(self.camera.frame), run_time=2)
class My3DScene(ThreeDScene):
def construct(self):
# Set initial orientation
self.set_camera_orientation(
phi=75 * DEGREES, # Polar angle (from z-axis)
theta=-45 * DEGREES # Azimuthal angle (around z-axis)
)
# Rotate to new orientation
self.move_camera(
phi=60 * DEGREES,
theta=-60 * DEGREES,
run_time=2
)
# Continuous rotation
self.begin_ambient_camera_rotation(rate=0.1) # rad/s
self.wait(5)
self.stop_ambient_camera_rotation()
# Adjust zoom
self.set_camera_orientation(zoom=0.5) # Closer
self.set_camera_orientation(zoom=2) # Further
| Movement | Duration | Notes |
|---|---|---|
| Quick pan | 0.5-1.0s | Minor adjustment |
| Standard pan | 1.5s | Normal movement |
| Dramatic zoom in | 2.0-3.0s | Building focus |
| Slow reveal zoom out | 3.0-4.0s | Grand reveal |
| Restore overview | 2.0s | Return home |
# Smooth (default) - professional
self.play(
self.camera.frame.animate.move_to(target),
rate_func=smooth
)
# Rush effects - dramatic
self.play(
self.camera.frame.animate.scale(0.3),
rate_func=rush_into # Accelerate at end
)
self.play(
Restore(self.camera.frame),
rate_func=rush_from # Decelerate from start
)
# Linear - mechanical feel
self.play(
self.camera.frame.animate.shift(RIGHT * 3),
rate_func=linear
)
from manim import *
class CameraDemo(MovingCameraScene):
def construct(self):
# Line width management
INIT_WIDTH = self.camera.cairo_line_width_multiple
INIT_FRAME = config.frame_width
manager = Mobject()
manager.add_updater(lambda m:
setattr(self.camera, 'cairo_line_width_multiple',
INIT_WIDTH * self.camera.frame.width / INIT_FRAME))
self.add(manager)
# Create content
circles = VGroup(*[
Circle(radius=0.5).move_to([x, y, 0])
for x in range(-4, 5, 2)
for y in range(-2, 3, 2)
])
self.add(circles)
# Save overview
self.camera.frame.save_state()
self.wait(1)
# Zoom to center circle
center = circles[len(circles)//2]
self.play(
self.camera.frame.animate
.set(height=center.height * 3)
.move_to(center),
run_time=2
)
# Add detail
label = Text("Center", font_size=12).next_to(center, UP, buff=0.1)
self.play(Write(label))
self.wait(2)
# Return to overview
self.play(
FadeOut(label),
Restore(self.camera.frame),
run_time=2
)
self.wait(1)