@remotion/studio 4.0.470 → 4.0.472

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 (112) hide show
  1. package/dist/components/AssetSelector.js +10 -1
  2. package/dist/components/Canvas.js +98 -0
  3. package/dist/components/CompositionSelectorItem.d.ts +1 -0
  4. package/dist/components/CompositionSelectorItem.js +12 -4
  5. package/dist/components/ContextMenu.d.ts +7 -2
  6. package/dist/components/ContextMenu.js +91 -43
  7. package/dist/components/Editor.js +14 -6
  8. package/dist/components/Modals.js +3 -1
  9. package/dist/components/NewComposition/CodemodFooter.js +2 -2
  10. package/dist/components/NewComposition/DeleteFolder.d.ts +6 -0
  11. package/dist/components/NewComposition/DeleteFolder.js +39 -0
  12. package/dist/components/NewComposition/RenameFolder.d.ts +6 -0
  13. package/dist/components/NewComposition/RenameFolder.js +60 -0
  14. package/dist/components/Preview.js +2 -1
  15. package/dist/components/SelectedOutlineOverlay.d.ts +109 -1
  16. package/dist/components/SelectedOutlineOverlay.js +489 -73
  17. package/dist/components/Splitter/SplitterContainer.js +9 -0
  18. package/dist/components/Splitter/SplitterHandle.js +63 -70
  19. package/dist/components/Timeline/Timeline.js +121 -1
  20. package/dist/components/Timeline/TimelineArrayField.d.ts +9 -0
  21. package/dist/components/Timeline/TimelineArrayField.js +210 -0
  22. package/dist/components/Timeline/TimelineBooleanField.d.ts +2 -2
  23. package/dist/components/Timeline/TimelineBooleanField.js +2 -2
  24. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +20 -0
  25. package/dist/components/Timeline/TimelineClipboardKeybindings.js +265 -0
  26. package/dist/components/Timeline/TimelineColorField.d.ts +2 -2
  27. package/dist/components/Timeline/TimelineColorField.js +2 -8
  28. package/dist/components/Timeline/TimelineDeleteKeybindings.js +15 -0
  29. package/dist/components/Timeline/TimelineDragHandler.js +1 -0
  30. package/dist/components/Timeline/TimelineEffectItem.js +159 -6
  31. package/dist/components/Timeline/TimelineEffectPropItem.js +95 -25
  32. package/dist/components/Timeline/TimelineEnumField.d.ts +2 -2
  33. package/dist/components/Timeline/TimelineEnumField.js +3 -3
  34. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +4 -3
  35. package/dist/components/Timeline/TimelineKeyframeControls.js +52 -33
  36. package/dist/components/Timeline/TimelineKeyframedValue.d.ts +7 -2
  37. package/dist/components/Timeline/TimelineKeyframedValue.js +22 -8
  38. package/dist/components/Timeline/TimelineLayerEye.d.ts +1 -0
  39. package/dist/components/Timeline/TimelineLayerEye.js +8 -3
  40. package/dist/components/Timeline/TimelineNumberField.d.ts +2 -2
  41. package/dist/components/Timeline/TimelineNumberField.js +7 -11
  42. package/dist/components/Timeline/TimelinePrimitiveFieldValue.d.ts +17 -0
  43. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +53 -0
  44. package/dist/components/Timeline/TimelineRotationField.d.ts +2 -2
  45. package/dist/components/Timeline/TimelineRotationField.js +41 -24
  46. package/dist/components/Timeline/TimelineRowChrome.d.ts +3 -0
  47. package/dist/components/Timeline/TimelineRowChrome.js +11 -10
  48. package/dist/components/Timeline/TimelineScaleField.d.ts +20 -0
  49. package/dist/components/Timeline/TimelineScaleField.js +314 -0
  50. package/dist/components/Timeline/TimelineSchemaField.d.ts +3 -2
  51. package/dist/components/Timeline/TimelineSchemaField.js +8 -42
  52. package/dist/components/Timeline/TimelineSelection.js +3 -2
  53. package/dist/components/Timeline/TimelineSequence.d.ts +1 -0
  54. package/dist/components/Timeline/TimelineSequence.js +51 -10
  55. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  56. package/dist/components/Timeline/TimelineSequenceItem.js +97 -7
  57. package/dist/components/Timeline/TimelineSequencePropItem.js +82 -21
  58. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +58 -0
  59. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +528 -0
  60. package/dist/components/Timeline/TimelineTrack.js +1 -1
  61. package/dist/components/Timeline/TimelineTranslateField.d.ts +2 -2
  62. package/dist/components/Timeline/TimelineTranslateField.js +21 -25
  63. package/dist/components/Timeline/TimelineUvCoordinateField.d.ts +2 -2
  64. package/dist/components/Timeline/TimelineUvCoordinateField.js +20 -26
  65. package/dist/components/Timeline/call-add-keyframe.js +2 -0
  66. package/dist/components/Timeline/call-delete-keyframe.d.ts +16 -0
  67. package/dist/components/Timeline/call-delete-keyframe.js +86 -14
  68. package/dist/components/Timeline/delete-selected-keyframe.d.ts +10 -0
  69. package/dist/components/Timeline/delete-selected-keyframe.js +48 -7
  70. package/dist/components/Timeline/delete-selected-timeline-item.js +6 -11
  71. package/dist/components/Timeline/get-node-keyframes.d.ts +5 -2
  72. package/dist/components/Timeline/get-node-keyframes.js +38 -5
  73. package/dist/components/Timeline/get-timeline-keyframes.js +4 -4
  74. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +38 -0
  75. package/dist/components/Timeline/reset-selected-timeline-props.js +156 -0
  76. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +3 -2
  77. package/dist/components/Timeline/sequence-props-subscription-store.js +2 -1
  78. package/dist/components/Timeline/timeline-field-utils.d.ts +1 -0
  79. package/dist/components/Timeline/timeline-field-utils.js +5 -1
  80. package/dist/components/Timeline/timeline-scroll-logic.js +3 -3
  81. package/dist/components/Timeline/timeline-translate-utils.js +6 -2
  82. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +7 -0
  83. package/dist/components/Timeline/use-sequence-props-subscription.js +2 -1
  84. package/dist/components/TopPanel.d.ts +1 -1
  85. package/dist/components/folder-menu-items.d.ts +12 -0
  86. package/dist/components/folder-menu-items.js +147 -0
  87. package/dist/components/import-assets.d.ts +6 -0
  88. package/dist/components/import-assets.js +157 -0
  89. package/dist/esm/{chunk-dny42qnq.js → chunk-48grt472.js} +9717 -5925
  90. package/dist/esm/internals.mjs +9717 -5925
  91. package/dist/esm/previewEntry.mjs +9531 -5737
  92. package/dist/esm/renderEntry.mjs +1 -1
  93. package/dist/helpers/calculate-timeline.js +7 -3
  94. package/dist/helpers/create-folder-tree.js +1 -0
  95. package/dist/helpers/detect-file-type.d.ts +69 -0
  96. package/dist/helpers/detect-file-type.js +278 -0
  97. package/dist/helpers/get-folder-id.d.ts +4 -0
  98. package/dist/helpers/get-folder-id.js +7 -0
  99. package/dist/helpers/get-left-of-timeline-slider.js +1 -1
  100. package/dist/helpers/get-timeline-sequence-layout.js +10 -11
  101. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -0
  102. package/dist/helpers/open-in-editor.d.ts +19 -1
  103. package/dist/helpers/open-in-editor.js +42 -4
  104. package/dist/helpers/timeline-layout.js +5 -1
  105. package/dist/helpers/use-menu-structure.js +0 -1
  106. package/dist/helpers/validate-folder-rename.d.ts +6 -0
  107. package/dist/helpers/validate-folder-rename.js +19 -0
  108. package/dist/state/modals.d.ts +10 -0
  109. package/dist/state/scale-lock.d.ts +18 -0
  110. package/dist/state/scale-lock.js +59 -0
  111. package/dist/state/z-index.js +5 -2
  112. package/package.json +10 -10
@@ -33,20 +33,26 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.SelectedOutlineOverlay = exports.getSelectedEffectFieldsBySequenceKey = exports.getUvCoordinateForPoint = exports.getUvHandlePosition = void 0;
36
+ exports.SelectedOutlineOverlay = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineDragValues = exports.getSequencesWithSelectableOutlines = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.getUvCoordinateForPoint = exports.getUvHandlePosition = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
40
+ const no_react_1 = require("remotion/no-react");
40
41
  const calculate_timeline_1 = require("../helpers/calculate-timeline");
41
42
  const client_id_1 = require("../helpers/client-id");
42
43
  const colors_1 = require("../helpers/colors");
43
44
  const get_box_quads_ponyfill_1 = require("../helpers/get-box-quads-ponyfill");
45
+ const scale_lock_1 = require("../state/scale-lock");
46
+ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
47
+ const call_add_keyframe_1 = require("./Timeline/call-add-keyframe");
44
48
  const save_effect_prop_1 = require("./Timeline/save-effect-prop");
45
49
  const save_sequence_prop_1 = require("./Timeline/save-sequence-prop");
46
50
  const timeline_field_utils_1 = require("./Timeline/timeline-field-utils");
47
51
  const timeline_translate_utils_1 = require("./Timeline/timeline-translate-utils");
52
+ const TimelineScaleField_1 = require("./Timeline/TimelineScaleField");
48
53
  const TimelineSelection_1 = require("./Timeline/TimelineSelection");
49
54
  const translateFieldKey = 'style.translate';
55
+ const scaleFieldKey = 'style.scale';
50
56
  const outlineContainer = {
51
57
  position: 'absolute',
52
58
  inset: 0,
@@ -77,6 +83,15 @@ const mixPoint = (from, to, progress) => {
77
83
  y: mix(from.y, to.y, progress),
78
84
  };
79
85
  };
86
+ const midpoint = (from, to) => {
87
+ return mixPoint(from, to, 0.5);
88
+ };
89
+ const dot = (left, right) => {
90
+ return left.x * right.x + left.y * right.y;
91
+ };
92
+ const vectorLength = (vector) => {
93
+ return Math.hypot(vector.x, vector.y);
94
+ };
80
95
  const getBilinearUvHandlePosition = (points, uv) => {
81
96
  const [tl, tr, br, bl] = points;
82
97
  const top = mixPoint(tl, tr, uv[0]);
@@ -248,6 +263,11 @@ const getElementOutlinePoints = (element, containerRect) => {
248
263
  const getSelectedSequenceKeys = (selectedItems) => {
249
264
  return new Set(selectedItems.map((item) => (0, TimelineSelection_1.getTimelineSequenceSelectionKey)(item.nodePathInfo)));
250
265
  };
266
+ const getOutlineSelectionInteraction = ({ shiftKey, metaKey, ctrlKey, }) => ({
267
+ shiftKey,
268
+ toggleKey: metaKey || ctrlKey,
269
+ });
270
+ exports.getOutlineSelectionInteraction = getOutlineSelectionInteraction;
251
271
  const getSelectedEffectFieldsBySequenceKey = (selectedItems) => {
252
272
  var _a, _b;
253
273
  const selectedEffects = new Map();
@@ -269,11 +289,7 @@ const getSelectedEffectFieldsBySequenceKey = (selectedItems) => {
269
289
  return selectedEffects;
270
290
  };
271
291
  exports.getSelectedEffectFieldsBySequenceKey = getSelectedEffectFieldsBySequenceKey;
272
- const getSequencesWithSelectedOutlines = ({ selectedItems, sequences, overrideIdsToNodePaths, }) => {
273
- const selectedSequenceKeys = getSelectedSequenceKeys(selectedItems);
274
- if (selectedSequenceKeys.size === 0) {
275
- return [];
276
- }
292
+ const getSequencesWithSelectableOutlines = ({ sequences, overrideIdsToNodePaths, }) => {
277
293
  return (0, calculate_timeline_1.calculateTimeline)({
278
294
  sequences: [...sequences],
279
295
  overrideIdsToNodePaths,
@@ -282,20 +298,24 @@ const getSequencesWithSelectedOutlines = ({ selectedItems, sequences, overrideId
282
298
  if (track.nodePathInfo === null) {
283
299
  return false;
284
300
  }
285
- return selectedSequenceKeys.has((0, TimelineSelection_1.getTimelineSequenceSelectionKey)(track.nodePathInfo));
301
+ return track.nodePathInfo.auxiliaryKeys.length === 0;
286
302
  })
287
303
  .filter((track) => track.sequence.refForOutline !== null)
304
+ .sort((a, b) => a.depth - b.depth)
288
305
  .map((track) => {
289
306
  if (track.nodePathInfo === null) {
290
307
  throw new Error('Expected selected outline to have a node path');
291
308
  }
292
309
  return {
310
+ depth: track.depth,
311
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
293
312
  key: (0, TimelineSelection_1.getTimelineSequenceSelectionKey)(track.nodePathInfo),
294
313
  nodePathInfo: track.nodePathInfo,
295
314
  sequence: track.sequence,
296
315
  };
297
316
  });
298
317
  };
318
+ exports.getSequencesWithSelectableOutlines = getSequencesWithSelectableOutlines;
299
319
  const getSelectedUvHandles = ({ codeValues, clientId, getEffectDragOverrides, nodePath, selectedEffects, sequence, }) => {
300
320
  if (clientId === null || selectedEffects === undefined) {
301
321
  return [];
@@ -316,12 +336,12 @@ const getSelectedUvHandles = ({ codeValues, clientId, getEffectDragOverrides, no
316
336
  }
317
337
  const dragOverrides = getEffectDragOverrides(nodePath, effectIndex);
318
338
  const activeSchema = remotion_1.Internals.flattenActiveSchema(effect.schema, (key) => {
319
- const dragOverride = dragOverrides[key];
339
+ const dragOverride = remotion_1.Internals.getStaticDragOverrideValue(dragOverrides[key]);
320
340
  if (dragOverride !== undefined) {
321
341
  return dragOverride;
322
342
  }
323
343
  const propStatus = effectStatus.props[key];
324
- if (!(propStatus === null || propStatus === void 0 ? void 0 : propStatus.canUpdate)) {
344
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) !== 'static') {
325
345
  return undefined;
326
346
  }
327
347
  return propStatus.codeValue;
@@ -332,7 +352,7 @@ const getSelectedUvHandles = ({ codeValues, clientId, getEffectDragOverrides, no
332
352
  continue;
333
353
  }
334
354
  const propStatus = effectStatus.props[fieldKey];
335
- if (!(propStatus === null || propStatus === void 0 ? void 0 : propStatus.canUpdate)) {
355
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) !== 'static') {
336
356
  continue;
337
357
  }
338
358
  const dragOverrideValue = dragOverrides[fieldKey];
@@ -394,78 +414,410 @@ const outlinesAreEqual = (a, b) => {
394
414
  }
395
415
  return true;
396
416
  };
397
- const SelectedOutlinePolygon = ({ outline, scale, target }) => {
398
- var _a;
417
+ const getSelectedOutlineDragStates = ({ dragTargets, getDragOverrides, timelinePosition, }) => {
418
+ return dragTargets.map((target) => {
419
+ var _a;
420
+ const dragOverrideValue = ((_a = getDragOverrides(target.nodePath)) !== null && _a !== void 0 ? _a : {})[translateFieldKey];
421
+ const sourceFrame = timelinePosition - target.keyframeDisplayOffset;
422
+ const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
423
+ codeValue: target.codeValue,
424
+ dragOverrideValue,
425
+ defaultValue: target.fieldDefault,
426
+ frame: sourceFrame,
427
+ shouldResortToDefaultValueIfUndefined: true,
428
+ });
429
+ const [startX, startY] = (0, timeline_translate_utils_1.parseTranslate)(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px'));
430
+ return {
431
+ defaultValue: target.fieldDefault !== undefined
432
+ ? JSON.stringify(target.fieldDefault)
433
+ : null,
434
+ key: remotion_1.Internals.makeSequencePropsSubscriptionKey(target.nodePath),
435
+ sourceFrame,
436
+ startX,
437
+ startY,
438
+ target,
439
+ };
440
+ });
441
+ };
442
+ const getSelectedOutlineDragValues = ({ dragStates, deltaX, deltaY, }) => {
443
+ return new Map(dragStates.map((dragState) => [
444
+ dragState.key,
445
+ (0, timeline_translate_utils_1.serializeTranslate)(dragState.startX + deltaX, dragState.startY + deltaY),
446
+ ]));
447
+ };
448
+ exports.getSelectedOutlineDragValues = getSelectedOutlineDragValues;
449
+ const getSelectedOutlineDragChanges = ({ dragStates, lastValues, }) => {
450
+ const changes = [];
451
+ for (const dragState of dragStates) {
452
+ const value = lastValues.get(dragState.key);
453
+ if (value === undefined) {
454
+ continue;
455
+ }
456
+ if (dragState.target.codeValue.status === 'keyframed') {
457
+ const startValue = (0, timeline_translate_utils_1.serializeTranslate)(dragState.startX, dragState.startY);
458
+ if (value === startValue) {
459
+ continue;
460
+ }
461
+ changes.push({
462
+ type: 'keyframed',
463
+ fileName: dragState.target.nodePath.absolutePath,
464
+ nodePath: dragState.target.nodePath,
465
+ fieldKey: translateFieldKey,
466
+ sourceFrame: dragState.sourceFrame,
467
+ value,
468
+ schema: dragState.target.schema,
469
+ clientId: dragState.target.clientId,
470
+ });
471
+ continue;
472
+ }
473
+ const stringifiedValue = JSON.stringify(value);
474
+ const shouldSave = value !== dragState.target.codeValue.codeValue &&
475
+ !(dragState.defaultValue === stringifiedValue &&
476
+ dragState.target.codeValue.codeValue === undefined);
477
+ if (!shouldSave) {
478
+ continue;
479
+ }
480
+ changes.push({
481
+ type: 'static',
482
+ fileName: dragState.target.nodePath.absolutePath,
483
+ nodePath: dragState.target.nodePath,
484
+ fieldKey: translateFieldKey,
485
+ value,
486
+ defaultValue: dragState.defaultValue,
487
+ schema: dragState.target.schema,
488
+ });
489
+ }
490
+ return changes;
491
+ };
492
+ exports.getSelectedOutlineDragChanges = getSelectedOutlineDragChanges;
493
+ const getSelectedOutlineScaleEdgeInfo = (points, edge) => {
494
+ const [tl, tr, br, bl] = points;
495
+ const edgePoints = {
496
+ top: { start: tl, end: tr, oppositeStart: bl, oppositeEnd: br },
497
+ right: { start: tr, end: br, oppositeStart: tl, oppositeEnd: bl },
498
+ bottom: { start: bl, end: br, oppositeStart: tl, oppositeEnd: tr },
499
+ left: { start: tl, end: bl, oppositeStart: tr, oppositeEnd: br },
500
+ }[edge];
501
+ const edgeMidpoint = midpoint(edgePoints.start, edgePoints.end);
502
+ const oppositeMidpoint = midpoint(edgePoints.oppositeStart, edgePoints.oppositeEnd);
503
+ const outward = vectorBetween(oppositeMidpoint, edgeMidpoint);
504
+ const length = vectorLength(outward);
505
+ if (length < 0.001) {
506
+ return null;
507
+ }
508
+ return {
509
+ axis: edge === 'left' || edge === 'right' ? 'x' : 'y',
510
+ cursor: edge === 'left' || edge === 'right' ? 'ew-resize' : 'ns-resize',
511
+ end: edgePoints.end,
512
+ extent: length,
513
+ normal: { x: outward.x / length, y: outward.y / length },
514
+ start: edgePoints.start,
515
+ };
516
+ };
517
+ exports.getSelectedOutlineScaleEdgeInfo = getSelectedOutlineScaleEdgeInfo;
518
+ const getSelectedOutlineScaleDragStates = ({ dragTargets, getDragOverrides, }) => {
519
+ return dragTargets.map((target) => {
520
+ var _a;
521
+ const dragOverrideValue = ((_a = getDragOverrides(target.nodePath)) !== null && _a !== void 0 ? _a : {})[scaleFieldKey];
522
+ const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
523
+ codeValue: target.codeValue,
524
+ dragOverrideValue,
525
+ defaultValue: target.fieldDefault,
526
+ shouldResortToDefaultValueIfUndefined: true,
527
+ });
528
+ const [startX, startY, startZ] = no_react_1.NoReactInternals.parseScaleValue(effectiveValue);
529
+ return {
530
+ defaultValue: target.fieldDefault !== undefined
531
+ ? JSON.stringify(target.fieldDefault)
532
+ : null,
533
+ key: remotion_1.Internals.makeSequencePropsSubscriptionKey(target.nodePath),
534
+ startX,
535
+ startY,
536
+ startZ,
537
+ target,
538
+ };
539
+ });
540
+ };
541
+ exports.getSelectedOutlineScaleDragStates = getSelectedOutlineScaleDragStates;
542
+ const getSelectedOutlineScaleDragValues = ({ axis, dragStates, scaleFactor, }) => {
543
+ return new Map(dragStates.map((dragState) => {
544
+ var _a, _b;
545
+ const min = (_a = dragState.target.fieldSchema.min) !== null && _a !== void 0 ? _a : -Infinity;
546
+ const max = (_b = dragState.target.fieldSchema.max) !== null && _b !== void 0 ? _b : Infinity;
547
+ const baseX = dragState.startX;
548
+ const baseY = dragState.startY;
549
+ const newValue = (axis === 'x' ? baseX : baseY) * scaleFactor;
550
+ const [x, y] = dragState.target.linked
551
+ ? (0, TimelineScaleField_1.getLinkedScale)({
552
+ axis,
553
+ newValue,
554
+ baseX,
555
+ baseY,
556
+ min,
557
+ max,
558
+ })
559
+ : axis === 'x'
560
+ ? [clamp(newValue, min, max), baseY]
561
+ : [baseX, clamp(newValue, min, max)];
562
+ return [
563
+ dragState.key,
564
+ no_react_1.NoReactInternals.serializeScaleValue([x, y, dragState.startZ]),
565
+ ];
566
+ }));
567
+ };
568
+ exports.getSelectedOutlineScaleDragValues = getSelectedOutlineScaleDragValues;
569
+ const getSelectedOutlineScaleDragChanges = ({ dragStates, lastValues, }) => {
570
+ return dragStates.flatMap((dragState) => {
571
+ const value = lastValues.get(dragState.key);
572
+ if (value === undefined) {
573
+ return [];
574
+ }
575
+ const stringifiedValue = JSON.stringify(value);
576
+ const shouldSave = stringifiedValue !==
577
+ JSON.stringify(dragState.target.codeValue.codeValue) &&
578
+ !(dragState.defaultValue === stringifiedValue &&
579
+ dragState.target.codeValue.codeValue === undefined);
580
+ if (!shouldSave) {
581
+ return [];
582
+ }
583
+ return [
584
+ {
585
+ fileName: dragState.target.nodePath.absolutePath,
586
+ nodePath: dragState.target.nodePath,
587
+ fieldKey: scaleFieldKey,
588
+ value,
589
+ defaultValue: dragState.defaultValue,
590
+ schema: dragState.target.schema,
591
+ },
592
+ ];
593
+ });
594
+ };
595
+ exports.getSelectedOutlineScaleDragChanges = getSelectedOutlineScaleDragChanges;
596
+ const clearSelectedOutlineDragOverrides = ({ clearDragOverrides, dragStates, }) => {
597
+ for (const dragState of dragStates) {
598
+ clearDragOverrides(dragState.target.nodePath);
599
+ }
600
+ };
601
+ const clearSelectedOutlineScaleDragOverrides = ({ clearDragOverrides, dragStates, }) => {
602
+ for (const dragState of dragStates) {
603
+ clearDragOverrides(dragState.target.nodePath);
604
+ }
605
+ };
606
+ const SelectedOutlinePolygon = ({ allDragTargets, hovered, outline, onHoverChange, onSelect, scale, target, }) => {
607
+ var _a, _b;
399
608
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
400
609
  const { setCodeValues, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
610
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
611
+ const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
612
+ timelinePositionRef.current = timelinePosition;
401
613
  const points = (0, react_1.useMemo)(() => outline.points.map(pointToString).join(' '), [outline.points]);
402
614
  const drag = (_a = target === null || target === void 0 ? void 0 : target.drag) !== null && _a !== void 0 ? _a : null;
615
+ const selected = (_b = target === null || target === void 0 ? void 0 : target.selected) !== null && _b !== void 0 ? _b : false;
616
+ const visible = selected || hovered;
403
617
  const onPointerDown = react_1.default.useCallback((event) => {
404
- var _a;
405
- if (event.button !== 0 || drag === null) {
618
+ if (event.button !== 0 || target === undefined) {
406
619
  return;
407
620
  }
408
621
  event.preventDefault();
409
622
  event.stopPropagation();
623
+ const interaction = (0, exports.getOutlineSelectionInteraction)(event);
624
+ const shouldUpdateSelection = !selected || interaction.shiftKey || interaction.toggleKey;
625
+ if (shouldUpdateSelection) {
626
+ onSelect(target.selection, interaction);
627
+ }
628
+ if (drag === null || interaction.shiftKey || interaction.toggleKey) {
629
+ return;
630
+ }
410
631
  const startPointerX = event.clientX;
411
632
  const startPointerY = event.clientY;
412
- const dragOverrideValue = ((_a = getDragOverrides(drag.nodePath)) !== null && _a !== void 0 ? _a : {})[translateFieldKey];
413
- const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
414
- codeValue: drag.codeValue,
415
- dragOverrideValue,
416
- defaultValue: drag.fieldDefault,
417
- shouldResortToDefaultValueIfUndefined: true,
633
+ const dragStates = getSelectedOutlineDragStates({
634
+ dragTargets: selected ? allDragTargets : [drag],
635
+ getDragOverrides,
636
+ timelinePosition: timelinePositionRef.current,
418
637
  });
419
- const [startX, startY] = (0, timeline_translate_utils_1.parseTranslate)(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px'));
420
- const defaultValue = drag.fieldDefault !== undefined
421
- ? JSON.stringify(drag.fieldDefault)
422
- : null;
423
- let lastValue = null;
638
+ let lastValues = new Map();
424
639
  const onPointerMove = (moveEvent) => {
425
640
  moveEvent.preventDefault();
426
- const nextX = startX + (moveEvent.clientX - startPointerX) / scale;
427
- const nextY = startY + (moveEvent.clientY - startPointerY) / scale;
428
- lastValue = (0, timeline_translate_utils_1.serializeTranslate)(nextX, nextY);
429
- setDragOverrides(drag.nodePath, translateFieldKey, lastValue);
641
+ lastValues = (0, exports.getSelectedOutlineDragValues)({
642
+ dragStates,
643
+ deltaX: (moveEvent.clientX - startPointerX) / scale,
644
+ deltaY: (moveEvent.clientY - startPointerY) / scale,
645
+ });
646
+ for (const dragState of dragStates) {
647
+ const value = lastValues.get(dragState.key);
648
+ if (value === undefined) {
649
+ throw new Error('Expected drag value to be available');
650
+ }
651
+ if (dragState.target.codeValue.status === 'keyframed') {
652
+ setDragOverrides(dragState.target.nodePath, translateFieldKey, remotion_1.Internals.makeKeyframedDragOverride({
653
+ status: dragState.target.codeValue,
654
+ frame: dragState.sourceFrame,
655
+ value,
656
+ }));
657
+ }
658
+ else {
659
+ setDragOverrides(dragState.target.nodePath, translateFieldKey, remotion_1.Internals.makeStaticDragOverride(value));
660
+ }
661
+ }
430
662
  };
431
663
  const onPointerUp = () => {
432
664
  window.removeEventListener('pointermove', onPointerMove);
433
665
  window.removeEventListener('pointerup', onPointerUp);
434
666
  window.removeEventListener('pointercancel', onPointerUp);
435
- const stringifiedValue = lastValue === null ? null : JSON.stringify(lastValue);
436
- const shouldSave = lastValue !== null &&
437
- lastValue !== drag.codeValue.codeValue &&
438
- !(defaultValue === stringifiedValue &&
439
- drag.codeValue.codeValue === undefined);
440
- if (!shouldSave) {
441
- clearDragOverrides(drag.nodePath);
667
+ const changes = (0, exports.getSelectedOutlineDragChanges)({
668
+ dragStates,
669
+ lastValues,
670
+ });
671
+ if (changes.length === 0) {
672
+ clearSelectedOutlineDragOverrides({ clearDragOverrides, dragStates });
442
673
  return;
443
674
  }
444
- (0, save_sequence_prop_1.saveSequenceProp)({
445
- fileName: drag.nodePath.absolutePath,
446
- nodePath: drag.nodePath,
447
- fieldKey: translateFieldKey,
448
- value: lastValue,
449
- defaultValue,
450
- schema: drag.schema,
451
- setCodeValues,
452
- clientId: drag.clientId,
453
- }).finally(() => {
454
- clearDragOverrides(drag.nodePath);
675
+ const staticChanges = changes.filter((change) => change.type === 'static');
676
+ const keyframedChanges = changes.filter((change) => change.type === 'keyframed');
677
+ Promise.all([
678
+ staticChanges.length > 0
679
+ ? (0, save_sequence_prop_1.saveSequenceProps)({
680
+ changes: staticChanges,
681
+ setCodeValues,
682
+ clientId: drag.clientId,
683
+ undoLabel: changes.length > 1 ? 'Move selected sequences' : null,
684
+ redoLabel: changes.length > 1 ? 'Move selected sequences back' : null,
685
+ })
686
+ : Promise.resolve(),
687
+ ...keyframedChanges.map((change) => (0, call_add_keyframe_1.callAddSequenceKeyframe)({
688
+ fileName: change.fileName,
689
+ nodePath: change.nodePath,
690
+ fieldKey: change.fieldKey,
691
+ sourceFrame: change.sourceFrame,
692
+ value: change.value,
693
+ schema: change.schema,
694
+ setCodeValues,
695
+ clientId: change.clientId,
696
+ })),
697
+ ])
698
+ .catch((err) => {
699
+ (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
700
+ })
701
+ .finally(() => {
702
+ clearSelectedOutlineDragOverrides({ clearDragOverrides, dragStates });
455
703
  });
456
704
  };
457
705
  window.addEventListener('pointermove', onPointerMove);
458
706
  window.addEventListener('pointerup', onPointerUp);
459
707
  window.addEventListener('pointercancel', onPointerUp);
460
708
  }, [
709
+ allDragTargets,
461
710
  clearDragOverrides,
462
711
  drag,
463
712
  getDragOverrides,
713
+ onSelect,
464
714
  scale,
715
+ selected,
716
+ setCodeValues,
717
+ setDragOverrides,
718
+ target,
719
+ ]);
720
+ return (jsx_runtime_1.jsx("polygon", { points: points, fill: "transparent", stroke: colors_1.BLUE, strokeOpacity: visible ? 1 : 0, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: target === undefined ? undefined : 'all', onPointerEnter: () => onHoverChange(outline.key), onPointerLeave: () => onHoverChange(null), onPointerDown: onPointerDown }));
721
+ };
722
+ const SelectedOutlineScaleEdgeLine = ({ allScaleDragTargets, edge, outline, onHoverChange, onSelect, target, }) => {
723
+ var _a, _b;
724
+ const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
725
+ const { setCodeValues, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
726
+ const scaleDrag = (_a = target === null || target === void 0 ? void 0 : target.scaleDrag) !== null && _a !== void 0 ? _a : null;
727
+ const selected = (_b = target === null || target === void 0 ? void 0 : target.selected) !== null && _b !== void 0 ? _b : false;
728
+ const edgeInfo = (0, react_1.useMemo)(() => (0, exports.getSelectedOutlineScaleEdgeInfo)(outline.points, edge), [edge, outline.points]);
729
+ const onPointerDown = react_1.default.useCallback((event) => {
730
+ if (event.button !== 0 || scaleDrag === null || edgeInfo === null) {
731
+ return;
732
+ }
733
+ event.preventDefault();
734
+ event.stopPropagation();
735
+ const interaction = (0, exports.getOutlineSelectionInteraction)(event);
736
+ const shouldUpdateSelection = !selected || interaction.shiftKey || interaction.toggleKey;
737
+ if (shouldUpdateSelection && target !== undefined) {
738
+ onSelect(target.selection, interaction);
739
+ }
740
+ if (interaction.shiftKey || interaction.toggleKey) {
741
+ return;
742
+ }
743
+ const startPointer = { x: event.clientX, y: event.clientY };
744
+ const dragStates = (0, exports.getSelectedOutlineScaleDragStates)({
745
+ dragTargets: selected ? allScaleDragTargets : [scaleDrag],
746
+ getDragOverrides,
747
+ });
748
+ let lastValues = new Map();
749
+ const onPointerMove = (moveEvent) => {
750
+ moveEvent.preventDefault();
751
+ const delta = {
752
+ x: moveEvent.clientX - startPointer.x,
753
+ y: moveEvent.clientY - startPointer.y,
754
+ };
755
+ const projectedDelta = dot(delta, edgeInfo.normal);
756
+ const scaleFactor = Math.max(0.001, 1 + projectedDelta / edgeInfo.extent);
757
+ lastValues = (0, exports.getSelectedOutlineScaleDragValues)({
758
+ dragStates,
759
+ axis: edgeInfo.axis,
760
+ scaleFactor,
761
+ });
762
+ for (const dragState of dragStates) {
763
+ const value = lastValues.get(dragState.key);
764
+ if (value === undefined) {
765
+ throw new Error('Expected scale drag value to be available');
766
+ }
767
+ setDragOverrides(dragState.target.nodePath, scaleFieldKey, remotion_1.Internals.makeStaticDragOverride(value));
768
+ }
769
+ };
770
+ const onPointerUp = () => {
771
+ window.removeEventListener('pointermove', onPointerMove);
772
+ window.removeEventListener('pointerup', onPointerUp);
773
+ window.removeEventListener('pointercancel', onPointerUp);
774
+ const changes = (0, exports.getSelectedOutlineScaleDragChanges)({
775
+ dragStates,
776
+ lastValues,
777
+ });
778
+ if (changes.length === 0) {
779
+ clearSelectedOutlineScaleDragOverrides({
780
+ clearDragOverrides,
781
+ dragStates,
782
+ });
783
+ return;
784
+ }
785
+ (0, save_sequence_prop_1.saveSequenceProps)({
786
+ changes,
787
+ setCodeValues,
788
+ clientId: scaleDrag.clientId,
789
+ undoLabel: changes.length > 1 ? 'Scale selected sequences' : null,
790
+ redoLabel: changes.length > 1 ? 'Scale selected sequences back' : null,
791
+ })
792
+ .catch((err) => {
793
+ (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
794
+ })
795
+ .finally(() => {
796
+ clearSelectedOutlineScaleDragOverrides({
797
+ clearDragOverrides,
798
+ dragStates,
799
+ });
800
+ });
801
+ };
802
+ window.addEventListener('pointermove', onPointerMove);
803
+ window.addEventListener('pointerup', onPointerUp);
804
+ window.addEventListener('pointercancel', onPointerUp);
805
+ }, [
806
+ allScaleDragTargets,
807
+ clearDragOverrides,
808
+ edgeInfo,
809
+ getDragOverrides,
810
+ onSelect,
811
+ scaleDrag,
812
+ selected,
465
813
  setCodeValues,
466
814
  setDragOverrides,
815
+ target,
467
816
  ]);
468
- return (jsx_runtime_1.jsx("polygon", { points: points, fill: drag === null ? 'none' : 'transparent', stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: drag === null ? undefined : 'all', onPointerDown: drag === null ? undefined : onPointerDown }));
817
+ if (scaleDrag === null || edgeInfo === null) {
818
+ return null;
819
+ }
820
+ return (jsx_runtime_1.jsx("line", { x1: edgeInfo.start.x, y1: edgeInfo.start.y, x2: edgeInfo.end.x, y2: edgeInfo.end.y, stroke: "transparent", strokeWidth: 12, vectorEffect: "non-scaling-stroke", pointerEvents: "stroke", cursor: edgeInfo.cursor, onPointerEnter: () => onHoverChange(outline.key), onPointerLeave: () => onHoverChange(null), onPointerDown: onPointerDown }));
469
821
  };
470
822
  const getSvgPointFromPointerEvent = ({ event, rect, }) => {
471
823
  return {
@@ -498,7 +850,7 @@ const SelectedUvHandleCircle = ({ handle, outline }) => {
498
850
  });
499
851
  const nextValue = constrainUv((0, exports.getUvCoordinateForPoint)(outline.points, point), handle.fieldSchema);
500
852
  lastValue = nextValue;
501
- setEffectDragOverrides(handle.nodePath, handle.effectIndex, handle.fieldKey, nextValue);
853
+ setEffectDragOverrides(handle.nodePath, handle.effectIndex, handle.fieldKey, remotion_1.Internals.makeStaticDragOverride(nextValue));
502
854
  };
503
855
  updateFromPointerEvent(event);
504
856
  const onPointerMove = (moveEvent) => {
@@ -545,81 +897,139 @@ const SelectedUvHandleCircle = ({ handle, outline }) => {
545
897
  return (jsx_runtime_1.jsx("circle", { cx: position.x, cy: position.y, r: 6, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: "move", onPointerDown: onPointerDown }));
546
898
  };
547
899
  const SelectedOutlineOverlay = ({ scale }) => {
548
- const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
900
+ const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
549
901
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
550
902
  const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
551
903
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
552
904
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
553
- const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
905
+ const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
906
+ const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
554
907
  const [outlines, setOutlines] = (0, react_1.useState)([]);
908
+ const [hoveredOutlineKey, setHoveredOutlineKey] = (0, react_1.useState)(null);
555
909
  const overlayRef = (0, react_1.useRef)(null);
556
- const selectedOutlineTargets = (0, react_1.useMemo)(() => {
910
+ const outlineTargets = (0, react_1.useMemo)(() => {
557
911
  if (!TimelineSelection_1.ENABLE_OUTLINES) {
558
912
  return [];
559
913
  }
914
+ const selectedSequenceKeys = getSelectedSequenceKeys(selectedItems);
560
915
  const selectedEffectsBySequenceKey = (0, exports.getSelectedEffectFieldsBySequenceKey)(selectedItems);
561
916
  const clientId = previewServerState.type === 'connected'
562
917
  ? previewServerState.clientId
563
918
  : null;
564
- return getSequencesWithSelectedOutlines({
565
- selectedItems,
919
+ return (0, exports.getSequencesWithSelectableOutlines)({
566
920
  sequences,
567
921
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
568
- }).map(({ key, nodePathInfo, sequence }) => {
569
- var _a;
922
+ }).map(({ key, keyframeDisplayOffset, nodePathInfo, sequence }) => {
923
+ var _a, _b;
570
924
  if (sequence.refForOutline === null) {
571
925
  throw new Error('Expected sequence to have a ref for outline');
572
926
  }
927
+ const selected = selectedSequenceKeys.has(key);
573
928
  const nodePath = nodePathInfo.sequenceSubscriptionKey;
574
929
  const { controls } = sequence;
575
930
  const fieldSchema = controls === null || controls === void 0 ? void 0 : controls.schema[translateFieldKey];
576
931
  const codeValue = (_a = remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)) === null || _a === void 0 ? void 0 : _a[translateFieldKey];
932
+ const scaleFieldSchema = controls === null || controls === void 0 ? void 0 : controls.schema[scaleFieldKey];
933
+ const scaleCodeValue = (_b = remotion_1.Internals.getCodeValuesCtx(codeValues, nodePath)) === null || _b === void 0 ? void 0 : _b[scaleFieldKey];
934
+ const canDragStatus = (codeValue === null || codeValue === void 0 ? void 0 : codeValue.status) === 'static' ||
935
+ ((codeValue === null || codeValue === void 0 ? void 0 : codeValue.status) === 'keyframed' &&
936
+ codeValue.interpolationFunction === 'interpolate');
577
937
  const canDrag = previewServerState.type === 'connected' &&
578
938
  controls !== null &&
579
939
  (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'translate' &&
580
- (codeValue === null || codeValue === void 0 ? void 0 : codeValue.canUpdate) === true;
940
+ canDragStatus;
941
+ const canScaleDrag = previewServerState.type === 'connected' &&
942
+ controls !== null &&
943
+ (scaleFieldSchema === null || scaleFieldSchema === void 0 ? void 0 : scaleFieldSchema.type) === 'scale' &&
944
+ (scaleCodeValue === null || scaleCodeValue === void 0 ? void 0 : scaleCodeValue.status) === 'static';
581
945
  return {
582
946
  key,
947
+ nodePathInfo,
583
948
  ref: sequence.refForOutline,
949
+ selected,
950
+ selection: { type: 'sequence', nodePathInfo },
584
951
  drag: canDrag
585
952
  ? {
586
953
  codeValue,
587
954
  clientId: previewServerState.clientId,
588
955
  fieldDefault: fieldSchema.default,
956
+ keyframeDisplayOffset,
957
+ nodePath,
958
+ schema: controls.schema,
959
+ }
960
+ : null,
961
+ scaleDrag: canScaleDrag
962
+ ? {
963
+ codeValue: scaleCodeValue,
964
+ clientId: previewServerState.clientId,
965
+ fieldDefault: scaleFieldSchema.default,
966
+ fieldSchema: scaleFieldSchema,
967
+ linked: getScaleLockState({
968
+ nodePath,
969
+ fieldKey: scaleFieldKey,
970
+ defaultValue: (() => {
971
+ var _a;
972
+ const dragOverrideValue = ((_a = getDragOverrides(nodePath)) !== null && _a !== void 0 ? _a : {})[scaleFieldKey];
973
+ const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
974
+ codeValue: scaleCodeValue,
975
+ dragOverrideValue,
976
+ defaultValue: scaleFieldSchema.default,
977
+ shouldResortToDefaultValueIfUndefined: true,
978
+ });
979
+ const [x, y] = no_react_1.NoReactInternals.parseScaleValue(effectiveValue);
980
+ return x === y;
981
+ })(),
982
+ }),
589
983
  nodePath,
590
984
  schema: controls.schema,
591
985
  }
592
986
  : null,
593
- uvHandles: getSelectedUvHandles({
594
- codeValues,
595
- clientId,
596
- getEffectDragOverrides,
597
- nodePath,
598
- selectedEffects: selectedEffectsBySequenceKey.get(key),
599
- sequence,
600
- }),
987
+ uvHandles: selected
988
+ ? getSelectedUvHandles({
989
+ codeValues,
990
+ clientId,
991
+ getEffectDragOverrides,
992
+ nodePath,
993
+ selectedEffects: selectedEffectsBySequenceKey.get(key),
994
+ sequence,
995
+ })
996
+ : [],
601
997
  };
602
998
  });
603
999
  }, [
604
1000
  codeValues,
1001
+ getDragOverrides,
605
1002
  getEffectDragOverrides,
1003
+ getScaleLockState,
606
1004
  overrideIdToNodePathMappings,
607
1005
  previewServerState,
608
1006
  selectedItems,
609
1007
  sequences,
610
1008
  ]);
1009
+ (0, react_1.useEffect)(() => {
1010
+ if (hoveredOutlineKey !== null &&
1011
+ !outlineTargets.some((target) => target.key === hoveredOutlineKey)) {
1012
+ setHoveredOutlineKey(null);
1013
+ }
1014
+ }, [hoveredOutlineKey, outlineTargets]);
611
1015
  const targetsByKey = (0, react_1.useMemo)(() => {
612
- return new Map(selectedOutlineTargets.map((target) => [target.key, target]));
613
- }, [selectedOutlineTargets]);
1016
+ return new Map(outlineTargets.map((target) => [target.key, target]));
1017
+ }, [outlineTargets]);
1018
+ const allDragTargets = (0, react_1.useMemo)(() => {
1019
+ return outlineTargets.flatMap((target) => target.selected && target.drag !== null ? [target.drag] : []);
1020
+ }, [outlineTargets]);
1021
+ const allScaleDragTargets = (0, react_1.useMemo)(() => {
1022
+ return outlineTargets.flatMap((target) => target.selected && target.scaleDrag !== null ? [target.scaleDrag] : []);
1023
+ }, [outlineTargets]);
614
1024
  (0, react_1.useEffect)(() => {
615
- if (selectedOutlineTargets.length === 0) {
1025
+ if (outlineTargets.length === 0) {
616
1026
  setOutlines((prevOutlines) => prevOutlines.length === 0 ? prevOutlines : []);
617
1027
  return;
618
1028
  }
619
1029
  let animationFrame = null;
620
1030
  const updateOutlines = () => {
621
1031
  if (overlayRef.current) {
622
- const nextOutlines = measureOutlines(overlayRef.current, selectedOutlineTargets);
1032
+ const nextOutlines = measureOutlines(overlayRef.current, outlineTargets);
623
1033
  setOutlines((prevOutlines) => outlinesAreEqual(prevOutlines, nextOutlines)
624
1034
  ? prevOutlines
625
1035
  : nextOutlines);
@@ -632,14 +1042,20 @@ const SelectedOutlineOverlay = ({ scale }) => {
632
1042
  cancelAnimationFrame(animationFrame);
633
1043
  }
634
1044
  };
635
- }, [selectedOutlineTargets]);
636
- if (selectedOutlineTargets.length === 0) {
1045
+ }, [outlineTargets]);
1046
+ if (outlineTargets.length === 0) {
637
1047
  return null;
638
1048
  }
639
1049
  return (jsx_runtime_1.jsx("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: outlines.map((outline) => {
640
- var _a;
1050
+ var _a, _b, _c;
641
1051
  return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [
642
- jsx_runtime_1.jsx(SelectedOutlinePolygon, { outline: outline, scale: scale, target: targetsByKey.get(outline.key) }), (_a = targetsByKey.get(outline.key)) === null || _a === void 0 ? void 0 : _a.uvHandles.map((handle) => (jsx_runtime_1.jsx(SelectedUvHandleCircle, { handle: handle, outline: outline }, `${handle.effectIndex}-${handle.fieldKey}`)))] }, outline.key));
1052
+ jsx_runtime_1.jsx(SelectedOutlinePolygon, { allDragTargets: allDragTargets, hovered: hoveredOutlineKey === outline.key, outline: outline, onHoverChange: setHoveredOutlineKey, onSelect: selectItem, scale: scale, target: targetsByKey.get(outline.key) }), ((_a = targetsByKey.get(outline.key)) === null || _a === void 0 ? void 0 : _a.selected) ||
1053
+ hoveredOutlineKey === outline.key
1054
+ ? ['top', 'right', 'bottom', 'left'].map((edge) => (jsx_runtime_1.jsx(SelectedOutlineScaleEdgeLine, { allScaleDragTargets: allScaleDragTargets, edge: edge, outline: outline, onHoverChange: setHoveredOutlineKey, onSelect: selectItem, target: targetsByKey.get(outline.key) }, edge)))
1055
+ : null, ((_b = targetsByKey.get(outline.key)) === null || _b === void 0 ? void 0 : _b.selected)
1056
+ ? (_c = targetsByKey
1057
+ .get(outline.key)) === null || _c === void 0 ? void 0 : _c.uvHandles.map((handle) => (jsx_runtime_1.jsx(SelectedUvHandleCircle, { handle: handle, outline: outline }, `${handle.effectIndex}-${handle.fieldKey}`)))
1058
+ : null] }, outline.key));
643
1059
  }) }));
644
1060
  };
645
1061
  exports.SelectedOutlineOverlay = SelectedOutlineOverlay;