createCanvasController()v4.0.527
Creates a CanvasController to share between <Canvas> and your editor UI. In React components, useCanvasController() keeps one controller across renders.
Experimental API: This package is not stable. Its public API may change without a major version bump.
controller.tsimport {createCanvasController} from '@remotion/sdk'; export const controller = createCanvasController();
The function takes no arguments.
Return value
timeline
An external store of readonly TimelineTrackData[]. Subscribe with timeline.subscribe(listener) and read with timeline.getSnapshot(). In React, pass both to useSyncExternalStore() as shown in the overview. Tracks are populated while the composition is mounted and cleared when <Canvas> unmounts.
Each track includes sequence registration data, depth, nodePathInfo, and timing fields such as cascadedStart, localStart, keyframeDisplayOffset, keyframePlaybackRate, and sequenceFrameOffset. The sequence's from and duration are its visible timeline range. nodePathInfo is null until a source identity is registered with setSequenceNodePaths().
sequence.controlsv4.0.529
The interactivity data of the mounted element, or null for elements that do not register any. The <Canvas> populates it for built-in elements and for components wrapped with Interactive.withSchema().
schema is the element's interactivity schema, describing the editable props, their types, ranges and defaults. runtimeValues is a store of the current prop values in dot notation, for example style.opacity; read it with getSnapshot() and subscribe(). supportsEffects tells whether effects can be added to the element, componentIdentity identifies the component and overrideId identifies the JSX element the sequence was created from. Sequences rendered from the same element, for example in a .map() loop, share an overrideId.
selection
A CanvasSelectionController with getSnapshot() and subscribe(listener) for reading selection. Use useCanvasSelection() in React.
select()
select(item, interaction, allSelectableItems) applies one selection interaction. interaction has shiftKey for range selection and toggleKey for Command/Ctrl toggling. allSelectableItems is the ordered list used to calculate ranges.
setSelectedItems()
setSelectedItems(items) replaces the selected items and uses the last item as the range anchor.
setSnapshot()
setSnapshot({selectedItems, anchor}) replaces the complete selection state.
clear()
clear() removes every selection item.
hover
A CanvasHoverController with getSnapshot(), subscribe(listener), setHoveredSequence(valueOrUpdater), and clear(source). Use useCanvasSequenceHover() for a layer row or useCanvasHover() to read the current hover. clear('canvas') or clear('timeline') only clears hover from that source; clear(null) clears either source.
setSequenceNodePaths()v4.0.529
setSequenceNodePaths(nodePaths) tells the Canvas which source node each mounted sequence was created from. nodePaths is a Record<string, SequencePropsSubscriptionKey> keyed by track.sequence.controls.overrideId. Import the SequencePropsSubscriptionKey type from remotion; its absolutePath and nodePath identify the JSX node, as returned by getNodes(). Pass empty arrays for sequenceKeys and effectKeys, and track.sequence.controls.videoConfigValues or null for videoConfigValues.
Afterwards, the affected tracks carry a nodePathInfo with that sequenceSubscriptionKey. Tracks rendered from the same source node are numbered through index and numberOfSequencesWithThisNodePath. getCanvasSequenceNodePathInfo() returns the registered identity, so selection and hover stay attached to the source node across remounts.
Passing an unchanged mapping is a no-op, so the function may be called from a timeline subscription. Call it again after the source changed. getCanvasSequenceSourceLocation() shows how to derive the mapping from the compiled source locations.
queueSequenceNodePathRemappings()v4.0.530
queueSequenceNodePathRemappings(remappings) hands the Canvas the nodePathRemappings that a mutation of @remotion/codemods returned. remappings is an array of {filePath, oldNodePath, newNodePath} entries, where filePath matches the absolutePath of the registered node paths. A null old path is an insertion, a null new path a removal.
Queue the remappings when you apply the edit to your project. The Canvas commits them when the next Fast Refresh update starts, immediately before React commits the refreshed tree, so the registered node paths and the selection never pair the new elements with the old paths. Studio's bundler, Browser Studio and createBrowserBundleRuntime() dispatch that event. Call queueSequenceNodePathRemappings() once per edit; the remappings of one edit are not chained with each other, only with those of earlier edits.
Applying an editexport constremoveNodes = async () => { constresult = awaitdeleteNodes ({project ,nodes });controller .queueSequenceNodePathRemappings (result .nodePathRemappings );compile (applyCodemodChanges (project ,result .changes )); };
Selected items whose node was removed leave the selection, other selected items follow their node to its new path. Override IDs belong to mounted instances, which Fast Refresh keeps at paths that still exist after the edit; a registered node path therefore only follows its node when its old path disappeared. Hover is cleared. Registering the resolved mapping again with setSequenceNodePaths() after the compilation confirms the result and covers edits that produced no remappings.
remapSequenceNodePaths()v4.0.530
remapSequenceNodePaths(remappings) applies the remappings of one edit right away instead of queueing them. Use it when you swap the mounted tree yourself, in the same task as the swap.
overridesv4.0.529
Preview prop values on mounted sequences without changing the source. Overrides are applied to sequences that have a nodePathInfo, so register node paths first. They are kept while the composition stays mounted and are not persisted; write the final value to the source, for example with updateNodeProps(), and clear the override once the update has been applied.
The Canvas sets overrides itself while an outline is being moved, and startCanvasKeyframeDrag() sets them while keyframes are dragged. Both leave them in place for you to clear after persisting. getCanvasKeyframeChangeOverride() computes the value that previews any other keyframe change, such as a new easing.
set()
set(nodePathInfo, key, value) overrides one prop of the sequence identified by nodePathInfo, a SequenceNodePathInfo from a track or a selection item. key is a key of the element's interactivity schema in dot notation, such as 'style.translate', 'from' or 'durationInFrames'.
value is either {type: 'static', value} to show a fixed value, or {type: 'keyframed', status} where status is a keyframed prop status as returned by getNodeProps() with the keyframes you want to preview. A keyframed override is evaluated at the current frame.
Scrubbing a valueexport constonScrub = (value : number) => {controller .overrides .set (nodePathInfo , 'style.opacity', {type : 'static',value , }); }; export constonScrubEnd = async (value : number) => { awaitpersist (value );controller .overrides .clear (nodePathInfo ); };
The runtimeValues of the track keep reporting the values from the source while an override is active.
clear()
clear(nodePathInfo) removes every override of the sequence.
Compatibility
| Browsers | Environments | |||||
|---|---|---|---|---|---|---|
Chrome | Firefox | Safari | ||||