Skip to content

SubScene

keyed_extras.subscene

SubScene

Bases: Base

A wrapper that embeds one Scene inside another.

SubScene enables hierarchical scene structures where a complete Scene can be treated as a single object within a parent Scene. This allows for powerful composition capabilities, such as:

- Creating reusable animation components that can be positioned and transformed
- Building complex animations from simpler, self-contained pieces
- Organizing related animations into logical groups
- Applying transformations (scale, position, opacity) to entire scenes at once

The child scene maintains its own animation timeline, which can be remapped to the parent scene's timeline using a time remapping function (see Tempo for a convenient way of constructing time remapping functions).

Tip

The keyed previewer command line tool opens the first scene discovered at the global scope. So, be sure to create the parent scene first.

You can also consider creating the child Scene within a function.

Parameters:

Name Type Description Default
scene Scene

The parent Scene in which this SubScene will be placed

required
child_scene Scene

The Scene to be embedded and rendered as an object

required
x HasValue[float] | None

X position in the parent scene.

None
y HasValue[float] | None

Y position in the parent scene.

None
scale HasValue[float]

Scale factor for the child scene.

1.0
alpha HasValue[float]

Opacity of the child scene (0.0-1.0).

1.0
remap TimeMap

Function to map parent scene frame numbers to child scene frame numbers. By default the child timeline is synchronized with the parent's.

Tempo()

as_object

as_object(self, parent_scene, x=None, y=None, scale=1.0, alpha=1.0, remap=Tempo())

Convert this scene into an object that can be added to another scene.

Parameters:

Name Type Description Default
parent_scene Scene

The scene to add this scene to

required
x float | None

X position in the parent scene

None
y float | None

Y position in the parent scene

None
scale float

Scale factor

1.0
alpha float

Opacity

1.0
remap TimeMap

Map the parent scene's frame to the desired playback of the child scene.

Tempo()

Returns:

Type Description
SubScene

A SubScene that can be rendered and transformed within a parent scene.

keyed_extras.tempo

Remap time (useful for SubScene).

TimeMap module-attribute

Type for time remapping functions that transform one frame counter into another.

Tempo

A time mapper that chains transformations for expressive frame remapping.

This class provides a fluent API for composing time transformations by chaining methods that modify how frames are mapped from one timeline to another.

Example
# Create a complex time mapping:
# - Play at half speed
# - Start 10 frames in
# - Stop at frame 30
remap = Map().stretch(0.5).shift(10).clamp(max_frame=30)

# Apply this to scene.frame
subscene = SubScene(scene, child_scene, remap=remap)
scene.add(subscene)

shift

shift(offset)

Shift the timeline by a fixed offset.

Parameters:

Name Type Description Default
offset int

Number of frames to shift.

required

Returns:

Type Description
Self

Self

stretch

stretch(factor, fixed_point=0)

Speed up or slow down time from a fixed point.

Can be used to speed up for slow down playback.

Parameters:

Name Type Description Default
factor float

Speed factor (>1 = faster, <1 = slower)

required
fixed_point int

Frame that remains unchanged by the scaling (default 0)

0

Returns:

Type Description
Self

Self

reverse_from

reverse_from(start_from)

Reverse time, playing from start_from backwards.

Parameters:

Name Type Description Default
start_from int

The frame to start playing in reverse from

required

Returns:

Type Description
Self

Self

loop

loop(*args)

Iterate over a range of frames repeatedly.

This follows Python's built-in range function behavior: - loop(stop): cycles through range(0, stop, 1) - loop(start, stop): cycles through range(start, stop, 1) - loop(start, stop, step): cycles through range(start, stop, step)

Tip

It is typically more intuitive to apply any desired stretching before looping.

Parameters:

Name Type Description Default
*args int

1-3 integer arguments following the same pattern as range()

()

Returns:

Type Description
Self

Self

Examples:

# Loop frames 0-9 repeatedly
remap = Tempo().loop(10)

# Loop frames 5-14 repeatedly, skipping every other frame
remap = Tempo().loop(5, 15, 2)

ping_pong

ping_pong(*args)

Play a segment forward then backward repeatedly.

This follows Python's built-in range function behavior: - ping_pong(stop): cycles through range(0, stop, 1) forward and backward - ping_pong(start, stop): cycles through range(start, stop, 1) forward and backward - ping_pong(start, stop, step): cycles through range(start, stop, step) forward and backward

Tip

It is typically more intuitive to apply any desired stretching before ping ponging.

Parameters:

Name Type Description Default
*args int

1-3 integer arguments following the same pattern as range()

()

Returns:

Type Description
Self

Self

Examples:

# Ping-pong frames 0-9 repeatedly
remap = Tempo().ping_pong(10)

# Ping-pong frames 5-14 repeatedly
remap = Tempo().ping_pong(5, 15)

# Ping-pong frames 5, 7, 9, 11, 13 repeatedly
remap = Tempo().ping_pong(5, 15, 2)

clamp

clamp(min_frame=0, max_frame=None)

Clamp time to a range.

Parameters:

Name Type Description Default
min_frame int

Minimum frame

0
max_frame Optional[int]

Maximum frame

None

Returns:

Type Description
Self

Self

pause

pause(at_frame, for_duration)

Pause the timeline at a specific frame for a certain duration.

Parameters:

Name Type Description Default
at_frame int

The frame at which to pause

required
for_duration int

How many frames to hold the pause

required

Returns:

Type Description
Self

Self

ramp_speed

ramp_speed(start_frame, end_frame, start_speed, end_speed)

Gradually change the playback speed over a range of frames.

Parameters:

Name Type Description Default
start_frame int

Frame to start the speed change

required
end_frame int

Frame to end the speed change

required
start_speed float

Initial speed factor (e.g., 1.0 = normal speed)

required
end_speed float

Final speed factor

required

Returns:

Type Description
Self

Self

jump

jump(from_frame, to_frame)

Jump from one frame to another instantly.

Parameters:

Name Type Description Default
from_frame int

Frame to jump from

required
to_frame int

Frame to jump to

required

Returns:

Type Description
Self

Self

interp

interp(mapping, kind='linear')

Map frames with advanced interpolation between keyframes.

Parameters:

Name Type Description Default
mapping dict[int, int]

Dictionary mapping source frames to destination frames

required
kind str

Interpolation type to use: - 'linear': Simple straight-line interpolation with direct connections between keyframes. - 'previous': Step function using the previous point's value. Creates a stair-step effect where timing changes at each keyframe. - 'next': Step function using the next point's value. Creates a stair-step effect with immediate jumps to the next value. - 'nearest': Uses the value of the nearest keyframe. Creates a stair-step effect with transitions at midpoints. - 'pchip': Piecewise Cubic Hermite Interpolating Polynomial. Creates smooth, natural-looking transitions that minimize oscillations. - 'akima': Alternative spline interpolation that reduces oscillations. Good for smooth transitions while being less influenced by outliers.

'linear'

Returns:

Type Description
Self

Self

Raises:

Type Description
ValueError

If kind is not supported.

Example
# Create smooth acceleration and deceleration
remap = Tempo().interp({
    0: 0,    # Start
    30: 10,  # Slow start (frames 0-30 map to frames 0-10)
    60: 50,  # Speed up in the middle (frames 30-60 map to frames 10-50)
    90: 60   # Slow down at the end (frames 60-90 map to frames 50-60)
}, kind='pchip')

# Create a time loop effect (non-monotonic mapping)
remap = Tempo().interp({
    0: 0,     # Start
    30: 60,   # Normal playback
    60: 30,   # Play in reverse
    90: 0     # Back to start
})

ease

ease(easing_function, duration)

Apply an easing function to time.

Parameters:

Name Type Description Default
easing_function Callable[[float], float]

A function that takes a value 0-1 and returns a remapped value 0-1

required
duration int

Total duration over which to apply the easing

required

Returns:

Type Description
Self

Self

stretch_between

stretch_between(start_point, end_point, factor)

Stretch or compress time between two fixed points.

This keeps both points fixed in the timeline while stretching or compressing the frames between them.

Parameters:

Name Type Description Default
start_point int

First fixed point (remains at the same time)

required
end_point int

Second fixed point (remains at the same time)

required
factor float

Stretch factor (<1 = stretch/slow down, >1 = compress/speed up)

required

Returns:

Type Description
Self

Self

remap_range

remap_range(source_start, source_end, target_start, target_end)

Remap a range of frames to a different range.

Parameters:

Name Type Description Default
source_start int

First frame of source range

required
source_end int

Last frame of source range

required
target_start int

First frame of target range

required
target_end int

Last frame of target range

required

Returns:

Type Description
Self

Self