timeline¶
- class janim.anims.timeline.Timeline(*args, **kwargs)¶
Bases:
objectInherit this class and implement the
construct()method to implement the logic of building animationsCall
build()to get the constructedTimelineobject- CONFIG: Config | None = None¶
Defining this variable in a subclass can serve to set configuration, for example:
class Example(Timeline): CONFIG = Config( font=['Consolas', 'LXGW WenKai Lite'] ) def construct(self) -> None: ...
See also:
Config
- ctx_var: ContextVar = <ContextVar name='Timeline.ctx_var'>¶
- static get_context(raise_exc=True) Timeline | None¶
Call this method to get the current
Timelineobject being constructingIf called outside of
construct()andraise_exc=True(default), raisesTimelineLookupError
- class ScheduledTask(at: float, func: Callable, args: list, kwargs: dict)¶
Bases:
objectSee
schedule()- at: float¶
- func: Callable¶
- args: list¶
- kwargs: dict¶
- class TimeOfCode(time: float, line: int)¶
Bases:
objectMarks the time corresponding to the line number of code execution in
construct()- time: float¶
- line: int¶
- class PausePoint(at: 'float', at_previous_frame: 'bool')¶
Bases:
object- at: float¶
- at_previous_frame: bool¶
- class PlayAudioInfo(audio: Audio, range: TimeRange, clip_range: TimeRange)¶
Bases:
objectParameter information for calling
play_audio()
- class SubtitleInfo(text: str, range: TimeRange, kwargs: dict, subtitle: Text | TypstText)¶
Bases:
objectParameter information for calling
subtitle()- text: str¶
- kwargs: dict¶
- class ExtraRenderGroup(t_range: 'TimeRange', func: 'RenderGroupFn', related_items: 'list[Item] | None')¶
Bases:
object- func: RenderGroupFn¶
- abstractmethod construct() None¶
Implement this method to build the animation logic
- build_indent_ctx: ContextVar = <ContextVar name='Timeline.build_indent_ctx'>¶
- build(*, quiet=False, hide_subtitles=False, show_debug_notice=False) BuiltTimeline¶
Build the animation and return it
- with_config()¶
If called for the first time, it will apply the config defined in the
Timelinesubclass based on the current context and record itIf called subsequently, it will directly set to the recorded value, ensuring consistency across different contexts
- schedule(at: float, func: Callable, *args, **kwargs) None¶
Schedule execution
Calls
funcwhen the progress reachesat, can pass*argsand**kwargs
- schedule_and_detect_changes(at: float, func: Callable, *args, **kwargs) None¶
Similar to
schedule(), but records the state of changed items after callingfunc
- timeout(delay: float, func: Callable, *args, **kwargs) None¶
Equivalent to
schedule(self.current_time + delay, func, *args, **kwargs)
- timeout_and_detect_changes(delay: float, func: Callable, *args, **kwargs) None¶
Similar to
timeout(), but records the state of changed items after callingfunc
- forward(dt: float = 1, *, _detect_changes=True, _record_lineno=True)¶
Advance by
dtseconds
- forward_to(t: float, *, _detect_changes=True) None¶
Advance to time
t
- prepare(*anims: SupportsAnim, at: float = 0, name: str | None = 'prepare', **kwargs) TimeRange¶
- play(*anims: SupportsAnim, name: str | None = 'play', **kwargs) TimeRange¶
- pause_point(*, offset: float = 0, at_previous_frame: bool = True) None¶
Mark that in the preview interface, execution will pause when reaching the current time point
at_previous_framecontrols whether to pause at the previous frame (default) or at the current frameoffsetrepresents how many seconds to offset, e.g.,offset=2means 2 seconds after the current positionIn the GUI interface, you can use
Ctrl+Left Arrowto quickly move to the previous pause point, andCtrl+Right Arrowto quickly move to the next one
- aas(file_path: str, subtitle: str | Iterable[str], **kwargs) TimeRange¶
Short form of
audio_and_subtitle()
- audio_and_subtitle(file_path: str, subtitle: str | Iterable[str], *, clip: tuple[float, float] | None | EllipsisType = Ellipsis, delay: float = 0, mul: float | Iterable[float] | None = None, **subtitle_kwargs) TimeRange¶
Play audio and display subtitles in the corresponding interval
If
clip=...(default, ellipsis), it automatically determines the clipping interval, removing leading and trailing silence (you can passclip=Noneto disable automatic clipping)If
mulis notNone, the audio amplitude will be multiplied by this value
- play_audio(audio: Audio, *, delay: float = 0, begin: float = 0, end: float = -1, clip: tuple[float, float] | None = None) TimeRange¶
Play audio at the current position
Can specify
beginandendto represent the clipping segmentCan specify that playback starts
delayseconds after the current positionIf
clipis specified, it will overridebeginandend(clipcan be considered a shorthand for both)
Return value represents the playback time range
- has_audio() bool¶
Whether this Timeline itself has playable audio
- has_audio_for_all() bool¶
Considering all child Timelines, whether there is playable audio
- subtitle(text: str | Iterable[str], duration: float = 1, *, delay: float = 0, scale: float | Iterable[float] = 0.8, use_typst_text: bool | Iterable[bool] = False, surrounding_color: JAnimColor = BLACK, surrounding_alpha: float = 0.5, font: str | Iterable[str] = [], depth: float = -100000.0, **kwargs) TimeRange¶
- subtitle(text: str | Iterable[str], range: TimeRange, **kwargs) TimeRange
Add subtitle
Text can be passed as a list, displayed vertically
You can specify that the subtitle appears
delayseconds after the current positiondurationrepresents the durationscalerepresents the scaling of text. You can pass a list to specify scaling for each textuse_typst_textindicates whether to useTypstText. You can pass a list to specify whether each text uses itSet
surrounding_alphato0to disable the background box
Configalso provides some configurable parameters:subtitle_fontglobally configures the font used for subtitlessubtitle_to_edge_buffconfigures the distance from the subtitle to the bottom edge; defaults toDEFAULT_ITEM_TO_EDGE_BUFF
Return value represents the display time range
- place_subtitle(subtitle: Text | TypstText, range: TimeRange) None¶
Called by
subtitle()to place subtitles in appropriate positions:For subtitles added in the same batch
[a, b],ais placed abovebIf
[a, b]mentioned above still exists and acis added, thencis placed at the top
- has_subtitle() bool¶
- class ItemAppearance(item: Item, aligner: TimeAligner)¶
Bases:
objectContains objects related to item display
self.stackis theAnimStackobjectself.visiblilityis a list storing the time points when items are shown/hidden - Even indices (0, 2, …) represent the time points when display starts, odd indices (1, 3, …) represent the time points when hiding occurs - For example, if the list is[3, 4, 8], it means display at 3s, hide at 4s, and display continuously after 8s - This recording method is the basis forTimeline.is_visible(),Timeline.show(),Timeline.hide()operationsself.rendererrepresents the renderer object being used
- is_visible_at(t: float) bool¶
Whether the item is visible at time
t
- class ItemAppearancesDict(time_aligner: TimeAligner)¶
Bases:
defaultdict[Item,ItemAppearance]
- track_item_and_descendants(item: Item, *, root_only: bool = False) None¶
Equivalent to calling
track()onitemand all its descendant items
- detect_changes(items: Iterable[Item]) None¶
Check changes of items in the specified list and record them as
Display(Only checks itself, excluding descendant items)
- hide_all() None¶
Hide all items currently displayed
- add_extra_render_group(t_range: TimeRange, func: RenderGroupFn, related_items: list[Item] | None) None¶
- get_construct_lineno() int | None¶
Get the current line number being executed in
construct()
- get_lineno_at_time(time: float)¶
Get the corresponding line number based on
time.
- class GuiCommand(global_t: float, text: str, frame: FrameType)¶
Bases:
object
- exception GuiCommandInterrupt(command: GuiCommand)¶
Bases:
Exception
- debug(item: Item, msg: str | None = None) None¶
Display the item’s animation stack in the timeline
Tip
A yellow bar displayed in the timeline indicates in which ranges the item is visible
Warning
Some animations are overriding, such as direct data changes (
Display) and.anim(MethodTransform). Don’t be confused if you don’t see the expected stack structure
- static fmt_time(t: float) str¶
- dbg_time(ext_msg: str = '') None¶
- class janim.anims.timeline.SourceTimeline(*args, **kwargs)¶
Bases:
TimelineCompared to
Timeline, this will display the source code in the background.- source_object() object¶
- build(*, quiet=False, hide_subtitles=False, show_debug_notice=False) BuiltTimeline¶
Build the animation and return it
- class janim.anims.timeline.ListedTimelines(*args, **kwargs)¶
Bases:
TimelineSpecify a group of
Timelineimplementations and play them in sequenceExample:
class Section0(Timeline): def construct(self): ... class Section1(Timeline): def construct(self): ... class Section2(Timeline): def construct(self): ... class Sections(ListedTimelines): includes = [Section1, Section2]
- construct()¶
- class janim.anims.timeline.AboveTimelines(*args, **kwargs)¶
Bases:
ListedTimelinesPlay all
Timelineimplementations previously defined in the same file, in orderExample:
class Section0(Timeline): def construct(self): ... class Section1(Timeline): def construct(self): ... class Section2(Timeline): def construct(self): ... class Sections(AboveTimelines): pass
You can additionally use
excludesto specify excluded itemsExample:
... class Sections(AboveTimelines): excludes = [Section0]
- construct()¶
- class janim.anims.timeline.BuiltTimeline(timeline: Timeline)¶
Bases:
objectInstance returned after running
Timeline.build()- property cfg: Config | ConfigGetter¶
- get_audio_samples_of_frame(fps: float, framerate: int, frame: int, *, count: int = 1) ndarray¶
Extract the audio stream of a specific frame
- current_camera_info(*, as_time: float | None = None) CameraInfo¶
Get the current
CameraInfoinformationHere, “current” means the
global_tmoment from the last call torender_all(); you can also specify it by passingas_time
- render_all(ctx: Context, global_t: float, *, camera: Camera | None = None) bool¶
Render all visible items
- capture(global_t: float, *, transparent: bool = True, ctx: Context | None = None) Image¶
- to_item(**kwargs) TimelineItem¶
Use this method to insert another Timeline into a Timeline
For example:
class Sub1(Timeline): def construct(self): text = Text('text from Sub1') text.points.shift(UP) self.play( Rotate(text, TAU, about_point=LEFT * 2), duration=4 ) class Sub2(Timeline): def construct(self): text = Text('text from Sub2') text.points.shift(DOWN) self.play( Rotate(text, TAU, about_point=RIGHT * 2), duration=4 ) class Test(Timeline): def construct(self): tl1 = Sub1().build().to_item().show() tl2 = Sub2().build().to_item().show() self.forward_to(tl2.end)
In this example,
Sub1andSub2are inserted intoTestAdditional parameters:
delay: How many seconds to delay before starting playback of this Timelinefirst_frame_duration: How many seconds the first frame lastskeep_last_frame: Whether to keep displaying the last frame after the Timeline ends
- to_playback_control_item(**kwargs) TimelinePlaybackControlItem¶
Use this method to insert another Timeline into a Timeline
And similar to
Video, you can usestart,stop, andseekto control playback progressExample:
class Sub(Timeline): def construct(self): self.play( ItemUpdater( None, lambda p: Text(f'{p.global_t:.2f}') ), duration=8 ) class Test(Timeline): def construct(self): sub = Sub().build().to_playback_control_item().show() sub.start() self.forward(2) sub.start(speed=0.1) self.forward(2) sub.seek(0).start(speed=4) self.forward(2)
Warning
By default, playback is not started; you need to use
startto begin playbackAdditional parameters:
keep_last_frame: Whether to keep displaying the last frame after the Timeline ends
- class janim.anims.timeline.TimelineItem(built: BuiltTimeline, *, delay: float = 0, first_frame_duration: float = 0, keep_last_frame: bool = False, **kwargs)¶
Bases:
ItemSee
BuiltTimeline.to_item()for details- class TIRenderer¶
Bases:
Renderer- render(item: TimelineItem)¶
- renderer_cls¶
alias of
TIRenderer
- start() Self¶
Start playing the sub-timeline from the current moment, keeping the first frame displayed before this moment
- property end: float¶
- class janim.anims.timeline.PlaybackControl(*args, loop: bool = False, **kwargs)¶
Bases:
object- start(*, speed: int = 1) Self¶
- stop() Self¶
- seek(t: float) Self¶
- compute_time(t: float, total: float | None = None) float¶
- class janim.anims.timeline.TimelinePlaybackControlItem(built: BuiltTimeline, *, keep_last_frame: bool = False, **kwargs)¶
Bases:
PlaybackControl,ItemSee
BuiltTimeline.to_playback_control_item()for details- class TPCIRenderer¶
Bases:
Renderer- render(item: TimelinePlaybackControlItem)¶
- renderer_cls¶
alias of
TPCIRenderer