54 Scenes and sampling
Use these operations to build a Scene and ask for its state at a time. For a short first program, see Quick Start: a moving circle.
procedure
(make-scene [initial-state #:camera camera]) → scene?
initial-state : scene-state? = empty-scene-state camera : camera? = default-camera
Visuals are added in argument order. Each later argument is placed in front of earlier Visuals. Adding a top-level identity already present as a Visual or named scalar in the current state raises an exception. A group is added as one top-level Visual; its child order remains internal to the group. A derived-visual? is likewise stored as one top-level identity and is resolved only when concrete geometry is requested.
An instantaneous addition at the exact end of a scene is not normally included in frame sampling. Follow it with scene-wait or scene-play when it must be visible in rendered output. Supplying no Visuals returns an equivalent scene.
procedure
(scene-remove scene target ...) → scene?
scene : scene? target : (or/c visual? symbol? visual-path?)
procedure
scene : scene? target : (or/c visual? symbol? visual-path?)
procedure
(scene-visual-at scene target time) → visual?
scene : scene? target : (or/c visual? symbol? visual-path?) time : (and/c finite-real? (>=/c 0))
procedure
(scene-set-value scene id value) → scene?
scene : scene? id : (or/c symbol? scene-parameter?) value : any/c
The two-argument shorthand (scene-set-value scene parameter) accepts a scene-parameter? and installs its declared initial value.
procedure
(scene-remove-value scene id) → scene?
scene : scene? id : (or/c symbol? scene-parameter?)
procedure
(scene-current-value scene id) → any/c
scene : scene? id : (or/c symbol? scene-parameter?)
procedure
(scene-value-at scene id time) → any/c
scene : scene? id : (or/c symbol? scene-parameter?) time : (and/c finite-real? (>=/c 0))
procedure
(scene-set-camera scene camera) → scene?
scene : scene? camera : camera?
An instantaneous replacement at the exact end of a scene is not normally included in frame sampling. Follow it with scene-wait or scene-play when the replacement must appear in rendered output.
When #:duration is omitted, ordinary requests default to one second. A direct write-in uses Manim’s default instead: one second for fewer than fifteen writable leaves and two seconds for fifteen or more. An explicit positive duration always takes precedence.
When at least one timing/composition value is present, every Visual, scalar, or camera request resolves to one or more concrete local intervals. A top-level timed value uses literal second-based start and duration and may wrap either one leaf or one composition. An ordinary unwrapped top-level Visual or camera request spans the complete enclosing clip.
Inside compositions, unwrapped direct children contribute one timing unit and a timed direct child contributes (+ start duration) units. A succession places those spans consecutively, an animation group starts them together and scales against the longest span, and a lagged start offsets raw starts by its lag ratio before scaling the complete envelope. Bare nested compositions remain one-unit direct children unless explicitly wrapped by timed. All three composition forms may nest arbitrarily with timed Visual/camera composition children.
Equal-start Visual leaves are compiled together against one prepared local start state. A later start batch is compiled against the exact semantic state sampled at that local boundary, so a touching relative request starts from the previous request’s exact endpoint rather than the enclosing clip start. Sampling remains direct and does not depend on rendering prior frames.
Structural introduction requests are installed only at their local start. A create request adds an empty-path placeholder, fade-in adds the complete Visual at opacity zero, and enter adds an affine/opacity appearance proxy. Requests beginning at that same local time share the prepared state, so movement, rotation, scaling, opacity, and compatible geometry changes can compose with an introduction. A fade-out, uncreate, or leave removal may not end while another animation of that target remains active; reintroduction at the exact removal boundary is allowed.
Positive-measure overlap on the same Visual component is rejected. Touching intervals are not overlap and are legal. Requests for disjoint components may overlap freely.
Camera requests use the same local intervals. A later pan, zoom, fit, or follow compiles from the exact camera view at its local start. camera-pan-by therefore adds to that local center, and camera-zoom-by divides that local visible width by its magnification factor. A camera-follow captures its target’s frame offset at the start of its own interval, samples the target’s actual local Visual state while active, and holds the resulting endpoint view after it ends. A camera-fit request remains a concrete center/width snapshot measured when it was constructed. Camera and Visual requests may appear in any order.
A single list of requests can be supplied in place of separate request arguments:
(scene-play scene (list (move-to 'a (vec2 2 0)) (rotate-by 'a 1) (camera-pan-to (vec2 1 0)) (camera-zoom-by 2)) #:duration 2)
At least one request is required. Each composition value itself also requires at least one child. In the full-clip case, two simultaneous requests may target the same Visual when every component they change is disjoint. With local timing, the same rule applies only where the request intervals overlap. The components in this version are translation, rotation, scale, opacity, path geometry, formula parts, and scene presence. Both move-to and move-along-path reserve translation. orient-along-path, rotate-to, and rotate-by reserve rotation. A request can change more than one component: fade-in and fade-out change opacity and presence; enter changes presence plus only its nonidentity affine/opacity components; leave does the same and reserves presence when it removes; create and uncreate change path geometry and presence, and transform-formula-parts changes formula parts and reserves presence.
Two overlapping requests may not change the same component for the same identity. Exact endpoint touching is allowed. Thus overlapping opacity requests conflict. Strict morphing, normalized morphing, creation, and uncreation conflict on path geometry. Two formula-part transformations conflict on formula parts. A formula-part transformation also conflicts with a same-target structural introduction or removal because both reserve presence. Requests for different identities do not conflict.
The camera center and visible world width are separate camera components. Pan and follow requests change the center. Zoom requests change visible width. A fit request changes both. One follow request and one zoom request may run together. Overlapping requests that reserve the same camera component raise an exception, so fit conflicts with pan, follow, zoom, or another fit for the same local interval. Touching camera intervals are legal and hand off exactly. Camera components do not conflict with Visual components.
Before easing is called, progress is clamped to the closed unit interval. The easing result must be a finite real and is also clamped to that interval. A normal easing procedure should map 0 to 0 and 1 to 1. Transform component endpoints follow the easing result.
Introduction, removal, and formula-part transformation requests have structural endpoint rules. For an untimed request the structural endpoint is the play-clip boundary; for a timed request it is the local interval endpoint. At that endpoint, a completed create contains the complete original path, a completed fade-in contains the supplied final opacity, a completed enter contains its exact authored Visual, and a completed transform-formula-parts contains the exact destination part list. A completed uncreate, fade-out, or removing leave removes its target. These rules apply even when easing does not map one to one. Such an easing procedure can therefore cause a discontinuity at the request endpoint.
A fade-to, morph-to, morph-to-normalized, morph-to-aligned, morph-to-open-aligned, morph-to-open-compound-aligned, or morph-to-compound-aligned request has no structural endpoint override. Like movement, rotation, scale, camera pan, camera zoom, camera fit, and camera follow, its final sampled value follows the easing result. A normalized morph preserves the exact source at eased progress zero and the exact requested destination at eased progress one. Camera animation preserves pixel dimensions and background throughout the clip.
procedure
(scene-wait scene duration) → scene?
scene : scene? duration : (and/c finite-real? positive?)
procedure
(scene-sample scene time) → scene-state?
scene : scene? time : (and/c finite-real? (>=/c 0))
Clip intervals are half-open. Sampling the exact total duration returns scene-current-state. This procedure samples only the Visual state; it does not apply camera animations. Camera values are sampled separately with scene-camera-at.
procedure
(scene-animation-inspections-at scene time)
→ (listof animation-inspection?) scene : scene? time : (and/c finite-real? (>=/c 0))
procedure
(animation-inspection? value) → boolean?
value : any/c
procedure
(animation-inspection-kind inspection) → any/c
inspection : animation-inspection?
procedure
(animation-inspection-data inspection) → any/c
inspection : animation-inspection?
procedure
(scene-camera-at scene time) → camera?
scene : scene? time : (and/c finite-real? (>=/c 0))
procedure
(scene-duration scene) → (and/c finite-real? (>=/c 0))
scene : scene?
procedure
(scene-current-state scene) → scene-state?
scene : scene?
procedure
(scene-current-camera scene) → camera?
scene : scene?
procedure
(scene-clip-count scene) → exact-nonnegative-integer?
scene : scene?