@remotion/studio 4.0.506 → 4.0.507

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.
Files changed (119) hide show
  1. package/dist/api/copy-render-output-to-asset.d.ts +4 -0
  2. package/dist/api/copy-render-output-to-asset.js +11 -0
  3. package/dist/components/AssetSelector.js +19 -4
  4. package/dist/components/AssetSelectorItem.js +2 -2
  5. package/dist/components/CodingAgentIcon.d.ts +4 -0
  6. package/dist/components/CodingAgentIcon.js +17 -0
  7. package/dist/components/ConfigureDefaultEditorModal.d.ts +1 -3
  8. package/dist/components/ConfigureDefaultEditorModal.js +67 -77
  9. package/dist/components/ConfigureLicenseModal.d.ts +1 -4
  10. package/dist/components/ConfigureLicenseModal.js +89 -81
  11. package/dist/components/ContextMenu.js +10 -8
  12. package/dist/components/EditorContexts.js +6 -5
  13. package/dist/components/ExpandedTracksProvider.js +10 -53
  14. package/dist/components/InspectorLocationCopy.js +8 -8
  15. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  16. package/dist/components/InspectorOpenInEditor.js +39 -49
  17. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -0
  18. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +22 -4
  19. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -1
  20. package/dist/components/Menu/MenuSectionHeader.d.ts +4 -0
  21. package/dist/components/Menu/MenuSectionHeader.js +20 -0
  22. package/dist/components/Menu/SubMenu.js +13 -2
  23. package/dist/components/Menu/menu-tree-context.d.ts +3 -0
  24. package/dist/components/Menu/menu-tree-context.js +13 -0
  25. package/dist/components/NewComposition/ComboBox.d.ts +6 -1
  26. package/dist/components/NewComposition/MenuContent.js +27 -19
  27. package/dist/components/NewComposition/menu-typeahead.js +2 -2
  28. package/dist/components/Preview.js +29 -4
  29. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.d.ts +1 -0
  30. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +2 -2
  31. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +3 -3
  32. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +1 -1
  33. package/dist/components/RenderModal/ServerRenderModal.js +4 -0
  34. package/dist/components/RenderQueue/RenderQueueItem.js +8 -2
  35. package/dist/components/RenderQueue/actions.d.ts +4 -2
  36. package/dist/components/RenderQueue/actions.js +4 -2
  37. package/dist/components/RenderQueue/index.js +3 -4
  38. package/dist/components/RenderQueue/use-render-output-file-drag.d.ts +8 -0
  39. package/dist/components/RenderQueue/use-render-output-file-drag.js +121 -0
  40. package/dist/components/SegmentedControl.js +0 -1
  41. package/dist/components/SelectedOutlineElement.d.ts +14 -17
  42. package/dist/components/SelectedOutlineElement.js +112 -930
  43. package/dist/components/SelectedOutlineKeyboardControls.d.ts +7 -0
  44. package/dist/components/SelectedOutlineKeyboardControls.js +261 -0
  45. package/dist/components/SelectedOutlineOverlay.d.ts +6 -13
  46. package/dist/components/SelectedOutlineOverlay.js +349 -864
  47. package/dist/components/SelectedOutlinePolygon.d.ts +25 -0
  48. package/dist/components/SelectedOutlinePolygon.js +359 -0
  49. package/dist/components/SelectedOutlineRenderer.d.ts +18 -0
  50. package/dist/components/SelectedOutlineRenderer.js +208 -0
  51. package/dist/components/SelectedOutlineRotationCornerHandle.d.ts +16 -0
  52. package/dist/components/SelectedOutlineRotationCornerHandle.js +269 -0
  53. package/dist/components/SelectedOutlineScaleEdgeLine.d.ts +16 -0
  54. package/dist/components/SelectedOutlineScaleEdgeLine.js +211 -0
  55. package/dist/components/SelectedOutlineSnapIndicators.d.ts +9 -0
  56. package/dist/components/SelectedOutlineSnapIndicators.js +29 -0
  57. package/dist/components/SelectedOutlineTransformOriginHandle.d.ts +9 -0
  58. package/dist/components/SelectedOutlineTransformOriginHandle.js +286 -0
  59. package/dist/components/SelectedOutlineUvControls.d.ts +3 -9
  60. package/dist/components/SelectedOutlineUvControls.js +57 -12
  61. package/dist/components/SettingsContext.d.ts +15 -0
  62. package/dist/components/SettingsContext.js +116 -0
  63. package/dist/components/SettingsModal.js +10 -4
  64. package/dist/components/SettingsModalFooter.d.ts +1 -3
  65. package/dist/components/SettingsModalFooter.js +4 -6
  66. package/dist/components/ShowOutlinesProvider.js +2 -3
  67. package/dist/components/Timeline/EasingEditorModal.js +66 -22
  68. package/dist/components/Timeline/Timeline.js +22 -5
  69. package/dist/components/Timeline/TimelineDuplicateCount.d.ts +4 -0
  70. package/dist/components/Timeline/TimelineDuplicateCount.js +28 -0
  71. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +3 -23
  72. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +4 -2
  73. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +11 -1
  74. package/dist/components/Timeline/TimelineSequence.js +28 -25
  75. package/dist/components/Timeline/TimelineSequenceItem.js +49 -27
  76. package/dist/components/Timeline/TimelineTrack.js +2 -1
  77. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -3
  78. package/dist/components/Timeline/get-sequence-context-menu-items.js +58 -53
  79. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +36 -4
  80. package/dist/components/Timeline/{use-open-sequence-in-editor.d.ts → use-open-sequence-in-apps.d.ts} +4 -1
  81. package/dist/components/Timeline/{use-open-sequence-in-editor.js → use-open-sequence-in-apps.js} +20 -4
  82. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +4 -0
  83. package/dist/components/Timeline/use-timeline-expanded-tree.js +45 -1
  84. package/dist/components/get-open-in-menu-items.d.ts +12 -0
  85. package/dist/components/get-open-in-menu-items.js +83 -0
  86. package/dist/components/selected-outline-measurement.d.ts +2 -2
  87. package/dist/components/selected-outline-order.d.ts +12 -0
  88. package/dist/components/selected-outline-order.js +251 -0
  89. package/dist/components/selected-outline-types.d.ts +9 -10
  90. package/dist/components/svg-point-to-client-point.d.ts +2 -0
  91. package/dist/components/svg-point-to-client-point.js +10 -0
  92. package/dist/components/use-auto-save-config.d.ts +8 -0
  93. package/dist/components/use-auto-save-config.js +74 -0
  94. package/dist/components/use-default-editor-info.d.ts +1 -0
  95. package/dist/components/use-default-editor-info.js +10 -30
  96. package/dist/esm/{chunk-jefhcs5z.js → chunk-fgedsvhb.js} +1 -2
  97. package/dist/esm/{chunk-b49ec3nz.js → chunk-ptnd65a9.js} +10602 -9364
  98. package/dist/esm/internals.mjs +10601 -9363
  99. package/dist/esm/previewEntry.mjs +10462 -9224
  100. package/dist/esm/renderEntry.mjs +2 -2
  101. package/dist/helpers/are-sequence-node-path-infos-equal.d.ts +2 -0
  102. package/dist/helpers/are-sequence-node-path-infos-equal.js +27 -0
  103. package/dist/helpers/calculate-timeline.js +3 -3
  104. package/dist/helpers/client-id.js +8 -1
  105. package/dist/helpers/format-file-location.d.ts +1 -1
  106. package/dist/helpers/format-file-location.js +3 -3
  107. package/dist/helpers/migrate-expanded-tracks-for-subscription-key.js +3 -3
  108. package/dist/helpers/open-in-editor.d.ts +1 -0
  109. package/dist/helpers/open-in-editor.js +5 -1
  110. package/dist/helpers/studio-runtime-config.js +3 -0
  111. package/dist/helpers/timeline-node-path-key.d.ts +2 -0
  112. package/dist/helpers/timeline-node-path-key.js +3 -1
  113. package/dist/helpers/use-asset-drag-events.d.ts +2 -1
  114. package/dist/helpers/use-asset-drag-events.js +14 -6
  115. package/dist/helpers/use-menu-structure.js +2 -2
  116. package/dist/helpers/use-runtime-values.d.ts +1 -3
  117. package/dist/state/timeline-sequence-hover.d.ts +9 -3
  118. package/dist/state/timeline-sequence-hover.js +63 -12
  119. package/package.json +12 -12
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.SelectedOutlineOverlay = exports.orderOutlinesForRendering = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getSelectedCropInfo = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineTransformOriginDragChanges = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineCropFollowingTransformOrigin = exports.getSelectedOutlineCropDragValues = exports.getSelectedOutlineCropDragChanges = exports.getSelectedOutlineActiveSchema = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = void 0;
36
+ exports.SelectedOutlineOverlay = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getSelectedCropInfo = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineTransformOriginDragChanges = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineCropFollowingTransformOrigin = exports.getSelectedOutlineCropDragValues = exports.getSelectedOutlineCropDragChanges = exports.getSelectedOutlineActiveSchema = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = exports.orderOutlinesForRendering = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const player_1 = require("@remotion/player");
39
39
  const react_1 = __importStar(require("react"));
@@ -41,25 +41,19 @@ const remotion_1 = require("remotion");
41
41
  const no_react_1 = require("remotion/no-react");
42
42
  const client_id_1 = require("../helpers/client-id");
43
43
  const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
44
+ const timeline_node_path_key_1 = require("../helpers/timeline-node-path-key");
44
45
  const use_is_fullscreen_1 = require("../helpers/use-is-fullscreen");
45
- const use_keybinding_1 = require("../helpers/use-keybinding");
46
46
  const use_runtime_values_1 = require("../helpers/use-runtime-values");
47
- const editor_guides_1 = require("../state/editor-guides");
48
47
  const editor_outlines_1 = require("../state/editor-outlines");
49
48
  const scale_lock_1 = require("../state/scale-lock");
50
49
  const timeline_sequence_hover_1 = require("../state/timeline-sequence-hover");
51
- const NotificationCenter_1 = require("./Notifications/NotificationCenter");
52
50
  const selected_outline_drag_1 = require("./selected-outline-drag");
53
51
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
54
- const selected_outline_snap_1 = require("./selected-outline-snap");
52
+ const selected_outline_order_1 = require("./selected-outline-order");
53
+ Object.defineProperty(exports, "orderOutlinesForRendering", { enumerable: true, get: function () { return selected_outline_order_1.orderOutlinesForRendering; } });
55
54
  const selected_outline_types_1 = require("./selected-outline-types");
56
- const selected_outline_uv_1 = require("./selected-outline-uv");
57
- const SelectedOutlineElement_1 = require("./SelectedOutlineElement");
58
- const SelectedOutlineUvControls_1 = require("./SelectedOutlineUvControls");
59
- const call_add_keyframe_1 = require("./Timeline/call-add-keyframe");
60
- const imperative_state_1 = require("./Timeline/imperative-state");
61
- const save_sequence_prop_1 = require("./Timeline/save-sequence-prop");
62
- const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
55
+ const SelectedOutlineKeyboardControls_1 = require("./SelectedOutlineKeyboardControls");
56
+ const SelectedOutlineRenderer_1 = require("./SelectedOutlineRenderer");
63
57
  const TimelineSelection_1 = require("./Timeline/TimelineSelection");
64
58
  const selected_outline_drag_2 = require("./selected-outline-drag");
65
59
  Object.defineProperty(exports, "applySelectedOutlineDragAxisLock", { enumerable: true, get: function () { return selected_outline_drag_2.applySelectedOutlineDragAxisLock; } });
@@ -144,518 +138,196 @@ const getCropDragFields = ({ activeSchema, cropValues, propStatuses, }) => {
144
138
  }
145
139
  return fields;
146
140
  };
147
- const outlineContainer = {
148
- position: 'absolute',
149
- inset: 0,
150
- pointerEvents: 'none',
151
- overflow: 'visible',
152
- };
153
- const SelectedOutlineSnapIndicators = ({ activeSnapPoints, compositionHeight, compositionWidth, scale }) => {
154
- if (activeSnapPoints.length === 0) {
155
- return null;
156
- }
157
- return (jsx_runtime_1.jsx("g", { pointerEvents: "none", children: activeSnapPoints.map((snapPoint) => {
158
- if (snapPoint.target.axis === 'x') {
159
- const x = snapPoint.target.position * scale;
160
- return (jsx_runtime_1.jsx("line", { x1: x, x2: x, y1: 0, y2: compositionHeight * scale, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
161
- }
162
- const y = snapPoint.target.position * scale;
163
- return (jsx_runtime_1.jsx("line", { x1: 0, x2: compositionWidth * scale, y1: y, y2: y, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
164
- }) }));
165
- };
166
- const outlinePointEqualityTolerance = 0.5;
167
- const outlineAreaEqualityTolerance = 0.5;
168
- const outlineBoundsOverlapTolerance = 0.5;
169
- const outlinePointsAreEquivalent = (a, b) => {
170
- return (Math.abs(a.x - b.x) <= outlinePointEqualityTolerance &&
171
- Math.abs(a.y - b.y) <= outlinePointEqualityTolerance);
172
- };
173
- const outlinesHaveEquivalentHitArea = (a, b) => {
174
- if (a.points.length !== b.points.length) {
175
- return false;
176
- }
177
- for (let startIndex = 0; startIndex < b.points.length; startIndex++) {
178
- for (const direction of [1, -1]) {
179
- const pointsMatch = a.points.every((point, index) => {
180
- const bIndex = (startIndex + direction * index + b.points.length) % b.points.length;
181
- return outlinePointsAreEquivalent(point, b.points[bIndex]);
182
- });
183
- if (pointsMatch) {
184
- return true;
185
- }
186
- }
187
- }
188
- return false;
189
- };
190
- const getOutlineHitArea = (outline) => {
191
- let area = 0;
192
- for (let i = 0; i < outline.points.length; i++) {
193
- const current = outline.points[i];
194
- const next = outline.points[(i + 1) % outline.points.length];
195
- area += current.x * next.y - next.x * current.y;
196
- }
197
- return Math.abs(area) / 2;
198
- };
199
- const getOutlineBounds = (outline) => {
200
- const xs = outline.points.map((point) => point.x);
201
- const ys = outline.points.map((point) => point.y);
202
- return {
203
- maxX: Math.max(...xs),
204
- maxY: Math.max(...ys),
205
- minX: Math.min(...xs),
206
- minY: Math.min(...ys),
207
- };
208
- };
209
- const outlineBoundsOverlap = (a, b) => {
210
- const aBounds = getOutlineBounds(a);
211
- const bBounds = getOutlineBounds(b);
212
- return (aBounds.minX <= bBounds.maxX + outlineBoundsOverlapTolerance &&
213
- aBounds.maxX + outlineBoundsOverlapTolerance >= bBounds.minX &&
214
- aBounds.minY <= bBounds.maxY + outlineBoundsOverlapTolerance &&
215
- aBounds.maxY + outlineBoundsOverlapTolerance >= bBounds.minY);
216
- };
217
- const getSequenceId = (target) => {
218
- var _a;
219
- var _b;
220
- return (_b = (_a = target === null || target === void 0 ? void 0 : target.sequence) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
221
- };
222
- const getParentBySequenceId = ({ sequences, targetsByKey, }) => {
223
- const parentBySequenceId = new Map();
224
- for (const sequence of sequences) {
225
- parentBySequenceId.set(sequence.id, sequence.parent);
226
- }
227
- for (const target of targetsByKey.values()) {
228
- const sequenceId = getSequenceId(target);
229
- if (sequenceId !== null && !parentBySequenceId.has(sequenceId)) {
230
- parentBySequenceId.set(sequenceId, target.sequence.parent);
231
- }
232
- }
233
- return parentBySequenceId;
234
- };
235
- const isAncestorTarget = ({ ancestor, descendant, parentBySequenceId, }) => {
236
- var _a;
237
- var _b, _c;
238
- const ancestorId = getSequenceId(ancestor);
239
- if (ancestorId === null) {
240
- return false;
241
- }
242
- let parentId = (_b = (_a = descendant.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
243
- while (parentId !== null) {
244
- if (parentId === ancestorId) {
245
- return true;
246
- }
247
- parentId = (_c = parentBySequenceId.get(parentId)) !== null && _c !== void 0 ? _c : null;
248
- }
249
- return false;
250
- };
251
- const orderOutlineGroup = ({ outlines, parentBySequenceId, targetsByKey, }) => {
252
- var _a;
253
- var _b, _c, _d, _e;
254
- const incomingEdges = new Map();
255
- const outgoingEdges = new Map();
256
- const outlinesByKey = new Map(outlines.map((outline) => [outline.key, outline]));
257
- for (const outline of outlines) {
258
- incomingEdges.set(outline.key, new Set());
259
- outgoingEdges.set(outline.key, new Set());
260
- }
261
- const hasPath = ({ fromKey, seen, toKey, }) => {
262
- var _a;
263
- if (fromKey === toKey) {
264
- return true;
265
- }
266
- if (seen.has(fromKey)) {
267
- return false;
268
- }
269
- seen.add(fromKey);
270
- for (const nextKey of (_a = outgoingEdges.get(fromKey)) !== null && _a !== void 0 ? _a : []) {
271
- if (hasPath({ fromKey: nextKey, seen, toKey })) {
272
- return true;
273
- }
274
- }
275
- return false;
276
- };
277
- const addEdge = (before, after, options) => {
278
- if (before.key === after.key) {
279
- return;
280
- }
281
- const incoming = incomingEdges.get(after.key);
282
- const outgoing = outgoingEdges.get(before.key);
283
- if (incoming === undefined || outgoing === undefined) {
284
- throw new Error('Expected outline to be registered before adding edge');
285
- }
286
- if (outgoing.has(after.key)) {
287
- return;
288
- }
289
- if (hasPath({ fromKey: after.key, seen: new Set(), toKey: before.key })) {
290
- if (options === null || options === void 0 ? void 0 : options.skipIfCycle) {
291
- return;
292
- }
293
- throw new Error('Could not determine a stable outline rendering order');
294
- }
295
- incoming.add(before.key);
296
- outgoing.add(after.key);
297
- };
298
- const addAncestorConstraint = ({ ancestor, descendant, descendantContainsSelection, equivalentHitArea, }) => {
299
- // Usually, children should be above parents so nested elements are directly
300
- // selectable. If an unselected child has the same hit area as its parent, put
301
- // it below the parent so the wrapper can be selected. Once the child or
302
- // one of its properties is selected, keep it above the parent so it remains
303
- // directly draggable.
304
- if (equivalentHitArea && !descendantContainsSelection) {
305
- addEdge(descendant, ancestor);
306
- }
307
- else {
308
- addEdge(ancestor, descendant);
309
- }
310
- };
311
- const outlineBySequenceId = new Map();
312
- for (const outline of outlines) {
313
- const sequenceId = getSequenceId(targetsByKey.get(outline.key));
314
- if (sequenceId !== null) {
315
- outlineBySequenceId.set(sequenceId, outline);
316
- }
317
- }
318
- // Only constrain each outline against its nearest rendered ancestor. The
319
- // resulting graph follows the sequence tree, so pairwise subpixel equivalence
320
- // cannot introduce contradictory edges across three nested outlines.
321
- for (const descendant of outlines) {
322
- const descendantTarget = targetsByKey.get(descendant.key);
323
- let parentId = (_b = (_a = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
324
- while (parentId !== null) {
325
- const ancestor = outlineBySequenceId.get(parentId);
326
- if (ancestor !== undefined) {
327
- addAncestorConstraint({
328
- ancestor,
329
- descendant,
330
- descendantContainsSelection: ((_c = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.selected) !== null && _c !== void 0 ? _c : false) ||
331
- ((_d = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.containsSelection) !== null && _d !== void 0 ? _d : false),
332
- equivalentHitArea: outlinesHaveEquivalentHitArea(ancestor, descendant),
333
- });
334
- break;
335
- }
336
- parentId = (_e = parentBySequenceId.get(parentId)) !== null && _e !== void 0 ? _e : null;
337
- }
338
- }
339
- // For unrelated overlapping outlines, put broader hit targets below
340
- // smaller ones so a large selected sequence cannot swallow clicks on
341
- // a more specific element in the same canvas area.
342
- for (let i = 0; i < outlines.length; i++) {
343
- for (let j = i + 1; j < outlines.length; j++) {
344
- const a = outlines[i];
345
- const b = outlines[j];
346
- const aTarget = targetsByKey.get(a.key);
347
- const bTarget = targetsByKey.get(b.key);
348
- if (aTarget === undefined || bTarget === undefined) {
349
- continue;
350
- }
351
- const aAncestorOfB = isAncestorTarget({
352
- ancestor: aTarget,
353
- descendant: bTarget,
354
- parentBySequenceId,
355
- });
356
- const bAncestorOfA = isAncestorTarget({
357
- ancestor: bTarget,
358
- descendant: aTarget,
359
- parentBySequenceId,
360
- });
361
- if (aAncestorOfB || bAncestorOfA || !outlineBoundsOverlap(a, b)) {
362
- continue;
363
- }
364
- const aArea = getOutlineHitArea(a);
365
- const bArea = getOutlineHitArea(b);
366
- if (Math.abs(aArea - bArea) <= outlineAreaEqualityTolerance) {
367
- continue;
368
- }
369
- if (aArea > bArea) {
370
- addEdge(a, b, { skipIfCycle: true });
371
- }
372
- else {
373
- addEdge(b, a, { skipIfCycle: true });
374
- }
375
- }
141
+ const calculateOutlineTargets = ({ connectedClientId, editorShowOutlines, getDragOverrides, getScaleLockState, isFullscreen, mode, previewSelectionAvailable, propStatuses, runtimeValuesByStore, selectableOutlines, selectedCropInfo, selectedEffectsBySequenceKey, selectedSequenceKeys, selectedTransformOriginInfo, sequenceKeysContainingSelection, studioInteractivityEnabled, targetKey, targetTimelinePosition, }) => {
142
+ if (isFullscreen ||
143
+ !(0, interactivity_enabled_1.isStudioSelectionEnabled)() ||
144
+ !previewSelectionAvailable ||
145
+ !editorShowOutlines) {
146
+ return [];
376
147
  }
377
- const emitted = new Set();
378
- const visiting = new Set();
379
- const ordered = [];
380
- const visit = (outline) => {
381
- var _a;
382
- if (emitted.has(outline.key)) {
383
- return;
148
+ const previewInteractive = connectedClientId !== null && studioInteractivityEnabled;
149
+ const firstNodePathInfoBySourceNode = new Map();
150
+ const selectedSourceNodeKeys = new Set();
151
+ for (const { key, nodePathInfo } of selectableOutlines) {
152
+ const sourceNodeKey = (0, timeline_node_path_key_1.timelineSequenceNodePathToKey)(nodePathInfo.sequenceSubscriptionKey);
153
+ if (selectedSequenceKeys.has(key)) {
154
+ selectedSourceNodeKeys.add(sourceNodeKey);
155
+ }
156
+ const currentFirst = firstNodePathInfoBySourceNode.get(sourceNodeKey);
157
+ if (currentFirst === undefined || nodePathInfo.index < currentFirst.index) {
158
+ firstNodePathInfoBySourceNode.set(sourceNodeKey, nodePathInfo);
384
159
  }
385
- if (visiting.has(outline.key)) {
386
- throw new Error('Could not determine a stable outline rendering order');
387
- }
388
- visiting.add(outline.key);
389
- for (const dependencyKey of (_a = incomingEdges.get(outline.key)) !== null && _a !== void 0 ? _a : []) {
390
- const dependency = outlinesByKey.get(dependencyKey);
391
- if (dependency === undefined) {
392
- throw new Error('Expected outline dependency to exist');
393
- }
394
- visit(dependency);
395
- }
396
- visiting.delete(outline.key);
397
- emitted.add(outline.key);
398
- ordered.push(outline);
399
- };
400
- for (const outline of outlines) {
401
- visit(outline);
402
160
  }
403
- return ordered;
404
- };
405
- const orderOutlinesForRendering = ({ outlines, sequences, targetsByKey, }) => {
406
- const parentBySequenceId = getParentBySequenceId({ sequences, targetsByKey });
407
- return orderOutlineGroup({
408
- outlines,
409
- parentBySequenceId,
410
- targetsByKey,
411
- });
412
- };
413
- exports.orderOutlinesForRendering = orderOutlinesForRendering;
414
- const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
415
- const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
416
- const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
417
- const { canvasContent, compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
418
- const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
419
- const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
420
- const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
421
- const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
422
- const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
423
- const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
424
- const { editorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
425
- const { hoveredSequence, setHoveredSequence } = (0, react_1.useContext)(timeline_sequence_hover_1.TimelineSequenceHoverContext);
426
- const { editorShowGuides, guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
427
- const isFullscreen = (0, use_is_fullscreen_1.useIsFullscreen)();
428
- const { frameBack, frameForward, getCurrentFrame, seek } = player_1.PlayerInternals.usePlayerMethods();
429
- const keybindings = (0, use_keybinding_1.useKeybinding)();
430
- const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
431
- const [outlines, setOutlines] = (0, react_1.useState)([]);
432
- const [draggingOutline, setDraggingOutline] = (0, react_1.useState)(false);
433
- const [activeSnapPoints, setActiveSnapPoints] = (0, react_1.useState)([]);
434
- const overlayRef = (0, react_1.useRef)(null);
435
- const keyboardNudgeSessionRef = (0, react_1.useRef)(null);
436
- const saveKeyboardNudgeSessionRef = (0, react_1.useRef)(() => undefined);
437
- const previewInteractive = previewServerState.type === 'connected' && (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
438
- const previewSelectionAvailable = previewServerState.type === 'connected' || window.remotion_isReadOnlyStudio;
439
- const onDraggingChange = react_1.default.useCallback((dragging) => {
440
- setDraggingOutline(dragging);
441
- if (dragging) {
442
- setHoveredSequence((currentHover) => (currentHover === null || currentHover === void 0 ? void 0 : currentHover.source) === 'canvas' ? null : currentHover);
443
- }
444
- else {
445
- setActiveSnapPoints([]);
446
- }
447
- }, [setHoveredSequence]);
448
- const onHoverChange = (0, react_1.useCallback)((key) => {
449
- setHoveredSequence((currentHover) => {
450
- if (key !== null) {
451
- return { key, source: 'canvas' };
452
- }
453
- return (currentHover === null || currentHover === void 0 ? void 0 : currentHover.source) === 'canvas' ? null : currentHover;
454
- });
455
- }, [setHoveredSequence]);
456
- const onSnapPointsChange = (0, react_1.useCallback)((snapPoints) => {
457
- setActiveSnapPoints(snapPoints);
458
- }, []);
459
- const selectOutlineItem = (0, react_1.useCallback)((item, interaction) => {
460
- selectItem(item, interaction, undefined, { reveal: true });
461
- }, [selectItem]);
462
- const outlineRuntimeControls = (0, react_1.useMemo)(() => {
463
- if (isFullscreen ||
464
- !(0, interactivity_enabled_1.isStudioSelectionEnabled)() ||
465
- !previewSelectionAvailable ||
466
- !editorShowOutlines) {
161
+ return selectableOutlines.flatMap((selectableOutline) => {
162
+ var _a, _b, _c, _d, _e, _f, _g;
163
+ const { key, keyframeDisplayOffset, nodePathInfo, sequence } = selectableOutline;
164
+ if (targetKey !== null && targetKey !== key) {
467
165
  return [];
468
166
  }
469
- const selectedSequenceKeys = (0, selected_outline_measurement_1.getSelectedSequenceKeys)(selectedItems);
470
- const sequenceKeysContainingSelection = (0, selected_outline_measurement_1.getSequenceKeysContainingSelection)(selectedItems);
471
- return (0, selected_outline_measurement_1.getSequencesWithSelectableOutlines)({
472
- sequences,
473
- overrideIdsToNodePaths: overrideIdToNodePathMappings,
474
- compositions,
475
- timelinePosition,
476
- }).flatMap(({ key, sequence }) => {
477
- if (!selectedSequenceKeys.has(key) &&
478
- !sequenceKeysContainingSelection.has(key) &&
479
- (hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.key) !== key) {
480
- return [];
481
- }
482
- return sequence.controls ? [sequence.controls] : [];
483
- });
484
- }, [
485
- compositions,
486
- editorShowOutlines,
487
- hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.key,
488
- isFullscreen,
489
- overrideIdToNodePathMappings,
490
- previewSelectionAvailable,
491
- selectedItems,
492
- sequences,
493
- timelinePosition,
494
- ]);
495
- const outlineRuntimeSnapshots = (0, use_runtime_values_1.useRuntimeValueSnapshots)(outlineRuntimeControls);
496
- const outlineRuntimeValuesByStore = (0, react_1.useMemo)(() => new Map(outlineRuntimeControls.map((controls, index) => [
497
- controls.runtimeValues,
498
- outlineRuntimeSnapshots[index],
499
- ])), [outlineRuntimeControls, outlineRuntimeSnapshots]);
500
- const outlineTargets = (0, react_1.useMemo)(() => {
501
- if (isFullscreen ||
502
- !(0, interactivity_enabled_1.isStudioSelectionEnabled)() ||
503
- !previewSelectionAvailable ||
504
- !editorShowOutlines) {
505
- return [];
506
- }
507
- const selectedSequenceKeys = (0, selected_outline_measurement_1.getSelectedSequenceKeys)(selectedItems);
508
- const sequenceKeysContainingSelection = (0, selected_outline_measurement_1.getSequenceKeysContainingSelection)(selectedItems);
509
- const selectedEffectsBySequenceKey = (0, selected_outline_measurement_1.getSelectedEffectFieldsBySequenceKey)(selectedItems);
510
- const selectedTransformOriginInfo = (0, selected_outline_measurement_1.getSelectedTransformOriginInfo)(selectedItems);
511
- const selectedCropInfo = (0, selected_outline_measurement_1.getSelectedCropInfo)(selectedItems);
512
- const clientId = previewServerState.type === 'connected'
513
- ? previewServerState.clientId
167
+ if (sequence.refForOutline === null) {
168
+ throw new Error('Expected sequence to have a ref for outline');
169
+ }
170
+ const selected = selectedSequenceKeys.has(key);
171
+ const containsSelection = sequenceKeysContainingSelection.has(key);
172
+ const nodePath = nodePathInfo.sequenceSubscriptionKey;
173
+ const sourceNodeKey = (0, timeline_node_path_key_1.timelineSequenceNodePathToKey)(nodePath);
174
+ const showSelectedOutline = containsSelection || selectedSourceNodeKeys.has(sourceNodeKey);
175
+ const selectionNodePathInfo = firstNodePathInfoBySourceNode.get(sourceNodeKey);
176
+ if (selectionNodePathInfo === undefined) {
177
+ throw new Error('Expected a first sequence for the source node');
178
+ }
179
+ const { controls } = sequence;
180
+ const nodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath);
181
+ const sourceFrame = targetTimelinePosition - keyframeDisplayOffset;
182
+ const dragOverrides = (_a = getDragOverrides(nodePath)) !== null && _a !== void 0 ? _a : {};
183
+ const runtimeValues = controls
184
+ ? ((_b = runtimeValuesByStore.get(controls.runtimeValues)) !== null && _b !== void 0 ? _b : controls.runtimeValues.getSnapshot())
185
+ : {};
186
+ const activeSchema = controls
187
+ ? (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
188
+ schema: controls.schema,
189
+ currentRuntimeValueDotNotation: runtimeValues,
190
+ dragOverrides,
191
+ propStatus: nodePropStatuses,
192
+ frame: sourceFrame,
193
+ })
514
194
  : null;
515
- return (0, selected_outline_measurement_1.getSequencesWithSelectableOutlines)({
516
- sequences,
517
- overrideIdsToNodePaths: overrideIdToNodePathMappings,
518
- compositions,
519
- timelinePosition,
520
- }).map(({ key, keyframeDisplayOffset, nodePathInfo, sequence }) => {
521
- var _a, _b, _c, _d, _e, _f, _g;
522
- if (sequence.refForOutline === null) {
523
- throw new Error('Expected sequence to have a ref for outline');
524
- }
525
- const selected = selectedSequenceKeys.has(key);
526
- const containsSelection = sequenceKeysContainingSelection.has(key);
527
- const nodePath = nodePathInfo.sequenceSubscriptionKey;
528
- const { controls } = sequence;
529
- const nodePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath);
530
- const sourceFrame = timelinePosition - keyframeDisplayOffset;
531
- const dragOverrides = (_a = getDragOverrides(nodePath)) !== null && _a !== void 0 ? _a : {};
532
- const runtimeValues = controls
533
- ? ((_b = outlineRuntimeValuesByStore.get(controls.runtimeValues)) !== null && _b !== void 0 ? _b : controls.runtimeValues.getSnapshot())
534
- : {};
535
- const activeSchema = controls
536
- ? (0, selected_outline_drag_1.getSelectedOutlineActiveSchema)({
537
- schema: controls.schema,
538
- currentRuntimeValueDotNotation: runtimeValues,
539
- dragOverrides,
540
- propStatus: nodePropStatuses,
541
- frame: sourceFrame,
542
- })
543
- : null;
544
- const cropValues = {
545
- cropLeft: getEffectiveCropValue({
546
- activeSchema,
547
- dragOverrides,
548
- fieldKey: selected_outline_types_1.cropFieldKeys.left,
549
- frame: sourceFrame,
550
- propStatuses: nodePropStatuses,
551
- runtimeValues,
552
- }),
553
- cropRight: getEffectiveCropValue({
554
- activeSchema,
555
- dragOverrides,
556
- fieldKey: selected_outline_types_1.cropFieldKeys.right,
557
- frame: sourceFrame,
558
- propStatuses: nodePropStatuses,
559
- runtimeValues,
560
- }),
561
- cropTop: getEffectiveCropValue({
562
- activeSchema,
563
- dragOverrides,
564
- fieldKey: selected_outline_types_1.cropFieldKeys.top,
565
- frame: sourceFrame,
566
- propStatuses: nodePropStatuses,
567
- runtimeValues,
568
- }),
569
- cropBottom: getEffectiveCropValue({
570
- activeSchema,
571
- dragOverrides,
572
- fieldKey: selected_outline_types_1.cropFieldKeys.bottom,
573
- frame: sourceFrame,
574
- propStatuses: nodePropStatuses,
575
- runtimeValues,
576
- }),
577
- };
578
- const crop = remotion_1.Internals.resolveSequenceCrop(cropValues);
579
- const cropFields = getCropDragFields({
195
+ const cropValues = {
196
+ cropLeft: getEffectiveCropValue({
580
197
  activeSchema,
581
- cropValues,
198
+ dragOverrides,
199
+ fieldKey: selected_outline_types_1.cropFieldKeys.left,
200
+ frame: sourceFrame,
582
201
  propStatuses: nodePropStatuses,
583
- });
584
- const fieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.translateFieldKey];
585
- const propStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.translateFieldKey];
586
- const scaleFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.scaleFieldKey];
587
- const scalePropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.scaleFieldKey];
588
- const rotationFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.rotateFieldKey];
589
- const rotationPropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.rotateFieldKey];
590
- const transformOriginFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.transformOriginFieldKey];
591
- const transformOriginPropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.transformOriginFieldKey];
592
- const transformOriginValueForRotation = (transformOriginFieldSchema === null || transformOriginFieldSchema === void 0 ? void 0 : transformOriginFieldSchema.type) === 'transform-origin' &&
593
- ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
594
- (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed')
595
- ? String((_c = remotion_1.Internals.getEffectiveVisualModeValue({
596
- propStatus: transformOriginPropStatus,
597
- dragOverrideValue: dragOverrides[selected_outline_types_1.transformOriginFieldKey],
598
- defaultValue: transformOriginFieldSchema.default,
599
- frame: sourceFrame,
600
- shouldResortToDefaultValueIfUndefined: true,
601
- })) !== null && _c !== void 0 ? _c : transformOriginFieldSchema.default)
602
- : '50% 50%';
603
- const canDragStatus = (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static' ||
604
- ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' &&
605
- propStatus.interpolationFunction === 'interpolate');
606
- const canRotationDragStatus = (rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'static' ||
607
- ((rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'keyframed' &&
608
- rotationPropStatus.interpolationFunction === 'interpolate');
609
- const canDrag = previewInteractive &&
610
- controls !== null &&
611
- (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
612
- canDragStatus;
613
- const canScaleDragStatus = (scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'static' ||
614
- ((scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'keyframed' &&
615
- scalePropStatus.interpolationFunction === 'interpolate');
616
- const canScaleDrag = previewInteractive &&
617
- controls !== null &&
618
- (scaleFieldSchema === null || scaleFieldSchema === void 0 ? void 0 : scaleFieldSchema.type) === 'scale' &&
619
- canScaleDragStatus;
620
- const canRotationDrag = previewInteractive &&
621
- controls !== null &&
622
- (rotationFieldSchema === null || rotationFieldSchema === void 0 ? void 0 : rotationFieldSchema.type) === 'rotation-css' &&
623
- canRotationDragStatus;
624
- const selectedForTransformOrigin = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.sequenceKey) === key;
625
- const transformOriginSourceFrame = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === null ||
626
- (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === undefined
627
- ? sourceFrame
628
- : selectedTransformOriginInfo.displayFrame - keyframeDisplayOffset;
629
- const canTransformOriginStatus = (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
630
- ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed' &&
631
- transformOriginPropStatus.interpolationFunction === 'interpolate');
632
- const canTransformOriginTranslateStatus = (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static' ||
633
- ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' &&
634
- propStatus.interpolationFunction === 'interpolate');
635
- const canTransformOriginDrag = previewInteractive &&
636
- selectedForTransformOrigin &&
637
- controls !== null &&
638
- (transformOriginFieldSchema === null || transformOriginFieldSchema === void 0 ? void 0 : transformOriginFieldSchema.type) === 'transform-origin' &&
639
- (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
640
- canTransformOriginStatus &&
641
- canTransformOriginTranslateStatus;
642
- const selectedForCrop = (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.sequenceKey) === key;
643
- const cropSourceFrame = (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.displayFrame) === null ||
644
- (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.displayFrame) === undefined
645
- ? sourceFrame
646
- : selectedCropInfo.displayFrame - keyframeDisplayOffset;
647
- const canCropDrag = previewInteractive &&
648
- selectedForCrop &&
649
- controls !== null &&
650
- cropFields !== null;
651
- const canDropEffect = previewInteractive && (controls === null || controls === void 0 ? void 0 : controls.supportsEffects) === true;
652
- return {
653
- key,
202
+ runtimeValues,
203
+ }),
204
+ cropRight: getEffectiveCropValue({
205
+ activeSchema,
206
+ dragOverrides,
207
+ fieldKey: selected_outline_types_1.cropFieldKeys.right,
208
+ frame: sourceFrame,
209
+ propStatuses: nodePropStatuses,
210
+ runtimeValues,
211
+ }),
212
+ cropTop: getEffectiveCropValue({
213
+ activeSchema,
214
+ dragOverrides,
215
+ fieldKey: selected_outline_types_1.cropFieldKeys.top,
216
+ frame: sourceFrame,
217
+ propStatuses: nodePropStatuses,
218
+ runtimeValues,
219
+ }),
220
+ cropBottom: getEffectiveCropValue({
221
+ activeSchema,
222
+ dragOverrides,
223
+ fieldKey: selected_outline_types_1.cropFieldKeys.bottom,
224
+ frame: sourceFrame,
225
+ propStatuses: nodePropStatuses,
226
+ runtimeValues,
227
+ }),
228
+ };
229
+ const crop = remotion_1.Internals.resolveSequenceCrop(cropValues);
230
+ const selectedForTransformOrigin = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.sequenceKey) === key;
231
+ const selectedForCrop = (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.sequenceKey) === key;
232
+ const selectedForUvHandles = selectedEffectsBySequenceKey.has(key);
233
+ const layoutTarget = {
234
+ key,
235
+ containsSelection,
236
+ crop,
237
+ keyframeDisplayOffset,
238
+ nodePathInfo,
239
+ ref: sequence.refForOutline,
240
+ selected,
241
+ selectedForCrop,
242
+ selectedForTransformOrigin,
243
+ selectedForUvHandles,
244
+ showSelectedOutline,
245
+ selection: {
246
+ type: 'sequence',
247
+ nodePathInfo: selectionNodePathInfo,
248
+ },
249
+ sequence,
250
+ };
251
+ if (mode === 'layout') {
252
+ return [layoutTarget];
253
+ }
254
+ const cropFields = getCropDragFields({
255
+ activeSchema,
256
+ cropValues,
257
+ propStatuses: nodePropStatuses,
258
+ });
259
+ const fieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.translateFieldKey];
260
+ const propStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.translateFieldKey];
261
+ const scaleFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.scaleFieldKey];
262
+ const scalePropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.scaleFieldKey];
263
+ const rotationFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.rotateFieldKey];
264
+ const rotationPropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.rotateFieldKey];
265
+ const transformOriginFieldSchema = activeSchema === null || activeSchema === void 0 ? void 0 : activeSchema[selected_outline_types_1.transformOriginFieldKey];
266
+ const transformOriginPropStatus = nodePropStatuses === null || nodePropStatuses === void 0 ? void 0 : nodePropStatuses[selected_outline_types_1.transformOriginFieldKey];
267
+ const transformOriginValueForRotation = (transformOriginFieldSchema === null || transformOriginFieldSchema === void 0 ? void 0 : transformOriginFieldSchema.type) === 'transform-origin' &&
268
+ ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
269
+ (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed')
270
+ ? String((_c = remotion_1.Internals.getEffectiveVisualModeValue({
271
+ propStatus: transformOriginPropStatus,
272
+ dragOverrideValue: dragOverrides[selected_outline_types_1.transformOriginFieldKey],
273
+ defaultValue: transformOriginFieldSchema.default,
274
+ frame: sourceFrame,
275
+ shouldResortToDefaultValueIfUndefined: true,
276
+ })) !== null && _c !== void 0 ? _c : transformOriginFieldSchema.default)
277
+ : '50% 50%';
278
+ const canDragStatus = (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static' ||
279
+ ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' &&
280
+ propStatus.interpolationFunction === 'interpolate');
281
+ const canRotationDragStatus = (rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'static' ||
282
+ ((rotationPropStatus === null || rotationPropStatus === void 0 ? void 0 : rotationPropStatus.status) === 'keyframed' &&
283
+ rotationPropStatus.interpolationFunction === 'interpolate');
284
+ const canDrag = previewInteractive &&
285
+ controls !== null &&
286
+ (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
287
+ canDragStatus;
288
+ const canScaleDragStatus = (scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'static' ||
289
+ ((scalePropStatus === null || scalePropStatus === void 0 ? void 0 : scalePropStatus.status) === 'keyframed' &&
290
+ scalePropStatus.interpolationFunction === 'interpolate');
291
+ const canScaleDrag = previewInteractive &&
292
+ controls !== null &&
293
+ (scaleFieldSchema === null || scaleFieldSchema === void 0 ? void 0 : scaleFieldSchema.type) === 'scale' &&
294
+ canScaleDragStatus;
295
+ const canRotationDrag = previewInteractive &&
296
+ controls !== null &&
297
+ (rotationFieldSchema === null || rotationFieldSchema === void 0 ? void 0 : rotationFieldSchema.type) === 'rotation-css' &&
298
+ canRotationDragStatus;
299
+ const transformOriginSourceFrame = (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === null ||
300
+ (selectedTransformOriginInfo === null || selectedTransformOriginInfo === void 0 ? void 0 : selectedTransformOriginInfo.displayFrame) === undefined
301
+ ? sourceFrame
302
+ : selectedTransformOriginInfo.displayFrame - keyframeDisplayOffset;
303
+ const canTransformOriginStatus = (transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'static' ||
304
+ ((transformOriginPropStatus === null || transformOriginPropStatus === void 0 ? void 0 : transformOriginPropStatus.status) === 'keyframed' &&
305
+ transformOriginPropStatus.interpolationFunction === 'interpolate');
306
+ const canTransformOriginTranslateStatus = (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static' ||
307
+ ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' &&
308
+ propStatus.interpolationFunction === 'interpolate');
309
+ const canTransformOriginDrag = previewInteractive &&
310
+ selectedForTransformOrigin &&
311
+ controls !== null &&
312
+ (transformOriginFieldSchema === null || transformOriginFieldSchema === void 0 ? void 0 : transformOriginFieldSchema.type) === 'transform-origin' &&
313
+ (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
314
+ canTransformOriginStatus &&
315
+ canTransformOriginTranslateStatus;
316
+ const cropSourceFrame = (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.displayFrame) === null ||
317
+ (selectedCropInfo === null || selectedCropInfo === void 0 ? void 0 : selectedCropInfo.displayFrame) === undefined
318
+ ? sourceFrame
319
+ : selectedCropInfo.displayFrame - keyframeDisplayOffset;
320
+ const canCropDrag = previewInteractive &&
321
+ selectedForCrop &&
322
+ controls !== null &&
323
+ cropFields !== null;
324
+ return [
325
+ {
326
+ ...layoutTarget,
654
327
  canCrop: previewInteractive && controls !== null && cropFields !== null,
655
- crop,
656
328
  cropDrag: canCropDrag
657
329
  ? {
658
- clientId: previewServerState.clientId,
330
+ clientId: connectedClientId,
659
331
  fields: cropFields,
660
332
  nodePath,
661
333
  schema: controls.schema,
@@ -670,23 +342,10 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
670
342
  : null,
671
343
  }
672
344
  : null,
673
- containsSelection,
674
- effectDrop: canDropEffect
675
- ? {
676
- clientId: previewServerState.clientId,
677
- fileName: nodePath.absolutePath,
678
- nodePath,
679
- }
680
- : null,
681
- nodePathInfo,
682
- ref: sequence.refForOutline,
683
- selected,
684
- selection: { type: 'sequence', nodePathInfo },
685
- sequence,
686
345
  drag: canDrag
687
346
  ? {
688
347
  propStatus,
689
- clientId: previewServerState.clientId,
348
+ clientId: connectedClientId,
690
349
  fieldDefault: fieldSchema.default,
691
350
  keyframeDisplayOffset,
692
351
  nodePath,
@@ -696,7 +355,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
696
355
  scaleDrag: canScaleDrag
697
356
  ? {
698
357
  propStatus: scalePropStatus,
699
- clientId: previewServerState.clientId,
358
+ clientId: connectedClientId,
700
359
  fieldDefault: scaleFieldSchema.default,
701
360
  fieldSchema: scaleFieldSchema,
702
361
  keyframeDisplayOffset,
@@ -722,7 +381,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
722
381
  rotationDrag: canRotationDrag
723
382
  ? {
724
383
  propStatus: rotationPropStatus,
725
- clientId: previewServerState.clientId,
384
+ clientId: connectedClientId,
726
385
  fieldDefault: rotationFieldSchema.default,
727
386
  fieldSchema: rotationFieldSchema,
728
387
  keyframeDisplayOffset,
@@ -733,7 +392,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
733
392
  : null,
734
393
  transformOriginDrag: canTransformOriginDrag
735
394
  ? {
736
- clientId: previewServerState.clientId,
395
+ clientId: connectedClientId,
737
396
  keyframeDisplayOffset,
738
397
  nodePath,
739
398
  originDefault: transformOriginFieldSchema.default,
@@ -782,353 +441,179 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
782
441
  })) !== null && _g !== void 0 ? _g : fieldSchema.default),
783
442
  }
784
443
  : null,
785
- uvHandles: containsSelection
786
- ? (0, selected_outline_uv_1.getSelectedUvHandles)({
787
- propStatuses,
788
- clientId,
789
- getEffectDragOverrides,
790
- nodePath,
791
- selectedEffects: selectedEffectsBySequenceKey.get(key),
792
- sequence,
793
- sourceFrame: timelinePosition - keyframeDisplayOffset,
794
- })
795
- : [],
796
- };
444
+ },
445
+ ];
446
+ });
447
+ };
448
+ const ActiveSelectedOutlineOverlayUnmemoized = ({ calculateOutlineTargetsForCurrentState, compositionHeight, compositionWidth, draggingOutline, getLatestOutlineTargetByKey, getSelectableOutlines, onDraggingChange, onSelect, scale, selectedSequenceKeys, sequenceKeysContainingSelection, sequences, translationX, translationY, }) => {
449
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
450
+ const updateOutlinesRef = (0, react_1.useRef)(() => undefined);
451
+ const selectableOutlines = (0, react_1.useMemo)(() => {
452
+ return getSelectableOutlines(timelinePosition);
453
+ }, [getSelectableOutlines, timelinePosition]);
454
+ const outlineRuntimeControls = (0, react_1.useMemo)(() => {
455
+ return selectableOutlines.flatMap(({ key, sequence }) => {
456
+ if (!selectedSequenceKeys.has(key) &&
457
+ !sequenceKeysContainingSelection.has(key)) {
458
+ return [];
459
+ }
460
+ return sequence.controls ? [sequence.controls] : [];
797
461
  });
798
462
  }, [
799
- propStatuses,
800
- getDragOverrides,
801
- getEffectDragOverrides,
802
- getScaleLockState,
803
- editorShowOutlines,
804
- isFullscreen,
805
- overrideIdToNodePathMappings,
806
- previewInteractive,
807
- previewSelectionAvailable,
808
- previewServerState,
809
- selectedItems,
810
- sequences,
811
- compositions,
812
- timelinePosition,
463
+ selectableOutlines,
464
+ selectedSequenceKeys,
465
+ sequenceKeysContainingSelection,
466
+ ]);
467
+ const outlineRuntimeSnapshots = (0, use_runtime_values_1.useRuntimeValueSnapshots)(outlineRuntimeControls);
468
+ const outlineRuntimeValuesByStore = (0, react_1.useMemo)(() => new Map(outlineRuntimeControls.map((controls, index) => [
469
+ controls.runtimeValues,
470
+ outlineRuntimeSnapshots[index],
471
+ ])), [outlineRuntimeControls, outlineRuntimeSnapshots]);
472
+ const outlineTargets = (0, react_1.useMemo)(() => calculateOutlineTargetsForCurrentState({
473
+ mode: 'layout',
474
+ runtimeValuesByStore: outlineRuntimeValuesByStore,
475
+ selectableOutlines,
476
+ targetKey: null,
477
+ targetTimelinePosition: timelinePosition,
478
+ }), [
479
+ calculateOutlineTargetsForCurrentState,
813
480
  outlineRuntimeValuesByStore,
481
+ selectableOutlines,
482
+ timelinePosition,
814
483
  ]);
815
- (0, react_1.useEffect)(() => {
816
- if ((hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.source) === 'canvas' &&
817
- !outlineTargets.some((target) => target.key === hoveredSequence.key)) {
818
- setHoveredSequence((currentHover) => (currentHover === null || currentHover === void 0 ? void 0 : currentHover.source) === 'canvas' ? null : currentHover);
819
- }
820
- }, [hoveredSequence, outlineTargets, setHoveredSequence]);
821
- const targetsByKey = (0, react_1.useMemo)(() => {
822
- return new Map(outlineTargets.map((target) => [target.key, target]));
823
- }, [outlineTargets]);
824
- const outlinesForRendering = (0, react_1.useMemo)(() => {
825
- return (0, exports.orderOutlinesForRendering)({ outlines, sequences, targetsByKey });
826
- }, [outlines, sequences, targetsByKey]);
827
- const outlinesByKey = (0, react_1.useMemo)(() => {
828
- return new Map(outlines.map((outline) => [outline.key, outline]));
829
- }, [outlines]);
830
- const allDragTargets = (0, react_1.useMemo)(() => {
831
- return outlineTargets.flatMap((target) => (target.selected || target.containsSelection) && target.drag !== null
832
- ? [target.drag]
833
- : []);
834
- }, [outlineTargets]);
835
- const allDragOutlines = (0, react_1.useMemo)(() => {
836
- return outlineTargets.flatMap((target) => {
837
- if ((!target.selected && !target.containsSelection) ||
838
- target.drag === null) {
839
- return [];
840
- }
841
- const outline = outlinesByKey.get(target.key);
842
- return outline === undefined ? [] : [outline];
843
- });
844
- }, [outlineTargets, outlinesByKey]);
845
- const allScaleDragTargets = (0, react_1.useMemo)(() => {
846
- return outlineTargets.flatMap((target) => target.selected && target.scaleDrag !== null ? [target.scaleDrag] : []);
847
- }, [outlineTargets]);
848
- const allRotationDragTargets = (0, react_1.useMemo)(() => {
849
- return outlineTargets.flatMap((target) => target.selected && target.rotationDrag !== null
850
- ? [target.rotationDrag]
851
- : []);
852
- }, [outlineTargets]);
853
- const guidesForSnap = (0, react_1.useMemo)(() => {
854
- if (!editorShowGuides || (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition') {
484
+ const outlineTargetsRef = (0, react_1.useRef)(outlineTargets);
485
+ const getOutlineTargets = (0, react_1.useCallback)(() => outlineTargetsRef.current, []);
486
+ (0, react_1.useLayoutEffect)(() => {
487
+ outlineTargetsRef.current = outlineTargets;
488
+ updateOutlinesRef.current();
489
+ }, [outlineTargets, scale, translationX, translationY]);
490
+ return (jsx_runtime_1.jsx(SelectedOutlineRenderer_1.SelectedOutlineRenderer, { compositionHeight: compositionHeight, compositionWidth: compositionWidth, dragging: draggingOutline, getLatestOutlineTargetByKey: getLatestOutlineTargetByKey, getOutlineTargets: getOutlineTargets, onDraggingChange: onDraggingChange, onSelect: onSelect, scale: scale, sequences: sequences, updateOutlinesRef: updateOutlinesRef }));
491
+ };
492
+ const ActiveSelectedOutlineOverlay = react_1.default.memo(ActiveSelectedOutlineOverlayUnmemoized);
493
+ const SelectedOutlineOverlayUnmemoized = ({ canvasHovered, compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
494
+ const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
495
+ const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
496
+ const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
497
+ const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
498
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
499
+ const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
500
+ const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
501
+ const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
502
+ const { editorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
503
+ const setHoveredSequence = (0, timeline_sequence_hover_1.useSetTimelineSequenceHover)();
504
+ const hoveredSequence = (0, timeline_sequence_hover_1.useTimelineSequenceHoverState)();
505
+ const isFullscreen = (0, use_is_fullscreen_1.useIsFullscreen)();
506
+ const { getCurrentFrame } = player_1.PlayerInternals.usePlayerMethods();
507
+ const [draggingOutline, setDraggingOutline] = (0, react_1.useState)(false);
508
+ const previewSelectionAvailable = previewServerState.type === 'connected' || window.remotion_isReadOnlyStudio;
509
+ const selectedSequenceKeys = (0, react_1.useMemo)(() => (0, selected_outline_measurement_1.getSelectedSequenceKeys)(selectedItems), [selectedItems]);
510
+ const sequenceKeysContainingSelection = (0, react_1.useMemo)(() => (0, selected_outline_measurement_1.getSequenceKeysContainingSelection)(selectedItems), [selectedItems]);
511
+ const selectedEffectsBySequenceKey = (0, react_1.useMemo)(() => (0, selected_outline_measurement_1.getSelectedEffectFieldsBySequenceKey)(selectedItems), [selectedItems]);
512
+ const selectedTransformOriginInfo = (0, react_1.useMemo)(() => (0, selected_outline_measurement_1.getSelectedTransformOriginInfo)(selectedItems), [selectedItems]);
513
+ const selectedCropInfo = (0, react_1.useMemo)(() => (0, selected_outline_measurement_1.getSelectedCropInfo)(selectedItems), [selectedItems]);
514
+ const getSelectableOutlines = (0, react_1.useCallback)((timelinePosition) => {
515
+ if (isFullscreen ||
516
+ !(0, interactivity_enabled_1.isStudioSelectionEnabled)() ||
517
+ !previewSelectionAvailable ||
518
+ !editorShowOutlines) {
855
519
  return [];
856
520
  }
857
- return guidesList.filter((guide) => guide.compositionId === canvasContent.compositionId);
858
- }, [canvasContent, editorShowGuides, guidesList]);
859
- const snapTargets = (0, react_1.useMemo)(() => {
860
- return (0, selected_outline_snap_1.getSelectedOutlineSnapTargets)({
861
- compositionHeight,
862
- compositionWidth,
863
- guides: guidesForSnap,
864
- });
865
- }, [compositionHeight, compositionWidth, guidesForSnap]);
866
- const saveKeyboardNudgeSession = (0, react_1.useCallback)(() => {
867
- const session = keyboardNudgeSessionRef.current;
868
- if (session === null) {
869
- return;
870
- }
871
- keyboardNudgeSessionRef.current = null;
872
- const changes = (0, selected_outline_drag_1.getSelectedOutlineDragChanges)({
873
- dragStates: session.dragStates,
874
- lastValues: session.lastValues,
875
- });
876
- if (changes.length === 0) {
877
- (0, selected_outline_drag_1.clearSelectedOutlineDragOverrides)({
878
- clearDragOverrides,
879
- dragStates: session.dragStates,
880
- });
881
- return;
882
- }
883
- const staticChanges = changes.filter((change) => change.type === 'static');
884
- const keyframedChanges = changes.filter((change) => change.type === 'keyframed');
885
- Promise.all([
886
- staticChanges.length > 0
887
- ? (0, save_sequence_prop_1.saveSequenceProps)({
888
- changes: staticChanges,
889
- addedKeyframes: null,
890
- movedKeyframes: null,
891
- setPropStatuses,
892
- clientId: session.clientId,
893
- undoLabel: changes.length > 1 ? 'Move selected sequences' : 'Move sequence',
894
- redoLabel: changes.length > 1
895
- ? 'Move selected sequences back'
896
- : 'Move sequence back',
897
- })
898
- : Promise.resolve(),
899
- (0, call_add_keyframe_1.callAddKeyframes)({
900
- sequenceKeyframes: keyframedChanges,
901
- effectKeyframes: [],
902
- setPropStatuses,
903
- clientId: session.clientId,
904
- }),
905
- ])
906
- .catch((err) => {
907
- (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
908
- })
909
- .finally(() => {
910
- (0, selected_outline_drag_1.clearSelectedOutlineDragOverrides)({
911
- clearDragOverrides,
912
- dragStates: session.dragStates,
913
- });
914
- });
915
- }, [clearDragOverrides, setPropStatuses]);
916
- (0, react_1.useEffect)(() => {
917
- saveKeyboardNudgeSessionRef.current = saveKeyboardNudgeSession;
918
- }, [saveKeyboardNudgeSession]);
919
- (0, react_1.useEffect)(() => {
920
- return () => {
921
- saveKeyboardNudgeSessionRef.current();
922
- };
923
- }, []);
924
- const seekWithArrowKey = (0, react_1.useCallback)((event, direction) => {
925
- if (direction === 'up' || direction === 'down') {
926
- return;
927
- }
928
- event.preventDefault();
929
- if (direction === 'left') {
930
- if (event.altKey) {
931
- seek(0);
932
- (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
933
- direction: 'fit-left',
934
- durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
935
- frame: 0,
936
- });
937
- }
938
- else if (event.shiftKey) {
939
- frameBack((0, imperative_state_1.getCurrentFps)());
940
- (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
941
- direction: 'fit-left',
942
- durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
943
- frame: Math.max(0, getCurrentFrame() - (0, imperative_state_1.getCurrentFps)()),
944
- });
945
- }
946
- else {
947
- frameBack(1);
948
- (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
949
- direction: 'fit-left',
950
- durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
951
- frame: Math.max(0, getCurrentFrame() - 1),
952
- });
953
- }
954
- return;
955
- }
956
- if (event.altKey) {
957
- seek((0, imperative_state_1.getCurrentDuration)() - 1);
958
- (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
959
- direction: 'fit-right',
960
- durationInFrames: (0, imperative_state_1.getCurrentDuration)() - 1,
961
- frame: (0, imperative_state_1.getCurrentDuration)() - 1,
962
- });
963
- }
964
- else if (event.shiftKey) {
965
- frameForward((0, imperative_state_1.getCurrentFps)());
966
- (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
967
- direction: 'fit-right',
968
- durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
969
- frame: Math.min((0, imperative_state_1.getCurrentDuration)() - 1, getCurrentFrame() + (0, imperative_state_1.getCurrentFps)()),
970
- });
971
- }
972
- else {
973
- frameForward(1);
974
- (0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
975
- direction: 'fit-right',
976
- durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
977
- frame: Math.min((0, imperative_state_1.getCurrentDuration)() - 1, getCurrentFrame() + 1),
978
- });
979
- }
980
- }, [frameBack, frameForward, getCurrentFrame, seek]);
981
- const onArrowKeyDown = (0, react_1.useCallback)((event) => {
982
- var _a;
983
- const direction = (0, selected_outline_drag_1.getSelectedOutlineKeyboardNudgeDirection)(event.key);
984
- if (direction === null) {
985
- return;
986
- }
987
- if (selectedItems.length === 0 || allDragTargets.length === 0) {
988
- seekWithArrowKey(event, direction);
989
- return;
990
- }
991
- if (event.altKey) {
992
- seekWithArrowKey(event, direction);
993
- return;
994
- }
995
- event.preventDefault();
996
- const activeSession = (_a = keyboardNudgeSessionRef.current) !== null && _a !== void 0 ? _a : (() => {
997
- const [firstDragTarget] = allDragTargets;
998
- if (firstDragTarget === undefined) {
999
- throw new Error('Expected a drag target');
1000
- }
1001
- return {
1002
- clientId: firstDragTarget.clientId,
1003
- deltaX: 0,
1004
- deltaY: 0,
1005
- dragStates: (0, selected_outline_drag_1.getSelectedOutlineDragStates)({
1006
- dragTargets: allDragTargets,
1007
- getDragOverrides,
1008
- timelinePosition,
1009
- }),
1010
- lastValues: new Map(),
1011
- };
1012
- })();
1013
- keyboardNudgeSessionRef.current = activeSession;
1014
- const nextDeltas = (0, selected_outline_drag_1.getSelectedOutlineKeyboardNudgeDeltas)({
1015
- deltaX: activeSession.deltaX,
1016
- deltaY: activeSession.deltaY,
1017
- direction,
1018
- shiftKey: event.shiftKey,
1019
- });
1020
- activeSession.deltaX = nextDeltas.deltaX;
1021
- activeSession.deltaY = nextDeltas.deltaY;
1022
- const lastValues = (0, selected_outline_drag_1.getSelectedOutlineDragValues)({
1023
- dragStates: activeSession.dragStates,
1024
- deltaX: activeSession.deltaX,
1025
- deltaY: activeSession.deltaY,
521
+ return (0, selected_outline_measurement_1.getSequencesWithSelectableOutlines)({
522
+ sequences,
523
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
524
+ compositions,
525
+ timelinePosition,
1026
526
  });
1027
- activeSession.lastValues = lastValues;
1028
- for (const dragState of activeSession.dragStates) {
1029
- const value = lastValues.get(dragState.key);
1030
- if (value === undefined) {
1031
- throw new Error('Expected drag value to be available');
1032
- }
1033
- if (dragState.target.propStatus.status === 'keyframed') {
1034
- setDragOverrides(dragState.target.nodePath, selected_outline_types_1.translateFieldKey, remotion_1.Internals.makeKeyframedDragOverride({
1035
- status: dragState.target.propStatus,
1036
- frame: dragState.sourceFrame,
1037
- value,
1038
- }));
1039
- }
1040
- else {
1041
- setDragOverrides(dragState.target.nodePath, selected_outline_types_1.translateFieldKey, remotion_1.Internals.makeStaticDragOverride(value));
1042
- }
1043
- }
1044
527
  }, [
1045
- allDragTargets,
528
+ compositions,
529
+ editorShowOutlines,
530
+ isFullscreen,
531
+ overrideIdToNodePathMappings,
532
+ previewSelectionAvailable,
533
+ sequences,
534
+ ]);
535
+ const calculateOutlineTargetsForCurrentState = (0, react_1.useCallback)((options) => calculateOutlineTargets({
536
+ ...options,
537
+ connectedClientId: previewServerState.type === 'connected'
538
+ ? previewServerState.clientId
539
+ : null,
540
+ editorShowOutlines,
1046
541
  getDragOverrides,
1047
- seekWithArrowKey,
1048
- selectedItems.length,
1049
- setDragOverrides,
1050
- timelinePosition,
542
+ getScaleLockState,
543
+ isFullscreen,
544
+ previewSelectionAvailable,
545
+ propStatuses,
546
+ selectedCropInfo,
547
+ selectedEffectsBySequenceKey,
548
+ selectedSequenceKeys,
549
+ selectedTransformOriginInfo,
550
+ sequenceKeysContainingSelection,
551
+ studioInteractivityEnabled: (0, interactivity_enabled_1.isStudioInteractivityEnabled)(),
552
+ }), [
553
+ editorShowOutlines,
554
+ getDragOverrides,
555
+ getScaleLockState,
556
+ isFullscreen,
557
+ previewSelectionAvailable,
558
+ previewServerState,
559
+ propStatuses,
560
+ selectedCropInfo,
561
+ selectedEffectsBySequenceKey,
562
+ selectedSequenceKeys,
563
+ selectedTransformOriginInfo,
564
+ sequenceKeysContainingSelection,
1051
565
  ]);
1052
- const onArrowKeyUp = (0, react_1.useCallback)((event) => {
1053
- const direction = (0, selected_outline_drag_1.getSelectedOutlineKeyboardNudgeDirection)(event.key);
1054
- if (direction === null || keyboardNudgeSessionRef.current === null) {
1055
- return;
1056
- }
1057
- event.preventDefault();
1058
- saveKeyboardNudgeSession();
1059
- }, [saveKeyboardNudgeSession]);
1060
- (0, react_1.useEffect)(() => {
1061
- const keyDownBindings = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].map((key) => keybindings.registerKeybinding({
1062
- event: 'keydown',
1063
- key,
1064
- callback: onArrowKeyDown,
1065
- commandCtrlKey: false,
1066
- preventDefault: false,
1067
- triggerIfInputFieldFocused: false,
1068
- keepRegisteredWhenNotHighestContext: false,
1069
- }));
1070
- const keyUpBindings = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].map((key) => keybindings.registerKeybinding({
1071
- event: 'keyup',
1072
- key,
1073
- callback: onArrowKeyUp,
1074
- commandCtrlKey: false,
1075
- preventDefault: false,
1076
- triggerIfInputFieldFocused: false,
1077
- keepRegisteredWhenNotHighestContext: false,
1078
- }));
1079
- return () => {
1080
- for (const binding of [...keyDownBindings, ...keyUpBindings]) {
1081
- binding.unregister();
1082
- }
566
+ const calculateOutlineTargetsRef = (0, react_1.useRef)(calculateOutlineTargetsForCurrentState);
567
+ const getSelectableOutlinesRef = (0, react_1.useRef)(getSelectableOutlines);
568
+ const selectableOutlinesCacheRef = (0, react_1.useRef)(null);
569
+ (0, react_1.useLayoutEffect)(() => {
570
+ calculateOutlineTargetsRef.current = calculateOutlineTargetsForCurrentState;
571
+ getSelectableOutlinesRef.current = getSelectableOutlines;
572
+ }, [calculateOutlineTargetsForCurrentState, getSelectableOutlines]);
573
+ const getSelectableOutlinesAtFrame = (0, react_1.useCallback)((timelinePosition) => {
574
+ const currentGetSelectableOutlines = getSelectableOutlinesRef.current;
575
+ const cached = selectableOutlinesCacheRef.current;
576
+ if ((cached === null || cached === void 0 ? void 0 : cached.timelinePosition) === timelinePosition &&
577
+ cached.getSelectableOutlines === currentGetSelectableOutlines) {
578
+ return cached.selectableOutlines;
579
+ }
580
+ const selectableOutlines = currentGetSelectableOutlines(timelinePosition);
581
+ selectableOutlinesCacheRef.current = {
582
+ getSelectableOutlines: currentGetSelectableOutlines,
583
+ selectableOutlines,
584
+ timelinePosition,
1083
585
  };
1084
- }, [keybindings, onArrowKeyDown, onArrowKeyUp, saveKeyboardNudgeSession]);
1085
- const updateOutlines = (0, react_1.useCallback)(() => {
1086
- if (overlayRef.current === null || outlineTargets.length === 0) {
1087
- setOutlines((prevOutlines) => prevOutlines.length === 0 ? prevOutlines : []);
1088
- return;
586
+ return selectableOutlines;
587
+ }, []);
588
+ const getLatestOutlineTargetByKey = (0, react_1.useCallback)((key) => {
589
+ const timelinePosition = getCurrentFrame();
590
+ const target = calculateOutlineTargetsRef.current({
591
+ mode: 'controls',
592
+ runtimeValuesByStore: new Map(),
593
+ selectableOutlines: getSelectableOutlinesAtFrame(timelinePosition),
594
+ targetKey: key,
595
+ targetTimelinePosition: timelinePosition,
596
+ })[0];
597
+ return target;
598
+ }, [getCurrentFrame, getSelectableOutlinesAtFrame]);
599
+ const getCurrentSelectableOutlines = (0, react_1.useCallback)(() => getSelectableOutlinesAtFrame(getCurrentFrame()), [getCurrentFrame, getSelectableOutlinesAtFrame]);
600
+ const onDraggingChange = (0, react_1.useCallback)((dragging) => {
601
+ setDraggingOutline(dragging);
602
+ if (dragging) {
603
+ setHoveredSequence((currentHover) => (currentHover === null || currentHover === void 0 ? void 0 : currentHover.source) === 'canvas' ? null : currentHover);
1089
604
  }
1090
- const nextOutlines = (0, selected_outline_measurement_1.measureOutlines)(overlayRef.current, outlineTargets);
1091
- setOutlines((prevOutlines) => (0, selected_outline_measurement_1.outlinesAreEqual)(prevOutlines, nextOutlines)
1092
- ? prevOutlines
1093
- : nextOutlines);
1094
- }, [outlineTargets]);
1095
- (0, react_1.useLayoutEffect)(() => {
1096
- updateOutlines();
1097
- }, [outlineTargets, scale, translationX, translationY, updateOutlines]);
605
+ }, [setHoveredSequence]);
606
+ const selectOutlineItem = (0, react_1.useCallback)((item, interaction) => {
607
+ selectItem(item, interaction, undefined, { reveal: true });
608
+ }, [selectItem]);
609
+ const measurementActive = canvasHovered || draggingOutline || (hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.source) === 'timeline';
1098
610
  (0, react_1.useLayoutEffect)(() => {
1099
- if (outlineTargets.length === 0 || typeof ResizeObserver === 'undefined') {
611
+ if (measurementActive) {
1100
612
  return;
1101
613
  }
1102
- let animationFrame = null;
1103
- const scheduleUpdate = () => {
1104
- if (animationFrame !== null) {
1105
- return;
1106
- }
1107
- animationFrame = requestAnimationFrame(() => {
1108
- animationFrame = null;
1109
- updateOutlines();
1110
- });
1111
- };
1112
- const resizeObserver = new ResizeObserver(scheduleUpdate);
1113
- if (overlayRef.current !== null) {
1114
- resizeObserver.observe(overlayRef.current);
1115
- }
1116
- for (const target of outlineTargets) {
1117
- if (target.ref.current !== null) {
1118
- resizeObserver.observe(target.ref.current);
1119
- }
1120
- }
1121
- return () => {
1122
- if (animationFrame !== null) {
1123
- cancelAnimationFrame(animationFrame);
1124
- }
1125
- resizeObserver.disconnect();
1126
- };
1127
- }, [outlineTargets, updateOutlines]);
1128
- if (outlineTargets.length === 0) {
1129
- return null;
1130
- }
1131
- return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [
1132
- jsx_runtime_1.jsx(SelectedOutlineSnapIndicators, { activeSnapPoints: activeSnapPoints, compositionHeight: compositionHeight, compositionWidth: compositionWidth, scale: scale }), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineElement, { allDragTargets: allDragTargets, allDragOutlines: allDragOutlines, allRotationDragTargets: allRotationDragTargets, allScaleDragTargets: allScaleDragTargets, dragging: draggingOutline, hovered: (hoveredSequence === null || hoveredSequence === void 0 ? void 0 : hoveredSequence.key) === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSnapPointsChange: onSnapPointsChange, onSelect: selectOutlineItem, scale: scale, snapTargets: snapTargets, target: targetsByKey.get(outline.key) }, outline.key))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineTransformOriginHandle, { outline: outline, onDraggingChange: onDraggingChange, target: targetsByKey.get(outline.key) }, `${outline.key}-transform-origin`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleConnectionLayer, { outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-connection-lines`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleCircleLayer, { onDraggingChange: onDraggingChange, onSelect: selectOutlineItem, outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-handles`)))] }));
614
+ setHoveredSequence((currentHover) => (currentHover === null || currentHover === void 0 ? void 0 : currentHover.source) === 'canvas' ? null : currentHover);
615
+ }, [measurementActive, setHoveredSequence]);
616
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
617
+ jsx_runtime_1.jsx(SelectedOutlineKeyboardControls_1.SelectedOutlineKeyboardControls, { getLatestOutlineTargetByKey: getLatestOutlineTargetByKey, getSelectableOutlines: getCurrentSelectableOutlines }), measurementActive ? (jsx_runtime_1.jsx(ActiveSelectedOutlineOverlay, { calculateOutlineTargetsForCurrentState: calculateOutlineTargetsForCurrentState, compositionHeight: compositionHeight, compositionWidth: compositionWidth, draggingOutline: draggingOutline, getLatestOutlineTargetByKey: getLatestOutlineTargetByKey, getSelectableOutlines: getSelectableOutlines, onDraggingChange: onDraggingChange, onSelect: selectOutlineItem, scale: scale, selectedSequenceKeys: selectedSequenceKeys, sequenceKeysContainingSelection: sequenceKeysContainingSelection, sequences: sequences, translationX: translationX, translationY: translationY })) : null] }));
1133
618
  };
1134
- exports.SelectedOutlineOverlay = SelectedOutlineOverlay;
619
+ exports.SelectedOutlineOverlay = react_1.default.memo(SelectedOutlineOverlayUnmemoized);