Using the Camera¶
Basic Knowledge¶
As we know, a basic JAnim timeline looks like this:
class MyTimeline(Timeline):
def construct(self):
...
JAnim has a built-in camera item that can be accessed via self.camera
Camera items can be translated, rotated, and scaled like regular items:
# Spiral parametric equation
def t_func(self, t):
scale = 0.01
return np.array([
scale * np.cos(t) * t**2,
scale * np.sin(t) * t**2,
0,
])
# Coordinate system
plane = NumberPlane(faded_line_ratio=1)
# Create spiral curve
curve = ParametricCurve(t_func, t_range=[0, 5 * TAU, 0.2], color=YELLOW)
self.show(plane, curve)
self.forward()
self.play(
self.camera.anim.points.rotate(PI / 2).scale(0.25), # Rotate and scale camera
curve.anim.radius.scale(0.25), # Scale spiral thickness
duration=3
)
self.forward()
See also:
# Coordinate system
axes = Axes(axis_config={ 'include_numbers': True })
# Create square
square = Square()
square.points.shift(UR * 2)
self.show(axes, square)
self.forward()
self.play(
self.camera.anim.points.shift(LEFT * 2),
self.camera.anim(duration=2).points.move_to(square),
Wait(0.5),
self.camera.anim(duration=1.5).points.to_center(),
lag_ratio=1
)
self.forward()
See also:
Note that when the camera scale is less than 1, it magnifies the image; when greater than 1, it shrinks the image
This is because we are scaling the size of the camera, not the size of the image. Shrinking the camera shrinks the “framing range”, naturally magnifying the image, and vice versa
Fixing Items in the Camera Frame¶
Moving the camera changes the viewport and shifts the entire image
However, sometimes we want certain items to remain stationary in the frame, such as title text or hint text
To achieve this, we can use the fix_in_frame() method. For example, with a slight modification to the example above:
# Coordinate system
axes = Axes(axis_config={ 'include_numbers': True })
# Create square
square = Square()
square.points.shift(UR * 2)
# Camera center point and text
dot = Dot(ORIGIN, color=BLUE).fix_in_frame()
txt1 = Text('Camera Center', color=BLUE).fix_in_frame()
txt1.points.next_to(dot, DOWN)
# Text at top-left corner of the frame
txt2 = Text('Moving the camera ...').fix_in_frame()
txt2.points.to_border(UL)
self.show(axes, square, dot, txt1, txt2)
self.forward()
self.play(
self.camera.anim.points.shift(LEFT * 2),
self.camera.anim(duration=2).points.move_to(square),
Wait(0.5),
self.camera.anim(duration=1.5).points.to_center(),
lag_ratio=1
)
self.forward()
See also:
In this example, we use a dot to represent the camera center, and through fix_in_frame(), the dot and several hint texts are kept stationary in the frame
Dynamically Adjusting Position with Animation Methods¶
Like regular items, we can clearly use animations to control the camera position and create interesting effects:
axes = Axes(
(0, 10), (0, 5),
axis_config={
'include_tip': True,
'include_numbers': True,
}
)
graph = axes.get_graph(lambda x: math.sin(x) + x / 2, color=BLUE)
dot = SmallDot(axes.c2p(), glow_alpha=0.5)
self.show(axes, graph)
self.camera.points.move_to(axes)
self.camera.save_state()
self.play(
self.camera.anim.points.move_to(dot).scale(0.35),
FadeIn(dot, scale=0.5),
)
self.play(
MoveAlongPath(dot, graph),
MoveAlongPath(self.camera, graph),
duration=4
)
self.play(
FadeOut(dot),
self.camera.anim.load_state()
)
See also:
Similarly, you can also add some Updater to the camera and try it out.
Others¶
JAnim GUI provides a convenient feature to adjust the camera in the preview window; see camera Command for details
For using cameras in 3D space, refer to the description on the 3D Scene page