@remotion/studio 4.0.527 → 4.0.528
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AgentPrompt.js +1 -2
- package/dist/components/AudioWaveform.d.ts +1 -0
- package/dist/components/AudioWaveform.js +10 -14
- package/dist/components/CodeFrame.js +1 -1
- package/dist/components/ColorPicker/checker.d.ts +1 -1
- package/dist/components/CurrentAsset.js +3 -2
- package/dist/components/EditorRuler/Ruler.js +6 -3
- package/dist/components/EffectPickerModal.js +69 -43
- package/dist/components/ElementInstallConfirmation.js +3 -3
- package/dist/components/ElementLibrariesSettings.d.ts +2 -0
- package/dist/components/ElementLibrariesSettings.js +200 -0
- package/dist/components/InitialCompositionLoader.js +3 -1
- package/dist/components/InspectorOpenInEditor.js +13 -0
- package/dist/components/InspectorPanel/AlignmentControls.js +28 -9
- package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +1 -1
- package/dist/components/InspectorPanel/EasingInspector.js +6 -2
- package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -1
- package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +1 -1
- package/dist/components/InspectorPanel/KeyframeInspector.js +28 -24
- package/dist/components/InspectorPanel/MultiSequenceNumberField.js +1 -1
- package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -1
- package/dist/components/InspectorPanel/SequenceSelectionInspector.js +30 -2
- package/dist/components/InspectorPanel/SequenceWrapAction.d.ts +8 -0
- package/dist/components/InspectorPanel/SequenceWrapAction.js +151 -0
- package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +2 -1
- package/dist/components/InspectorPanel/easing-inspector-selection.js +4 -3
- package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +2 -1
- package/dist/components/InspectorPanel/keyframe-inspector-frame.js +2 -2
- package/dist/components/InspectorSequenceSection.d.ts +1 -0
- package/dist/components/InspectorSequenceSection.js +7 -5
- package/dist/components/KeyboardShortcutsSettings.js +1 -1
- package/dist/components/Menu/styles.d.ts +2 -2
- package/dist/components/Modals.js +7 -6
- package/dist/components/ModelManager.js +10 -9
- package/dist/components/NewComposition/CancelButton.js +10 -4
- package/dist/components/NewComposition/InputDragger.d.ts +3 -1
- package/dist/components/NewComposition/InputDragger.js +28 -9
- package/dist/components/NewComposition/NewComposition.js +7 -6
- package/dist/components/NewComposition/RemInput.d.ts +1 -1
- package/dist/components/NewComposition/menu-typeahead.js +1 -1
- package/dist/components/Preview.js +3 -2
- package/dist/components/RenderModal/SchemaEditor/create-zod-values.js +1 -2
- package/dist/components/RenderModal/WebRenderModalPicture.js +1 -2
- package/dist/components/RenderQueue/CaptionQueueItem.js +14 -5
- package/dist/components/RenderQueue/CaptionQueueProcessor.js +30 -7
- package/dist/components/RenderQueue/QueueJobError.d.ts +8 -0
- package/dist/components/RenderQueue/QueueJobError.js +24 -0
- package/dist/components/RenderQueue/QueueJobErrorModal.d.ts +8 -0
- package/dist/components/RenderQueue/QueueJobErrorModal.js +63 -0
- package/dist/components/RenderQueue/RenderQueueItemCancelButton.d.ts +3 -1
- package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +11 -4
- package/dist/components/RenderQueue/RenderQueueRepeat.d.ts +3 -1
- package/dist/components/RenderQueue/RenderQueueRepeat.js +20 -3
- package/dist/components/RenderQueue/VideoMattingQueueItem.js +24 -27
- package/dist/components/RenderQueue/VideoMattingQueueProcessor.js +68 -28
- package/dist/components/RenderQueue/caption-job-types.d.ts +3 -1
- package/dist/components/RenderQueue/context.d.ts +4 -0
- package/dist/components/RenderQueue/context.js +58 -8
- package/dist/components/RenderQueue/index.js +2 -3
- package/dist/components/RenderQueue/load-model-for-job.d.ts +2 -1
- package/dist/components/RenderQueue/load-model-for-job.js +5 -1
- package/dist/components/RenderQueue/video-matting-job-types.d.ts +13 -6
- package/dist/components/SelectedOutlineCropControls.js +2 -1
- package/dist/components/SelectedOutlineEditingHandles.js +9 -2
- package/dist/components/SelectedOutlineElement.js +9 -3
- package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -4
- package/dist/components/SelectedOutlineKeyboardControls.js +4 -22
- package/dist/components/SelectedOutlineOverlay.js +152 -106
- package/dist/components/SelectedOutlinePathPoints.d.ts +8 -0
- package/dist/components/SelectedOutlinePathPoints.js +433 -0
- package/dist/components/SelectedOutlinePolygon.js +21 -46
- package/dist/components/SelectedOutlineRenderer.d.ts +3 -5
- package/dist/components/SelectedOutlineRenderer.js +32 -136
- package/dist/components/SelectedOutlineTransformOriginHandle.js +3 -2
- package/dist/components/SelectedOutlineUvControls.js +12 -7
- package/dist/components/SettingsModal.js +30 -3
- package/dist/components/SettingsModalFooter.d.ts +1 -0
- package/dist/components/SettingsModalFooter.js +7 -3
- package/dist/components/ShowOutlinesProvider.js +1 -1
- package/dist/components/SkillsSettings.d.ts +0 -1
- package/dist/components/SkillsSettings.js +13 -14
- package/dist/components/Splitter/SplitterElement.js +1 -2
- package/dist/components/TimeValue.js +1 -1
- package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +1 -0
- package/dist/components/Timeline/LoopedTimelineIndicators.js +7 -6
- package/dist/components/Timeline/TimelineArrayField.js +1 -1
- package/dist/components/Timeline/TimelineClipboardKeybindings.js +0 -1
- package/dist/components/Timeline/TimelineColorField.js +1 -1
- package/dist/components/Timeline/TimelineDragHandler.js +1 -1
- package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
- package/dist/components/Timeline/TimelineEffectPropItem.js +12 -5
- package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
- package/dist/components/Timeline/TimelineExpandedRow.js +5 -4
- package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
- package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
- package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +1 -0
- package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +3 -1
- package/dist/components/Timeline/TimelineFontFamilyField.js +12 -12
- package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -0
- package/dist/components/Timeline/TimelineKeyframeControls.js +39 -28
- package/dist/components/Timeline/TimelineLayerChildren.js +1 -1
- package/dist/components/Timeline/TimelineList.js +1 -1
- package/dist/components/Timeline/TimelineNumberField.js +2 -4
- package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -1
- package/dist/components/Timeline/TimelineSelection.d.ts +9 -9
- package/dist/components/Timeline/TimelineSelection.js +16 -9
- package/dist/components/Timeline/TimelineSequence.d.ts +3 -1
- package/dist/components/Timeline/TimelineSequence.js +39 -21
- package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
- package/dist/components/Timeline/TimelineSequenceItem.js +18 -8
- package/dist/components/Timeline/TimelineSequencePropItem.d.ts +3 -0
- package/dist/components/Timeline/TimelineSequencePropItem.js +262 -25
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +11 -13
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +98 -77
- package/dist/components/Timeline/TimelineTextContentField.js +27 -4
- package/dist/components/Timeline/TimelineTimeIndicators.js +10 -5
- package/dist/components/Timeline/TimelineTrack.js +1 -1
- package/dist/components/Timeline/TimelineTrimTooltip.d.ts +11 -0
- package/dist/components/Timeline/TimelineTrimTooltip.js +41 -0
- package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
- package/dist/components/Timeline/TimelineVideoInfo.js +13 -10
- package/dist/components/Timeline/delete-selected-keyframe.js +22 -8
- package/dist/components/Timeline/delete-selected-timeline-item.d.ts +1 -5
- package/dist/components/Timeline/delete-selected-timeline-item.js +7 -93
- package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +2 -1
- package/dist/components/Timeline/get-animation-item-selection-for-frame.js +7 -5
- package/dist/components/Timeline/get-keyframed-sequence-drag-targets.d.ts +23 -0
- package/dist/components/Timeline/get-keyframed-sequence-drag-targets.js +57 -0
- package/dist/components/Timeline/get-node-keyframes.d.ts +2 -1
- package/dist/components/Timeline/get-node-keyframes.js +6 -4
- package/dist/components/Timeline/get-playback-rate-keyframe-changes.d.ts +21 -0
- package/dist/components/Timeline/get-playback-rate-keyframe-changes.js +142 -0
- package/dist/components/Timeline/get-timeline-keyframes.d.ts +15 -2
- package/dist/components/Timeline/get-timeline-keyframes.js +44 -6
- package/dist/components/Timeline/keyframe-clipboard.js +17 -3
- package/dist/components/Timeline/split-selected-timeline-item.js +4 -1
- package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
- package/dist/components/Timeline/timeline-field-row-layout.js +1 -0
- package/dist/components/Timeline/use-delete-timeline-items.js +17 -11
- package/dist/components/Timeline/use-expanded-track-keyframe-rows.d.ts +2 -1
- package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +3 -1
- package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +7 -3
- package/dist/components/Timeline/use-timeline-keyframe-drag.js +28 -19
- package/dist/components/Transcription/Models.js +1 -1
- package/dist/components/Transcription/TranscriptionModal.js +3 -1
- package/dist/components/Transcription/resample-media-to-16-khz.d.ts +2 -1
- package/dist/components/Transcription/resample-media-to-16-khz.js +20 -2
- package/dist/components/UpdatesSettings.js +2 -0
- package/dist/components/VideoMatting/Models.js +1 -1
- package/dist/components/VideoMatting/VideoMattingModal.js +30 -47
- package/dist/components/VideoMatting/VideoMattingModalWithOptionalPackage.js +1 -1
- package/dist/components/WebMcp.js +22 -40
- package/dist/components/composition-drop-preview.js +1 -0
- package/dist/components/effect-drag-and-drop.d.ts +13 -5
- package/dist/components/effect-drag-and-drop.js +19 -4
- package/dist/components/get-open-in-menu-items.d.ts +2 -1
- package/dist/components/get-open-in-menu-items.js +17 -1
- package/dist/components/selected-outline-drag.d.ts +1 -6
- package/dist/components/selected-outline-drag.js +22 -6
- package/dist/components/selected-outline-geometry.d.ts +2 -18
- package/dist/components/selected-outline-measurement.d.ts +23 -41
- package/dist/components/selected-outline-measurement.js +14 -252
- package/dist/components/selected-outline-order.d.ts +4 -11
- package/dist/components/selected-outline-order.js +2 -254
- package/dist/components/selected-outline-snap.d.ts +1 -1
- package/dist/components/selected-outline-snap.js +2 -1
- package/dist/components/selected-outline-types.d.ts +18 -28
- package/dist/components/selected-outline-uv.d.ts +4 -4
- package/dist/components/selected-outline-uv.js +6 -111
- package/dist/components/sequence-props-api.js +0 -10
- package/dist/components/use-selected-outline-control-target.js +12 -21
- package/dist/components/wrap-jsx-node-api.d.ts +2 -0
- package/dist/components/wrap-jsx-node-api.js +13 -0
- package/dist/error-overlay/remotion-overlay/OpenInEditor.js +45 -2
- package/dist/error-overlay/remotion-overlay/StackFrame.js +32 -3
- package/dist/esm/{CaptionQueueProcessor-npa6szn1.mjs → CaptionQueueProcessor-nr7hjcga.mjs} +63 -17
- package/dist/esm/LazyModels-ajkn7fs3.mjs +12 -0
- package/dist/esm/LazyModels-g1g7cf4e.mjs +12 -0
- package/dist/esm/{TranscriptionModal-79m5wgcj.mjs → TranscriptionModal-e18bzbkb.mjs} +15 -15
- package/dist/esm/{VideoMattingModal-31pew0xj.mjs → VideoMattingModal-5bz2s4rs.mjs} +47 -65
- package/dist/esm/{VideoMattingQueueProcessor-t1hgm2rm.mjs → VideoMattingQueueProcessor-4tkj0f4k.mjs} +69 -26
- package/dist/esm/{index-v4tr1bft.mjs → index-09txs1bj.mjs} +5 -0
- package/dist/esm/{index-n5gmcvhz.mjs → index-5ycb9e9q.mjs} +2 -4
- package/dist/esm/{index-5t2dwxsk.mjs → index-890dd9b3.mjs} +259 -21
- package/dist/esm/{index-ac5550e7.mjs → index-8nt6a0mw.mjs} +3 -3
- package/dist/esm/{index-614tdz2q.mjs → index-9q9w8v9p.mjs} +3 -3
- package/dist/esm/{index-s7qa3xbw.mjs → index-c2wabcdt.mjs} +6 -6
- package/dist/esm/{index-r1gr3j3a.mjs → index-dfy1t576.mjs} +50 -1
- package/dist/esm/{index-21hxsfaa.mjs → index-dh3zk2hv.mjs} +6 -25
- package/dist/esm/{index-4zen9prq.mjs → index-dpyss74p.mjs} +6563 -5485
- package/dist/esm/{index-9x6e1dq0.mjs → index-hqxc6tzp.mjs} +40 -6
- package/dist/esm/{index-9xxg6218.mjs → index-qve7mdfp.mjs} +19 -1
- package/dist/esm/{index-e855w59j.mjs → index-s6qya2gg.mjs} +3 -5
- package/dist/esm/index-t7tbt980.mjs +103 -0
- package/dist/esm/{index-r0ejh5sy.mjs → index-t7xnxdf8.mjs} +44 -26
- package/dist/esm/index-wqc43mw0.mjs +158 -0
- package/dist/esm/{index-ppspzgn9.mjs → index-x6r9bn12.mjs} +4026 -4761
- package/dist/esm/{index-vxwg66ar.mjs → index-xac20sv4.mjs} +44 -57
- package/dist/esm/index.mjs +4 -5
- package/dist/esm/internals.mjs +13 -13
- package/dist/esm/previewEntry.mjs +18 -15
- package/dist/esm/renderEntry.mjs +5 -1
- package/dist/helpers/calculate-timeline.d.ts +5 -1
- package/dist/helpers/calculate-timeline.js +1 -1
- package/dist/helpers/checkerboard-background.d.ts +2 -2
- package/dist/helpers/colors.d.ts +132 -112
- package/dist/helpers/colors.js +117 -95
- package/dist/helpers/create-folder-tree.js +2 -1
- package/dist/helpers/editor-guide-selection.d.ts +1 -1
- package/dist/helpers/editor-ruler.js +23 -12
- package/dist/helpers/get-connected-compositions.d.ts +6 -1
- package/dist/helpers/get-connected-compositions.js +1 -1
- package/dist/helpers/get-sequence-double-click-action.js +1 -1
- package/dist/helpers/get-sequence-visible-range.d.ts +1 -1
- package/dist/helpers/get-sequence-visible-range.js +2 -5
- package/dist/helpers/get-timeline-nestedness.d.ts +1 -1
- package/dist/helpers/get-timeline-nestedness.js +1 -1
- package/dist/helpers/get-timeline-sequence-sort-key.d.ts +1 -1
- package/dist/helpers/get-timeline-sequence-sort-key.js +1 -1
- package/dist/helpers/hoverable.js +4 -4
- package/dist/helpers/inject-css.js +5 -7
- package/dist/helpers/prism-vsc-dark-plus.d.ts +1 -1
- package/dist/helpers/prism-vsc-dark-plus.js +52 -51
- package/dist/helpers/resolve-studio-color.d.ts +1 -0
- package/dist/helpers/resolve-studio-color.js +11 -0
- package/dist/helpers/studio-css-variables.d.ts +1 -0
- package/dist/helpers/studio-css-variables.js +105 -0
- package/dist/helpers/studio-pixel-ratio.d.ts +1 -0
- package/dist/helpers/studio-pixel-ratio.js +7 -0
- package/dist/helpers/timeline-node-path-key.d.ts +1 -1
- package/dist/helpers/timeline-node-path-key.js +2 -2
- package/dist/helpers/use-runtime-values.js +2 -28
- package/dist/hot-middleware-client/client.js +5 -3
- package/dist/icons/align-center-horizontal.js +2 -1
- package/dist/icons/align-left.js +2 -1
- package/dist/icons/align-right.js +2 -1
- package/dist/icons/{separation.d.ts → background-removal.d.ts} +1 -1
- package/dist/icons/background-removal.js +9 -0
- package/dist/icons/wrap.d.ts +4 -0
- package/dist/icons/wrap.js +10 -0
- package/dist/previewEntry.js +2 -0
- package/dist/renderEntry.js +2 -0
- package/dist/state/modals.d.ts +15 -1
- package/dist/state/timeline-sequence-hover.d.ts +6 -16
- package/dist/state/timeline-sequence-hover.js +6 -67
- package/package.json +20 -19
- package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +0 -15
- package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +0 -31
- package/dist/esm/LazyModels-nh3c8h9p.mjs +0 -12
- package/dist/esm/LazyModels-rr5v8h5y.mjs +0 -12
- package/dist/esm/index-cw0pnpg5.mjs +0 -50
- package/dist/esm/index-k426ye99.mjs +0 -139
- package/dist/helpers/get-box-quads-polyfill-internals.d.ts +0 -82
- package/dist/helpers/get-box-quads-polyfill-internals.js +0 -2403
- package/dist/helpers/get-box-quads-ponyfill.d.ts +0 -10
- package/dist/helpers/get-box-quads-ponyfill.js +0 -23
- package/dist/icons/separation.js +0 -7
- /package/dist/esm/{resolve-composition-component-location-qrp05g62.mjs → resolve-composition-component-location-2hgf6g0a.mjs} +0 -0
|
@@ -6,6 +6,7 @@ const react_1 = require("react");
|
|
|
6
6
|
const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
|
|
7
7
|
const client_id_1 = require("../helpers/client-id");
|
|
8
8
|
const colors_1 = require("../helpers/colors");
|
|
9
|
+
const copy_text_1 = require("../helpers/copy-text");
|
|
9
10
|
const get_git_menu_item_1 = require("../helpers/get-git-menu-item");
|
|
10
11
|
const open_in_editor_1 = require("../helpers/open-in-editor");
|
|
11
12
|
const caret_1 = require("../icons/caret");
|
|
@@ -57,6 +58,16 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
|
|
|
57
58
|
(0, NotificationCenter_1.showNotification)(err.message, 2000);
|
|
58
59
|
}
|
|
59
60
|
}, [contextForAgents]);
|
|
61
|
+
const copyPath = (0, react_1.useCallback)(() => {
|
|
62
|
+
if (!(location === null || location === void 0 ? void 0 : location.source)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
(0, copy_text_1.copyText)(location.source)
|
|
66
|
+
.then(() => (0, NotificationCenter_1.showNotification)('Copied path', 1500))
|
|
67
|
+
.catch((err) => {
|
|
68
|
+
(0, NotificationCenter_1.showNotification)(`Could not copy path: ${err.message}`, 2000);
|
|
69
|
+
});
|
|
70
|
+
}, [location]);
|
|
60
71
|
const defaultAppName = defaultOpenInTarget === 'git-source'
|
|
61
72
|
? 'GitHub'
|
|
62
73
|
: (defaultEditorName !== null && defaultEditorName !== void 0 ? defaultEditorName : 'default editor');
|
|
@@ -89,6 +100,7 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
|
|
|
89
100
|
folder: locationType === 'folder',
|
|
90
101
|
gitSourceDisabled: location === null,
|
|
91
102
|
onConfigureApps: configureDefaultApps,
|
|
103
|
+
onCopyPath: locationType === 'folder' && (location === null || location === void 0 ? void 0 : location.source) ? copyPath : undefined,
|
|
92
104
|
onOpenInCodingAgent: (codingAgentId, codingAgentName) => {
|
|
93
105
|
openWithCodingAgent(codingAgentId, codingAgentName).catch(() => undefined);
|
|
94
106
|
},
|
|
@@ -138,6 +150,7 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locat
|
|
|
138
150
|
canConfigureApps,
|
|
139
151
|
canOpenInEditor,
|
|
140
152
|
configureDefaultApps,
|
|
153
|
+
copyPath,
|
|
141
154
|
defaultEditorId,
|
|
142
155
|
defaultOpenInTarget,
|
|
143
156
|
editorInfo,
|
|
@@ -78,11 +78,16 @@ const AlignmentControls = ({ track }) => {
|
|
|
78
78
|
const nodePath = track.nodePathInfo.sequenceSubscriptionKey;
|
|
79
79
|
const nodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath);
|
|
80
80
|
const firstKeyframedStatus = Object.values(nodePropStatuses !== null && nodePropStatuses !== void 0 ? nodePropStatuses : {}).find((status) => status.status === 'keyframed');
|
|
81
|
-
const sourceFrame =
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
const sourceFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
82
|
+
displayFrame: timelinePosition,
|
|
83
|
+
propStatus: firstKeyframedStatus !== null && firstKeyframedStatus !== void 0 ? firstKeyframedStatus : null,
|
|
84
|
+
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
85
|
+
propStatus: firstKeyframedStatus !== null && firstKeyframedStatus !== void 0 ? firstKeyframedStatus : null,
|
|
84
86
|
keyframeDisplayOffset: track.keyframeDisplayOffset,
|
|
85
|
-
|
|
87
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
88
|
+
}),
|
|
89
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
90
|
+
});
|
|
86
91
|
const dragOverrides = (_b = getDragOverrides(nodePath)) !== null && _b !== void 0 ? _b : {};
|
|
87
92
|
const activeSchema = (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
|
|
88
93
|
schema: track.sequence.controls.schema,
|
|
@@ -170,7 +175,16 @@ const AlignmentControls = ({ track }) => {
|
|
|
170
175
|
fileName: nodePath.absolutePath,
|
|
171
176
|
nodePath,
|
|
172
177
|
fieldKey: selected_outline_types_1.translateFieldKey,
|
|
173
|
-
sourceFrame,
|
|
178
|
+
sourceFrame: (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
179
|
+
displayFrame: timelinePosition,
|
|
180
|
+
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
181
|
+
propStatus,
|
|
182
|
+
keyframeDisplayOffset: track.keyframeDisplayOffset,
|
|
183
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
184
|
+
}),
|
|
185
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
186
|
+
propStatus,
|
|
187
|
+
}),
|
|
174
188
|
value: newValue,
|
|
175
189
|
schema: track.sequence.controls.schema,
|
|
176
190
|
setPropStatuses,
|
|
@@ -197,11 +211,16 @@ const AlignmentControls = ({ track }) => {
|
|
|
197
211
|
const renderNodePath = track.nodePathInfo.sequenceSubscriptionKey;
|
|
198
212
|
const renderNodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, renderNodePath);
|
|
199
213
|
const firstRenderKeyframedStatus = Object.values(renderNodePropStatuses !== null && renderNodePropStatuses !== void 0 ? renderNodePropStatuses : {}).find((status) => status.status === 'keyframed');
|
|
200
|
-
const renderSourceFrame =
|
|
201
|
-
|
|
202
|
-
|
|
214
|
+
const renderSourceFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
215
|
+
displayFrame: timelinePosition,
|
|
216
|
+
propStatus: firstRenderKeyframedStatus !== null && firstRenderKeyframedStatus !== void 0 ? firstRenderKeyframedStatus : null,
|
|
217
|
+
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
218
|
+
propStatus: firstRenderKeyframedStatus !== null && firstRenderKeyframedStatus !== void 0 ? firstRenderKeyframedStatus : null,
|
|
203
219
|
keyframeDisplayOffset: track.keyframeDisplayOffset,
|
|
204
|
-
|
|
220
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
221
|
+
}),
|
|
222
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
223
|
+
});
|
|
205
224
|
const renderDragOverrides = (_a = getDragOverrides(renderNodePath)) !== null && _a !== void 0 ? _a : {};
|
|
206
225
|
const renderActiveSchema = (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
|
|
207
226
|
schema: track.sequence.controls.schema,
|
|
@@ -113,6 +113,7 @@ const EasingInspector = ({ selection }) => {
|
|
|
113
113
|
}
|
|
114
114
|
return (0, easing_inspector_selection_1.getEasingSelectionFromCurrentKeyframes)({
|
|
115
115
|
keyframeDisplayOffset: track.keyframeDisplayOffset,
|
|
116
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
116
117
|
nodePathInfo: selection.nodePathInfo,
|
|
117
118
|
propStatus: easingUpdate.propStatus,
|
|
118
119
|
segmentIndex: easingUpdate.segmentIndex,
|
|
@@ -123,6 +124,7 @@ const EasingInspector = ({ selection }) => {
|
|
|
123
124
|
: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
124
125
|
propStatus: easingUpdate.propStatus,
|
|
125
126
|
keyframeDisplayOffset: track.keyframeDisplayOffset,
|
|
127
|
+
keyframePlaybackRate: track.keyframePlaybackRate,
|
|
126
128
|
});
|
|
127
129
|
const state = (0, react_1.useMemo)(() => {
|
|
128
130
|
if (initialEasing === null || currentEasingSelection === null) {
|
|
@@ -154,7 +156,8 @@ const EasingInspector = ({ selection }) => {
|
|
|
154
156
|
previewServerState.type !== 'connected') {
|
|
155
157
|
return;
|
|
156
158
|
}
|
|
157
|
-
const sourceFrame = timelinePosition - easingKeyframeDisplayOffset
|
|
159
|
+
const sourceFrame = (timelinePosition - easingKeyframeDisplayOffset) *
|
|
160
|
+
track.keyframePlaybackRate;
|
|
158
161
|
const value = remotion_1.Internals.getEffectiveVisualModeValue({
|
|
159
162
|
propStatus: easingUpdate.propStatus,
|
|
160
163
|
dragOverrideValue: easingDetails.dragOverrideValue,
|
|
@@ -208,7 +211,8 @@ const EasingInspector = ({ selection }) => {
|
|
|
208
211
|
const renderHeader = (0, react_1.useCallback)(() => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
209
212
|
jsx_runtime_1.jsx(common_1.InspectorBackAction, { disabled: parentSelection === null, onClick: onSelectParent, title: "Back to property", children: fieldLabel }), easingUpdate === null || track === null ? null : (jsx_runtime_1.jsx(KeyframeEasingNavigator_1.KeyframeEasingNavigator, { currentSelection: currentEasingSelection !== null && currentEasingSelection !== void 0 ? currentEasingSelection : selection, includeEasings: true, keyframes: easingUpdate.propStatus.keyframes.map((keyframe) => ({
|
|
210
213
|
...keyframe,
|
|
211
|
-
frame: keyframe.frame +
|
|
214
|
+
frame: keyframe.frame / track.keyframePlaybackRate +
|
|
215
|
+
easingKeyframeDisplayOffset,
|
|
212
216
|
})), nodePathInfo: selection.nodePathInfo }))] })), [
|
|
213
217
|
currentEasingSelection,
|
|
214
218
|
easingUpdate,
|
|
@@ -82,7 +82,7 @@ const ElementLibraryButton = () => {
|
|
|
82
82
|
segmentId: 'element-library',
|
|
83
83
|
selectedId: null,
|
|
84
84
|
style: elementLibraryDropdownSegmentStyle,
|
|
85
|
-
title: 'Choose an Element
|
|
85
|
+
title: 'Choose an Element Library to browse inside Studio.',
|
|
86
86
|
tooltipLabel: null,
|
|
87
87
|
type: 'menu',
|
|
88
88
|
values: [
|
|
@@ -98,7 +98,7 @@ const TimelineNavigatorItem = ({ extendLineLeft, extendLineRight, item, onSelect
|
|
|
98
98
|
};
|
|
99
99
|
const KeyframeEasingNavigator = ({ currentSelection, includeEasings, keyframes, nodePathInfo }) => {
|
|
100
100
|
const { isSelected, selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
101
|
-
const setFrame = remotion_1.Internals.
|
|
101
|
+
const setFrame = remotion_1.Internals.Timeline.useTimelineSeekFrame();
|
|
102
102
|
const videoConfig = (0, remotion_1.useVideoConfig)();
|
|
103
103
|
const items = (0, react_1.useMemo)(() => (0, keyframe_easing_navigator_items_1.getKeyframeEasingNavigatorItems)({
|
|
104
104
|
includeEasings,
|
|
@@ -12,9 +12,7 @@ const is_menu_item_1 = require("../Menu/is-menu-item");
|
|
|
12
12
|
const InputDragger_1 = require("../NewComposition/InputDragger");
|
|
13
13
|
const call_delete_keyframe_1 = require("../Timeline/call-delete-keyframe");
|
|
14
14
|
const call_move_keyframe_1 = require("../Timeline/call-move-keyframe");
|
|
15
|
-
const get_easing_selection_after_keyframe_delete_1 = require("../Timeline/get-easing-selection-after-keyframe-delete");
|
|
16
15
|
const get_timeline_keyframes_1 = require("../Timeline/get-timeline-keyframes");
|
|
17
|
-
const imperative_state_1 = require("../Timeline/imperative-state");
|
|
18
16
|
const parse_keyframe_field_from_node_path_1 = require("../Timeline/parse-keyframe-field-from-node-path");
|
|
19
17
|
const TimelineEffectPropItem_1 = require("../Timeline/TimelineEffectPropItem");
|
|
20
18
|
const TimelineSelection_1 = require("../Timeline/TimelineSelection");
|
|
@@ -80,7 +78,7 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
80
78
|
return null;
|
|
81
79
|
}
|
|
82
80
|
const nodePath = selection.nodePathInfo.sequenceSubscriptionKey;
|
|
83
|
-
const { keyframeDisplayOffset } = track;
|
|
81
|
+
const { keyframeDisplayOffset, keyframePlaybackRate } = track;
|
|
84
82
|
if (keyframeField.type === 'sequence') {
|
|
85
83
|
const sequenceFields = (0, timeline_layout_1.getFieldsToShow)({
|
|
86
84
|
schema: track.sequence.controls.schema,
|
|
@@ -100,18 +98,25 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
100
98
|
field: sequenceField,
|
|
101
99
|
fieldLabel: (_d = sequenceField.description) !== null && _d !== void 0 ? _d : sequenceField.key,
|
|
102
100
|
fileName: nodePath.absolutePath,
|
|
101
|
+
keyframePlaybackRate,
|
|
103
102
|
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
104
103
|
propStatus: sequencePropStatus,
|
|
105
104
|
keyframeDisplayOffset,
|
|
105
|
+
keyframePlaybackRate,
|
|
106
106
|
}),
|
|
107
107
|
nodePath,
|
|
108
108
|
propStatus: sequencePropStatus,
|
|
109
109
|
schema: track.sequence.controls.schema,
|
|
110
|
-
sourceFrame:
|
|
111
|
-
|
|
110
|
+
sourceFrame: (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
111
|
+
displayFrame: selection.frame,
|
|
112
|
+
propStatus: sequencePropStatus,
|
|
113
|
+
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
112
114
|
propStatus: sequencePropStatus,
|
|
113
115
|
keyframeDisplayOffset,
|
|
116
|
+
keyframePlaybackRate,
|
|
114
117
|
}),
|
|
118
|
+
keyframePlaybackRate,
|
|
119
|
+
}),
|
|
115
120
|
};
|
|
116
121
|
}
|
|
117
122
|
const effect = track.sequence.effects[keyframeField.effectIndex];
|
|
@@ -143,18 +148,25 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
143
148
|
field: effectField,
|
|
144
149
|
fieldLabel: (_g = effectField.description) !== null && _g !== void 0 ? _g : effectField.key,
|
|
145
150
|
fileName: nodePath.absolutePath,
|
|
151
|
+
keyframePlaybackRate,
|
|
146
152
|
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
147
153
|
propStatus: effectPropStatus,
|
|
148
154
|
keyframeDisplayOffset,
|
|
155
|
+
keyframePlaybackRate,
|
|
149
156
|
}),
|
|
150
157
|
nodePath,
|
|
151
158
|
propStatus: effectPropStatus,
|
|
152
159
|
schema: effect.schema,
|
|
153
|
-
sourceFrame:
|
|
154
|
-
|
|
160
|
+
sourceFrame: (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
161
|
+
displayFrame: selection.frame,
|
|
162
|
+
propStatus: effectPropStatus,
|
|
163
|
+
keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
155
164
|
propStatus: effectPropStatus,
|
|
156
165
|
keyframeDisplayOffset,
|
|
166
|
+
keyframePlaybackRate,
|
|
157
167
|
}),
|
|
168
|
+
keyframePlaybackRate,
|
|
169
|
+
}),
|
|
158
170
|
validatedLocation: {
|
|
159
171
|
source: nodePath.absolutePath,
|
|
160
172
|
line: 1,
|
|
@@ -188,9 +200,11 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
188
200
|
if (details === null) {
|
|
189
201
|
return;
|
|
190
202
|
}
|
|
191
|
-
const toFrame = (0,
|
|
203
|
+
const toFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
192
204
|
displayFrame,
|
|
193
205
|
keyframeDisplayOffset: details.keyframeDisplayOffset,
|
|
206
|
+
keyframePlaybackRate: details.keyframePlaybackRate,
|
|
207
|
+
propStatus: details.propStatus,
|
|
194
208
|
});
|
|
195
209
|
if (displayFrame === selection.frame || toFrame === details.sourceFrame) {
|
|
196
210
|
clearFrameDragOverride(details);
|
|
@@ -227,9 +241,11 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
227
241
|
durationInFrames: videoConfig.durationInFrames,
|
|
228
242
|
frame: value,
|
|
229
243
|
});
|
|
230
|
-
const toFrame = (0,
|
|
244
|
+
const toFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
|
|
231
245
|
displayFrame,
|
|
232
246
|
keyframeDisplayOffset: details.keyframeDisplayOffset,
|
|
247
|
+
keyframePlaybackRate: details.keyframePlaybackRate,
|
|
248
|
+
propStatus: details.propStatus,
|
|
233
249
|
});
|
|
234
250
|
setDraftFrame(displayFrame);
|
|
235
251
|
clearFrameDragOverride(details);
|
|
@@ -289,19 +305,7 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
289
305
|
if (details === null || previewServerState.type !== 'connected') {
|
|
290
306
|
return;
|
|
291
307
|
}
|
|
292
|
-
|
|
293
|
-
? (0, get_easing_selection_after_keyframe_delete_1.getEasingSelectionAfterKeyframeDelete)({
|
|
294
|
-
deletedSourceFrames: [details.sourceFrame],
|
|
295
|
-
keyframeDisplayOffset: details.keyframeDisplayOffset,
|
|
296
|
-
nodePathInfo: selection.nodePathInfo,
|
|
297
|
-
propStatus: details.propStatus,
|
|
298
|
-
timelinePosition: (0, imperative_state_1.getCurrentFrame)(),
|
|
299
|
-
})
|
|
300
|
-
: null;
|
|
301
|
-
if (easingSelection !== null) {
|
|
302
|
-
selectItems([easingSelection], { reveal: true });
|
|
303
|
-
}
|
|
304
|
-
else if (parentSelection !== null) {
|
|
308
|
+
if (parentSelection !== null) {
|
|
305
309
|
selectItems([parentSelection], { reveal: true });
|
|
306
310
|
}
|
|
307
311
|
if (details.type === 'sequence') {
|
|
@@ -331,7 +335,6 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
331
335
|
parentSelection,
|
|
332
336
|
previewServerState,
|
|
333
337
|
selectItems,
|
|
334
|
-
selection.nodePathInfo,
|
|
335
338
|
setPropStatuses,
|
|
336
339
|
]);
|
|
337
340
|
if (details === null || track === null) {
|
|
@@ -340,7 +343,8 @@ const KeyframeInspector = ({ selection }) => {
|
|
|
340
343
|
return (jsx_runtime_1.jsxs("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: [
|
|
341
344
|
jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorSections, { track: track }), jsx_runtime_1.jsx(common_1.InspectorBackAction, { disabled: parentSelection === null, onClick: onSelectParent, title: "Back to property", children: details.fieldLabel }), jsx_runtime_1.jsx(KeyframeEasingNavigator_1.KeyframeEasingNavigator, { currentSelection: selection, includeEasings: (0, update_selected_easing_1.canEditEasingForInterpolationFunction)(details.propStatus.interpolationFunction), keyframes: details.propStatus.keyframes.map((keyframe) => ({
|
|
342
345
|
...keyframe,
|
|
343
|
-
frame: keyframe.frame
|
|
346
|
+
frame: keyframe.frame / details.keyframePlaybackRate +
|
|
347
|
+
details.keyframeDisplayOffset,
|
|
344
348
|
})), nodePathInfo: selection.nodePathInfo }), jsx_runtime_1.jsxs("div", { style: styles_1.detailsWithInlineAction, children: [
|
|
345
349
|
jsx_runtime_1.jsxs("div", { style: styles_1.detailsBeforeInlineAction, children: [
|
|
346
350
|
jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: "Frame", children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: draftFrame, status: "ok", onValueChange: onFrameChange, onValueChangeEnd: onFrameChangeEnd, onTextChange: () => undefined, min: 0, max: Math.max(0, videoConfig.durationInFrames - 1), step: 1, formatter: (value) => String(Math.round(Number(value))), rightAlign: true, small: true }) }), jsx_runtime_1.jsx("div", { style: styles_1.keyframeEditorRow, children: jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: details.fieldLabel, children: jsx_runtime_1.jsx("div", { style: styles_1.keyframeEditorValue, children: details.type === 'sequence' ? (jsx_runtime_1.jsx(TimelineSequencePropItem_1.TimelineSequenceKeyframedValue, { field: details.field, fileName: details.fileName, nodePath: details.nodePath, schema: details.schema, propStatus: details.propStatus, sourceFrame: details.sourceFrame })) : (jsx_runtime_1.jsx(TimelineEffectPropItem_1.TimelineEffectPropValue, { field: details.field, nodePath: details.nodePath, validatedLocation: details.validatedLocation, sourceFrame: details.sourceFrame, runtimeValueStore: null })) }) }) })
|
|
@@ -63,7 +63,7 @@ const NumericAxis = ({ field, values, axis, onPreview, onSave, onClear }) => {
|
|
|
63
63
|
}
|
|
64
64
|
}, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : coordinates[0], "aria-label": axis === null
|
|
65
65
|
? ((_d = field.description) !== null && _d !== void 0 ? _d : field.key)
|
|
66
|
-
: `Offset ${['X', 'Y', 'Z'][axis]}`, title: "Type to set all values; drag to adjust each value", status: "ok", small: true, rightAlign: false, min: min, max: max, step: step, snapToStep: axis === null, dragDecimalPlaces: decimalPlaces, dragSensitivity: axis === null ? 1 : 3, buttonStyle: { paddingLeft: 0 }, style: { width: 70 }, formatter: (value) => mixed && dragValue === null
|
|
66
|
+
: `Offset ${['X', 'Y', 'Z'][axis]}`, title: "Type to set all values; drag to adjust each value", status: "ok", small: true, rightAlign: false, min: min, max: max, step: step, allowStepMismatch: true, integerOnly: schema.type === 'number' && schema.integer === true, snapToStep: axis === null, dragDecimalPlaces: decimalPlaces, dragSensitivity: axis === null ? 1 : 3, buttonStyle: { paddingLeft: 0 }, style: { width: 70 }, formatter: (value) => mixed && dragValue === null
|
|
67
67
|
? 'Mixed'
|
|
68
68
|
: (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({ fieldSchema: schema, value }), onTextChange: noop_1.noop, onValueChange: (value, source) => {
|
|
69
69
|
var _a;
|
|
@@ -6,7 +6,9 @@ type SequenceInspectorSourceLocation = {
|
|
|
6
6
|
readonly openFileLocation: () => void;
|
|
7
7
|
readonly validatedLocation: CodePosition | null;
|
|
8
8
|
};
|
|
9
|
-
export declare const useSequenceInspectorSourceLocation: (sequence: import("remotion").TSequence
|
|
9
|
+
export declare const useSequenceInspectorSourceLocation: (sequence: import("remotion").TSequence & {
|
|
10
|
+
loopDisplay: import("@remotion/canvas").TimelineLoopDisplay | undefined;
|
|
11
|
+
}) => SequenceInspectorSourceLocation;
|
|
10
12
|
export declare const SequenceInspectorHeader: React.FC<{
|
|
11
13
|
readonly sourceLocation: SequenceInspectorSourceLocation;
|
|
12
14
|
readonly track: TimelineTrackData;
|
|
@@ -8,6 +8,7 @@ const client_id_1 = require("../../helpers/client-id");
|
|
|
8
8
|
const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
|
|
9
9
|
const use_media_metadata_1 = require("../../helpers/use-media-metadata");
|
|
10
10
|
const audio_1 = require("../../icons/audio");
|
|
11
|
+
const background_removal_1 = require("../../icons/background-removal");
|
|
11
12
|
const duplicate_1 = require("../../icons/duplicate");
|
|
12
13
|
const scissors_1 = require("../../icons/scissors");
|
|
13
14
|
const snowflake_1 = require("../../icons/snowflake");
|
|
@@ -30,6 +31,7 @@ const CollapsibleInspectorSection_1 = require("./CollapsibleInspectorSection");
|
|
|
30
31
|
const common_1 = require("./common");
|
|
31
32
|
const ConnectedCompositionsSection_1 = require("./ConnectedCompositionsSection");
|
|
32
33
|
const SequenceInspectorHeader_1 = require("./SequenceInspectorHeader");
|
|
34
|
+
const SequenceWrapAction_1 = require("./SequenceWrapAction");
|
|
33
35
|
const styles_1 = require("./styles");
|
|
34
36
|
const use_track_for_selection_1 = require("./use-track-for-selection");
|
|
35
37
|
const actionIconStyle = {
|
|
@@ -105,6 +107,11 @@ const SequenceSourceQuickActions = ({ selection, track, validatedSource }) => {
|
|
|
105
107
|
: selection.nodePathInfo.numberOfSequencesWithThisNodePath > 1
|
|
106
108
|
? 'Programmatically duplicated media cannot be transcribed from source'
|
|
107
109
|
: undefined;
|
|
110
|
+
const videoMattingDisabledReason = sourceActionsDisabled
|
|
111
|
+
? 'Studio is read-only'
|
|
112
|
+
: selection.nodePathInfo.numberOfSequencesWithThisNodePath > 1
|
|
113
|
+
? 'Programmatically duplicated videos cannot have their background removed from source'
|
|
114
|
+
: undefined;
|
|
108
115
|
const onGenerateCaptions = (0, react_1.useCallback)(() => {
|
|
109
116
|
if (transcriptionDisabledReason !== undefined || mediaSequence === null) {
|
|
110
117
|
return;
|
|
@@ -130,6 +137,27 @@ const SequenceSourceQuickActions = ({ selection, track, validatedSource }) => {
|
|
|
130
137
|
mediaSequence,
|
|
131
138
|
transcriptionDisabledReason,
|
|
132
139
|
]);
|
|
140
|
+
const onRemoveBackground = (0, react_1.useCallback)(() => {
|
|
141
|
+
if (videoMattingDisabledReason !== undefined ||
|
|
142
|
+
track.sequence.type !== 'video') {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const nodePath = selection.nodePathInfo.sequenceSubscriptionKey;
|
|
146
|
+
setSelectedModal({
|
|
147
|
+
type: 'video-matting',
|
|
148
|
+
src: track.sequence.src,
|
|
149
|
+
displayName: (0, public_output_name_1.getMediaFileName)(track.sequence.src, track.sequence.displayName),
|
|
150
|
+
target: {
|
|
151
|
+
fileName: nodePath.absolutePath,
|
|
152
|
+
nodePath,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}, [
|
|
156
|
+
selection.nodePathInfo,
|
|
157
|
+
setSelectedModal,
|
|
158
|
+
track.sequence,
|
|
159
|
+
videoMattingDisabledReason,
|
|
160
|
+
]);
|
|
133
161
|
const onDuplicate = (0, react_1.useCallback)(() => {
|
|
134
162
|
if (sourceActionsDisabled) {
|
|
135
163
|
return;
|
|
@@ -165,7 +193,7 @@ const SequenceSourceQuickActions = ({ selection, track, validatedSource }) => {
|
|
|
165
193
|
(0, NotificationCenter_1.showNotification)(err.message, 4000);
|
|
166
194
|
});
|
|
167
195
|
}, [selection.nodePathInfo, splitVideoFromAudioDisabledReason]);
|
|
168
|
-
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [(freezeFrameMenuItem === null || freezeFrameMenuItem === void 0 ? void 0 : freezeFrameMenuItem.type) === 'item' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: Boolean(freezeFrameMenuItem.disabled), onClick: () => freezeFrameMenuItem.onClick(freezeFrameMenuItem.id, null), renderIcon: (color) => (jsx_runtime_1.jsx(snowflake_1.SnowflakeIcon, { style: largeActionIconStyle, color: color })), children: freezeFrameMenuItem.label })) : null, track.sequence.type === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: splitVideoFromAudioDisabledReason !== undefined, onClick: onSplitVideoFromAudio, title: splitVideoFromAudioDisabledReason, renderIcon: (color) => (jsx_runtime_1.jsx(audio_1.AudioIcon, { style: actionIconStyle, color: color })), children: "Split video from audio" })) : null, mediaSequence !== null && (mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.hasAudioTrack) !== false ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: transcriptionDisabledReason !== undefined, onClick: onGenerateCaptions, title: transcriptionDisabledReason, renderIcon: (color) => (jsx_runtime_1.jsx(transcription_1.TranscriptionIcon, { style: actionIconStyle, color: color })), children: "Generate captions" })) : null, jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: sourceActionsDisabled, onClick: onDuplicate, renderIcon: (color) => (jsx_runtime_1.jsx(duplicate_1.DuplicateIcon, { style: largeActionIconStyle, color: color })), children: "Duplicate" }), jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: sourceActionsDisabled, onClick: onDelete, renderIcon: (color) => (jsx_runtime_1.jsx(trash_1.TrashIcon, { style: actionIconStyle, color: color })), children: "Delete" })] }));
|
|
196
|
+
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [(freezeFrameMenuItem === null || freezeFrameMenuItem === void 0 ? void 0 : freezeFrameMenuItem.type) === 'item' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: Boolean(freezeFrameMenuItem.disabled), onClick: () => freezeFrameMenuItem.onClick(freezeFrameMenuItem.id, null), renderIcon: (color) => (jsx_runtime_1.jsx(snowflake_1.SnowflakeIcon, { style: largeActionIconStyle, color: color })), children: freezeFrameMenuItem.label })) : null, track.sequence.type === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: videoMattingDisabledReason !== undefined, onClick: onRemoveBackground, title: videoMattingDisabledReason, renderIcon: (color) => (jsx_runtime_1.jsx(background_removal_1.BackgroundRemovalIcon, { style: actionIconStyle, color: color })), children: "Remove background" })) : null, track.sequence.type === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: splitVideoFromAudioDisabledReason !== undefined, onClick: onSplitVideoFromAudio, title: splitVideoFromAudioDisabledReason, renderIcon: (color) => (jsx_runtime_1.jsx(audio_1.AudioIcon, { style: actionIconStyle, color: color })), children: "Split video from audio" })) : null, mediaSequence !== null && (mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.hasAudioTrack) !== false ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: transcriptionDisabledReason !== undefined, onClick: onGenerateCaptions, title: transcriptionDisabledReason, renderIcon: (color) => (jsx_runtime_1.jsx(transcription_1.TranscriptionIcon, { style: actionIconStyle, color: color })), children: "Generate captions" })) : null, jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: sourceActionsDisabled, onClick: onDuplicate, renderIcon: (color) => (jsx_runtime_1.jsx(duplicate_1.DuplicateIcon, { style: largeActionIconStyle, color: color })), children: "Duplicate" }), jsx_runtime_1.jsx(SequenceWrapAction_1.SequenceWrapAction, { nodePathInfo: selection.nodePathInfo, sequence: track.sequence, sourceActionsDisabled: sourceActionsDisabled }), jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: sourceActionsDisabled, onClick: onDelete, renderIcon: (color) => (jsx_runtime_1.jsx(trash_1.TrashIcon, { style: actionIconStyle, color: color })), children: "Delete" })] }));
|
|
169
197
|
};
|
|
170
198
|
const SequenceExpandedInspector = ({ track, readOnlyStudio }) => {
|
|
171
199
|
const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
|
|
@@ -210,7 +238,7 @@ const SequenceExpandedInspector = ({ track, readOnlyStudio }) => {
|
|
|
210
238
|
return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Sequence inspector unavailable" });
|
|
211
239
|
}
|
|
212
240
|
return (jsx_runtime_1.jsxs("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, onPointerDown: selectSequenceOnInspectorPointerDown, children: [
|
|
213
|
-
jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }, stackKey !== null && stackKey !== void 0 ? stackKey : track.sequence.id), jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorDuplicationSection, { track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsx(ConnectedCompositionsSection_1.ConnectedCompositionsSection, { connectedCompositions: connectedCompositions })) : null, validatedLocation ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx(InspectorSequenceSection_1.InspectorSequenceSection, { sequence: track.sequence, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, renderTransformControls: () => jsx_runtime_1.jsx(AlignmentControls_1.AlignmentControls, { track: track }) }), jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "sequence-actions", children: jsx_runtime_1.jsxs(common_1.InspectorQuickActionsSection, { children: [
|
|
241
|
+
jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }, stackKey !== null && stackKey !== void 0 ? stackKey : track.sequence.id), jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorDuplicationSection, { track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsx(ConnectedCompositionsSection_1.ConnectedCompositionsSection, { connectedCompositions: connectedCompositions })) : null, validatedLocation ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx(InspectorSequenceSection_1.InspectorSequenceSection, { sequence: track.sequence, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, keyframePlaybackRate: track.keyframePlaybackRate, renderTransformControls: () => jsx_runtime_1.jsx(AlignmentControls_1.AlignmentControls, { track: track }) }), jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "sequence-actions", children: jsx_runtime_1.jsxs(common_1.InspectorQuickActionsSection, { children: [
|
|
214
242
|
jsx_runtime_1.jsx(SplitSequenceQuickAction, { selection: sequenceSelection, track: track }), jsx_runtime_1.jsx(SequenceSourceQuickActions, { selection: sequenceSelection, track: track, validatedSource: validatedLocation.source })
|
|
215
243
|
] }) })
|
|
216
244
|
] })) : (jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Source controls unavailable" }))] }));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
|
|
3
|
+
import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
|
|
4
|
+
export declare const SequenceWrapAction: React.FC<{
|
|
5
|
+
readonly nodePathInfo: SequenceNodePathInfo;
|
|
6
|
+
readonly sequence: TimelineTrackData['sequence'];
|
|
7
|
+
readonly sourceActionsDisabled: boolean;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SequenceWrapAction = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const remotion_1 = require("remotion");
|
|
7
|
+
const colors_1 = require("../../helpers/colors");
|
|
8
|
+
const caret_1 = require("../../icons/caret");
|
|
9
|
+
const wrap_1 = require("../../icons/wrap");
|
|
10
|
+
const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
|
|
11
|
+
const NotificationCenter_1 = require("../Notifications/NotificationCenter");
|
|
12
|
+
const SegmentedButton_1 = require("../SegmentedButton");
|
|
13
|
+
const wrap_jsx_node_api_1 = require("../wrap-jsx-node-api");
|
|
14
|
+
const wrapperNames = ['AbsoluteFill', 'Sequence', 'HtmlInCanvas'];
|
|
15
|
+
const buttonStyle = {
|
|
16
|
+
borderRadius: 4,
|
|
17
|
+
height: 28,
|
|
18
|
+
margin: '0 4px',
|
|
19
|
+
width: 'calc(100% - 8px)',
|
|
20
|
+
};
|
|
21
|
+
const segmentStyle = {
|
|
22
|
+
fontSize: 13,
|
|
23
|
+
gap: 8,
|
|
24
|
+
justifyContent: 'flex-start',
|
|
25
|
+
padding: `0 ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING - 4}px`,
|
|
26
|
+
width: '100%',
|
|
27
|
+
};
|
|
28
|
+
const iconStyle = { height: 22, width: 22 };
|
|
29
|
+
const iconContainerStyle = {
|
|
30
|
+
flexShrink: 0,
|
|
31
|
+
height: 22,
|
|
32
|
+
marginLeft: -2,
|
|
33
|
+
marginRight: -2,
|
|
34
|
+
width: 22,
|
|
35
|
+
};
|
|
36
|
+
const labelStyle = {
|
|
37
|
+
flex: 1,
|
|
38
|
+
fontFamily: 'sans-serif',
|
|
39
|
+
fontSize: 13,
|
|
40
|
+
lineHeight: '18px',
|
|
41
|
+
minWidth: 0,
|
|
42
|
+
overflow: 'hidden',
|
|
43
|
+
textAlign: 'left',
|
|
44
|
+
textOverflow: 'ellipsis',
|
|
45
|
+
userSelect: 'none',
|
|
46
|
+
WebkitUserSelect: 'none',
|
|
47
|
+
whiteSpace: 'nowrap',
|
|
48
|
+
};
|
|
49
|
+
const caretStyle = {
|
|
50
|
+
display: 'flex',
|
|
51
|
+
flexShrink: 0,
|
|
52
|
+
height: 12,
|
|
53
|
+
width: 12,
|
|
54
|
+
};
|
|
55
|
+
const SequenceWrapAction = ({ nodePathInfo, sequence, sourceActionsDisabled }) => {
|
|
56
|
+
const { width, height } = (0, remotion_1.useVideoConfig)();
|
|
57
|
+
const nodePathKey = JSON.stringify(nodePathInfo.sequenceSubscriptionKey);
|
|
58
|
+
const [eligibility, setEligibility] = (0, react_1.useState)(null);
|
|
59
|
+
const [busy, setBusy] = (0, react_1.useState)(false);
|
|
60
|
+
(0, react_1.useEffect)(() => {
|
|
61
|
+
setEligibility(null);
|
|
62
|
+
if (sourceActionsDisabled) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let cancelled = false;
|
|
66
|
+
const nodePath = JSON.parse(nodePathKey);
|
|
67
|
+
(0, wrap_jsx_node_api_1.wrapJsxNode)({
|
|
68
|
+
fileName: nodePath.absolutePath,
|
|
69
|
+
nodePath: nodePath.nodePath,
|
|
70
|
+
wrapper: null,
|
|
71
|
+
width: null,
|
|
72
|
+
height: null,
|
|
73
|
+
})
|
|
74
|
+
.then((result) => {
|
|
75
|
+
if (!cancelled && result.success) {
|
|
76
|
+
setEligibility({
|
|
77
|
+
canWrap: result.canWrap,
|
|
78
|
+
canWrapHtmlInCanvas: result.canWrapHtmlInCanvas,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
.catch(() => undefined);
|
|
83
|
+
return () => {
|
|
84
|
+
cancelled = true;
|
|
85
|
+
};
|
|
86
|
+
}, [nodePathKey, sequence, sourceActionsDisabled]);
|
|
87
|
+
const onWrap = (0, react_1.useCallback)((wrapper) => {
|
|
88
|
+
if (busy || sourceActionsDisabled || !(eligibility === null || eligibility === void 0 ? void 0 : eligibility.canWrap)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
setBusy(true);
|
|
92
|
+
const nodePath = JSON.parse(nodePathKey);
|
|
93
|
+
(0, wrap_jsx_node_api_1.wrapJsxNode)({
|
|
94
|
+
fileName: nodePath.absolutePath,
|
|
95
|
+
nodePath: nodePath.nodePath,
|
|
96
|
+
wrapper,
|
|
97
|
+
width,
|
|
98
|
+
height,
|
|
99
|
+
})
|
|
100
|
+
.then((result) => {
|
|
101
|
+
if (!result.success) {
|
|
102
|
+
(0, NotificationCenter_1.showNotification)(result.reason, 4000);
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
.catch((error) => {
|
|
106
|
+
(0, NotificationCenter_1.showNotification)(error.message, 4000);
|
|
107
|
+
})
|
|
108
|
+
.finally(() => setBusy(false));
|
|
109
|
+
}, [busy, eligibility, height, nodePathKey, sourceActionsDisabled, width]);
|
|
110
|
+
const values = (0, react_1.useMemo)(() => wrapperNames.map((wrapper) => ({
|
|
111
|
+
type: 'item',
|
|
112
|
+
id: wrapper,
|
|
113
|
+
label: `<${wrapper}>`,
|
|
114
|
+
value: wrapper,
|
|
115
|
+
onClick: () => onWrap(wrapper),
|
|
116
|
+
keyHint: null,
|
|
117
|
+
leftItem: null,
|
|
118
|
+
subMenu: null,
|
|
119
|
+
quickSwitcherLabel: null,
|
|
120
|
+
disabled: busy ||
|
|
121
|
+
(wrapper === 'HtmlInCanvas' &&
|
|
122
|
+
(!(eligibility === null || eligibility === void 0 ? void 0 : eligibility.canWrapHtmlInCanvas) || !(0, remotion_1.isHtmlInCanvasSupported)())),
|
|
123
|
+
})), [busy, eligibility, onWrap]);
|
|
124
|
+
const segments = (0, react_1.useMemo)(() => [
|
|
125
|
+
{
|
|
126
|
+
ariaLabel: 'Wrap',
|
|
127
|
+
buttonId: null,
|
|
128
|
+
disabled: busy,
|
|
129
|
+
idleColor: colors_1.LIGHT_TEXT,
|
|
130
|
+
leaveLeftSpace: false,
|
|
131
|
+
onOpenChange: null,
|
|
132
|
+
renderContent: (color) => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
133
|
+
jsx_runtime_1.jsx("span", { style: iconContainerStyle, children: jsx_runtime_1.jsx(wrap_1.WrapIcon, { color: color, style: iconStyle }) }), jsx_runtime_1.jsx("span", { style: labelStyle, children: "Wrap" }), jsx_runtime_1.jsx("span", { style: caretStyle, children: jsx_runtime_1.jsx(caret_1.CaretDown, { color: color }) })
|
|
134
|
+
] })),
|
|
135
|
+
segmentId: 'wrap',
|
|
136
|
+
selectedId: null,
|
|
137
|
+
style: segmentStyle,
|
|
138
|
+
title: nodePathInfo.numberOfSequencesWithThisNodePath > 1
|
|
139
|
+
? `Wrap all ${nodePathInfo.numberOfSequencesWithThisNodePath} instances of this JSX element`
|
|
140
|
+
: 'Wrap this JSX element',
|
|
141
|
+
tooltipLabel: null,
|
|
142
|
+
type: 'menu',
|
|
143
|
+
values,
|
|
144
|
+
},
|
|
145
|
+
], [busy, nodePathInfo.numberOfSequencesWithThisNodePath, values]);
|
|
146
|
+
if (!(eligibility === null || eligibility === void 0 ? void 0 : eligibility.canWrap) || sourceActionsDisabled) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return (jsx_runtime_1.jsx(SegmentedButton_1.SegmentedButton, { segments: segments, style: buttonStyle, title: null }));
|
|
150
|
+
};
|
|
151
|
+
exports.SequenceWrapAction = SequenceWrapAction;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { CanUpdateSequencePropStatusKeyframed } from 'remotion';
|
|
2
2
|
import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
|
|
3
|
-
export declare const getEasingSelectionFromCurrentKeyframes: ({ keyframeDisplayOffset, nodePathInfo, propStatus, segmentIndex, }: {
|
|
3
|
+
export declare const getEasingSelectionFromCurrentKeyframes: ({ keyframeDisplayOffset, keyframePlaybackRate, nodePathInfo, propStatus, segmentIndex, }: {
|
|
4
4
|
readonly keyframeDisplayOffset: number;
|
|
5
|
+
readonly keyframePlaybackRate: number;
|
|
5
6
|
readonly nodePathInfo: SequenceNodePathInfo;
|
|
6
7
|
readonly propStatus: CanUpdateSequencePropStatusKeyframed;
|
|
7
8
|
readonly segmentIndex: number;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getEasingSelectionFromCurrentKeyframes = void 0;
|
|
4
4
|
const get_timeline_keyframes_1 = require("../Timeline/get-timeline-keyframes");
|
|
5
|
-
const getEasingSelectionFromCurrentKeyframes = ({ keyframeDisplayOffset, nodePathInfo, propStatus, segmentIndex, }) => {
|
|
5
|
+
const getEasingSelectionFromCurrentKeyframes = ({ keyframeDisplayOffset, keyframePlaybackRate, nodePathInfo, propStatus, segmentIndex, }) => {
|
|
6
6
|
const fromKeyframe = propStatus.keyframes[segmentIndex];
|
|
7
7
|
const toKeyframe = propStatus.keyframes[segmentIndex + 1];
|
|
8
8
|
if (!fromKeyframe || !toKeyframe) {
|
|
@@ -11,12 +11,13 @@ const getEasingSelectionFromCurrentKeyframes = ({ keyframeDisplayOffset, nodePat
|
|
|
11
11
|
const resolvedKeyframeDisplayOffset = (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
|
|
12
12
|
propStatus,
|
|
13
13
|
keyframeDisplayOffset,
|
|
14
|
+
keyframePlaybackRate,
|
|
14
15
|
});
|
|
15
16
|
return {
|
|
16
17
|
type: 'easing',
|
|
17
18
|
nodePathInfo,
|
|
18
|
-
fromFrame: fromKeyframe.frame + resolvedKeyframeDisplayOffset,
|
|
19
|
-
toFrame: toKeyframe.frame + resolvedKeyframeDisplayOffset,
|
|
19
|
+
fromFrame: fromKeyframe.frame / keyframePlaybackRate + resolvedKeyframeDisplayOffset,
|
|
20
|
+
toFrame: toKeyframe.frame / keyframePlaybackRate + resolvedKeyframeDisplayOffset,
|
|
20
21
|
segmentIndex,
|
|
21
22
|
};
|
|
22
23
|
};
|
|
@@ -2,7 +2,8 @@ export declare const clampInspectorKeyframeDisplayFrame: ({ durationInFrames, fr
|
|
|
2
2
|
readonly durationInFrames: number;
|
|
3
3
|
readonly frame: number;
|
|
4
4
|
}) => number;
|
|
5
|
-
export declare const getInspectorKeyframeSourceFrame: ({ displayFrame, keyframeDisplayOffset, }: {
|
|
5
|
+
export declare const getInspectorKeyframeSourceFrame: ({ displayFrame, keyframeDisplayOffset, keyframePlaybackRate, }: {
|
|
6
6
|
readonly displayFrame: number;
|
|
7
7
|
readonly keyframeDisplayOffset: number;
|
|
8
|
+
readonly keyframePlaybackRate: number;
|
|
8
9
|
}) => number;
|
|
@@ -8,7 +8,7 @@ const clampInspectorKeyframeDisplayFrame = ({ durationInFrames, frame, }) => {
|
|
|
8
8
|
return Math.min(Math.max(Math.round(frame), 0), durationInFrames - 1);
|
|
9
9
|
};
|
|
10
10
|
exports.clampInspectorKeyframeDisplayFrame = clampInspectorKeyframeDisplayFrame;
|
|
11
|
-
const getInspectorKeyframeSourceFrame = ({ displayFrame, keyframeDisplayOffset, }) => {
|
|
12
|
-
return displayFrame - keyframeDisplayOffset;
|
|
11
|
+
const getInspectorKeyframeSourceFrame = ({ displayFrame, keyframeDisplayOffset, keyframePlaybackRate, }) => {
|
|
12
|
+
return (displayFrame - keyframeDisplayOffset) * keyframePlaybackRate;
|
|
13
13
|
};
|
|
14
14
|
exports.getInspectorKeyframeSourceFrame = getInspectorKeyframeSourceFrame;
|