@remotion/studio 4.0.485 → 4.0.487

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 (275) hide show
  1. package/dist/ResolveCompositionConfigInStudio.js +42 -0
  2. package/dist/components/AssetSelector.js +1 -1
  3. package/dist/components/AssetSelectorItem.js +9 -9
  4. package/dist/components/AudioWaveform.js +3 -3
  5. package/dist/components/Button.js +2 -2
  6. package/dist/components/Canvas.js +28 -0
  7. package/dist/components/CanvasOrLoading.js +1 -1
  8. package/dist/components/CheckboardToggle.js +1 -1
  9. package/dist/components/Checkbox.js +3 -3
  10. package/dist/components/ColorPicker/AlphaSlider.js +4 -3
  11. package/dist/components/ColorPicker/ColorPicker.js +4 -4
  12. package/dist/components/ColorPicker/ColorPickerPopup.js +10 -10
  13. package/dist/components/ColorPicker/HueSlider.js +4 -3
  14. package/dist/components/ColorPicker/SaturationValueArea.js +5 -4
  15. package/dist/components/ColorPicker/checker.d.ts +1 -1
  16. package/dist/components/ColorPicker/checker.js +3 -3
  17. package/dist/components/CompactExplanation.js +3 -3
  18. package/dist/components/CompositionSelector.js +141 -5
  19. package/dist/components/CompositionSelectorItem.d.ts +1 -0
  20. package/dist/components/CompositionSelectorItem.js +103 -11
  21. package/dist/components/ContextMenu.js +2 -1
  22. package/dist/components/CopyButton.js +3 -2
  23. package/dist/components/CurrentAsset.d.ts +3 -1
  24. package/dist/components/CurrentAsset.js +15 -2
  25. package/dist/components/CurrentComposition.js +43 -2
  26. package/dist/components/EditorContexts.js +2 -1
  27. package/dist/components/EffectPickerModal.js +1 -1
  28. package/dist/components/FilePreview.js +2 -1
  29. package/dist/components/FpsCounter.js +3 -2
  30. package/dist/components/FullscreenToggle.js +2 -1
  31. package/dist/components/GlobalKeybindings.js +19 -12
  32. package/dist/components/InlineAction.js +2 -2
  33. package/dist/components/InlineEditableTitle.d.ts +1 -0
  34. package/dist/components/InlineEditableTitle.js +12 -7
  35. package/dist/components/InspectorInfoHeader.js +2 -2
  36. package/dist/components/InspectorPanel/DefaultInspector.d.ts +1 -0
  37. package/dist/components/InspectorPanel/DefaultInspector.js +2 -2
  38. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +1 -1
  39. package/dist/components/InspectorPanel/common.js +2 -2
  40. package/dist/components/InspectorPanel/styles.js +3 -3
  41. package/dist/components/InspectorPanel.d.ts +1 -0
  42. package/dist/components/InspectorPanel.js +2 -2
  43. package/dist/components/InspectorSequenceSection.js +1 -1
  44. package/dist/components/InspectorSourceLocation.d.ts +1 -0
  45. package/dist/components/InspectorSourceLocation.js +18 -3
  46. package/dist/components/InstallablePackage.js +1 -1
  47. package/dist/components/KeyboardShortcutsExplainer.js +9 -5
  48. package/dist/components/LoopToggle.js +1 -1
  49. package/dist/components/Menu/MenuDivider.js +1 -1
  50. package/dist/components/Menu/MenuItem.js +1 -1
  51. package/dist/components/Menu/MenuSubItem.js +1 -1
  52. package/dist/components/Menu/styles.js +3 -3
  53. package/dist/components/MenuToolbar.js +2 -2
  54. package/dist/components/ModalButton.js +1 -1
  55. package/dist/components/ModalContainer.js +3 -3
  56. package/dist/components/ModalFooter.js +2 -1
  57. package/dist/components/ModalHeader.js +3 -2
  58. package/dist/components/Modals.js +2 -1
  59. package/dist/components/NewComposition/CancelButton.js +4 -3
  60. package/dist/components/NewComposition/ComboBox.js +3 -3
  61. package/dist/components/NewComposition/InputDragger.js +11 -3
  62. package/dist/components/NewComposition/MenuContent.js +1 -1
  63. package/dist/components/NewComposition/NewComposition.js +4 -1
  64. package/dist/components/NewComposition/NewFolder.d.ts +5 -0
  65. package/dist/components/NewComposition/NewFolder.js +86 -0
  66. package/dist/components/NewComposition/RemInput.js +3 -3
  67. package/dist/components/NewComposition/RemTextarea.js +1 -1
  68. package/dist/components/NewComposition/RenameStaticFile.js +20 -59
  69. package/dist/components/NewComposition/ValidationMessage.js +1 -1
  70. package/dist/components/NewComposition/use-rename-static-file.d.ts +18 -0
  71. package/dist/components/NewComposition/use-rename-static-file.js +90 -0
  72. package/dist/components/NoRegisterRoot.js +3 -2
  73. package/dist/components/Notifications/ColorDot.js +3 -2
  74. package/dist/components/Notifications/Notification.js +4 -4
  75. package/dist/components/Notifications/NotificationCenter.js +2 -1
  76. package/dist/components/Notifications/ServerDisconnected.js +5 -4
  77. package/dist/components/OptionsPanel.js +1 -1
  78. package/dist/components/OutlineToggle.js +1 -1
  79. package/dist/components/PlayPause.js +4 -3
  80. package/dist/components/Preview.js +1 -1
  81. package/dist/components/PreviewToolbar.js +3 -2
  82. package/dist/components/QuickSwitcher/AlgoliaCredit.js +2 -1
  83. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  84. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +2 -2
  85. package/dist/components/RefreshCompositionOverlay.js +2 -1
  86. package/dist/components/RenderButton.js +10 -9
  87. package/dist/components/RenderModal/CliCopyButton.js +1 -1
  88. package/dist/components/RenderModal/ClientRenderProgress.js +1 -1
  89. package/dist/components/RenderModal/DataEditor.js +1 -1
  90. package/dist/components/RenderModal/GuiRenderStatus.js +1 -1
  91. package/dist/components/RenderModal/InfoBubble.js +2 -2
  92. package/dist/components/RenderModal/InfoTooltip.js +3 -3
  93. package/dist/components/RenderModal/InlineEyeIcon.js +2 -1
  94. package/dist/components/RenderModal/InlineRemoveButton.js +2 -1
  95. package/dist/components/RenderModal/MultiRangeSlider.js +1 -1
  96. package/dist/components/RenderModal/OptionExplainer.d.ts +11 -1
  97. package/dist/components/RenderModal/OptionExplainer.js +33 -13
  98. package/dist/components/RenderModal/OptionExplainerBubble.d.ts +15 -1
  99. package/dist/components/RenderModal/OptionExplainerBubble.js +17 -3
  100. package/dist/components/RenderModal/RenderModalHr.js +2 -1
  101. package/dist/components/RenderModal/RenderStatusModal.js +2 -1
  102. package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +1 -0
  103. package/dist/components/RenderModal/SchemaEditor/Fieldset.js +6 -1
  104. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +1 -2
  105. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +1 -5
  106. package/dist/components/RenderModal/SchemaEditor/SchemaResetButton.js +2 -1
  107. package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.js +1 -1
  108. package/dist/components/RenderModal/SchemaEditor/SchemaVerticalGuide.js +2 -1
  109. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +1 -1
  110. package/dist/components/RenderModal/SchemaEditor/ZodErrorMessages.js +1 -1
  111. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +1 -1
  112. package/dist/components/RenderModal/SchemaEditor/create-zod-values.js +2 -1
  113. package/dist/components/RenderModal/ServerRenderModal.js +1 -1
  114. package/dist/components/RenderModal/WarningIndicatorButton.js +4 -6
  115. package/dist/components/RenderModal/WebRenderModal.js +5 -2
  116. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +3 -0
  117. package/dist/components/RenderModal/WebRenderModalAdvanced.js +92 -5
  118. package/dist/components/RenderModal/WebRenderModalAudio.js +4 -3
  119. package/dist/components/RenderModal/WebRenderModalBasic.js +2 -2
  120. package/dist/components/RenderModal/WebRenderModalLicense.js +2 -2
  121. package/dist/components/RenderModal/WebRenderModalPicture.js +2 -1
  122. package/dist/components/RenderModal/render-modals.js +3 -3
  123. package/dist/components/RenderPreview.js +1 -1
  124. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -0
  125. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +2 -1
  126. package/dist/components/RenderQueue/RenderQueueDownloadItem.js +2 -1
  127. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +2 -1
  128. package/dist/components/RenderQueue/RenderQueueItemStatus.js +1 -1
  129. package/dist/components/RenderQueue/RenderQueueOpenInFolder.js +2 -1
  130. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +2 -1
  131. package/dist/components/RenderQueue/RenderQueueRepeat.js +2 -1
  132. package/dist/components/RenderQueue/client-side-render-types.d.ts +2 -1
  133. package/dist/components/RenderQueue/index.js +1 -1
  134. package/dist/components/RendersTab.js +2 -2
  135. package/dist/components/SegmentedControl.js +3 -3
  136. package/dist/components/SelectedOutlineElement.d.ts +9 -0
  137. package/dist/components/SelectedOutlineElement.js +63 -18
  138. package/dist/components/SelectedOutlineOverlay.d.ts +2 -0
  139. package/dist/components/SelectedOutlineOverlay.js +53 -2
  140. package/dist/components/SelectedOutlineUvControls.js +18 -11
  141. package/dist/components/SidebarCollapserControls.js +5 -4
  142. package/dist/components/SnappingProvider.d.ts +4 -0
  143. package/dist/components/SnappingProvider.js +24 -0
  144. package/dist/components/SnappingToggle.d.ts +2 -0
  145. package/dist/components/SnappingToggle.js +26 -0
  146. package/dist/components/Splitter/SplitterContext.d.ts +1 -1
  147. package/dist/components/Splitter/SplitterElement.js +2 -1
  148. package/dist/components/StaticFilePreview.js +1 -1
  149. package/dist/components/Tabs/index.js +3 -3
  150. package/dist/components/Tabs/vertical.js +3 -3
  151. package/dist/components/TextViewer.js +2 -1
  152. package/dist/components/TimeValue.js +1 -1
  153. package/dist/components/Timeline/EasingEditorModal.js +8 -8
  154. package/dist/components/Timeline/KeyframeSettingsModal.js +1 -1
  155. package/dist/components/Timeline/LoopedIndicator.js +2 -2
  156. package/dist/components/Timeline/MaxTimelineTracks.js +3 -2
  157. package/dist/components/Timeline/TimelineArrayField.js +6 -5
  158. package/dist/components/Timeline/TimelineColorField.js +2 -1
  159. package/dist/components/Timeline/TimelineEffectItem.js +3 -2
  160. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  161. package/dist/components/Timeline/TimelineExpandArrowButton.js +3 -2
  162. package/dist/components/Timeline/TimelineExpandedRow.js +2 -1
  163. package/dist/components/Timeline/TimelineExpandedSection.js +1 -1
  164. package/dist/components/Timeline/TimelineFieldLabel.js +2 -1
  165. package/dist/components/Timeline/TimelineFontFamilyField.d.ts +11 -0
  166. package/dist/components/Timeline/TimelineFontFamilyField.js +545 -0
  167. package/dist/components/Timeline/TimelineImageInfo.js +2 -1
  168. package/dist/components/Timeline/TimelineInOutPointer.js +2 -1
  169. package/dist/components/Timeline/TimelineInOutPointerHandle.js +2 -4
  170. package/dist/components/Timeline/TimelineKeyframeControls.js +2 -2
  171. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.js +1 -1
  172. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +1 -1
  173. package/dist/components/Timeline/TimelineLayerEye.js +3 -3
  174. package/dist/components/Timeline/TimelineMediaInfo.js +2 -2
  175. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  176. package/dist/components/Timeline/TimelineRotationField.js +4 -3
  177. package/dist/components/Timeline/TimelineScaleField.js +1 -1
  178. package/dist/components/Timeline/TimelineSchemaField.d.ts +2 -0
  179. package/dist/components/Timeline/TimelineSchemaField.js +47 -7
  180. package/dist/components/Timeline/TimelineScrollable.js +3 -2
  181. package/dist/components/Timeline/TimelineSelection.js +11 -6
  182. package/dist/components/Timeline/TimelineSequence.js +17 -20
  183. package/dist/components/Timeline/TimelineSequenceFrame.js +3 -2
  184. package/dist/components/Timeline/TimelineSequenceItem.js +8 -7
  185. package/dist/components/Timeline/TimelineSequenceName.js +3 -2
  186. package/dist/components/Timeline/TimelineSequencePropItem.js +2 -1
  187. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +20 -1
  188. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +128 -11
  189. package/dist/components/Timeline/TimelineSlider.js +2 -1
  190. package/dist/components/Timeline/TimelineSliderHandle.js +2 -1
  191. package/dist/components/Timeline/TimelineTimeIndicators.js +1 -1
  192. package/dist/components/Timeline/TimelineVideoInfo.js +2 -1
  193. package/dist/components/Timeline/TimelineZoomControls.js +4 -3
  194. package/dist/components/Timeline/call-move-keyframe.d.ts +5 -0
  195. package/dist/components/Timeline/call-move-keyframe.js +14 -3
  196. package/dist/components/Timeline/google-fonts-list.d.ts +6 -0
  197. package/dist/components/Timeline/google-fonts-list.js +1512 -0
  198. package/dist/components/Timeline/save-sequence-prop.d.ts +8 -1
  199. package/dist/components/Timeline/save-sequence-prop.js +63 -19
  200. package/dist/components/Timeline/timeline-rotation-field-utils.d.ts +5 -0
  201. package/dist/components/Timeline/timeline-rotation-field-utils.js +16 -0
  202. package/dist/components/Timeline/timeline-scroll-logic.js +5 -2
  203. package/dist/components/TimelineInOutToggle.js +1 -1
  204. package/dist/components/UpdateCheck.js +2 -2
  205. package/dist/components/UpdateModal/OpenIssueButton.js +1 -1
  206. package/dist/components/VisualControls/ClickableFileName.js +4 -4
  207. package/dist/components/VisualControls/VisualControlsContent.js +9 -1
  208. package/dist/components/effect-drag-and-drop.js +30 -8
  209. package/dist/components/import-assets.d.ts +8 -2
  210. package/dist/components/import-assets.js +55 -1
  211. package/dist/components/options-sidebar-tabs.d.ts +1 -0
  212. package/dist/components/options-sidebar-tabs.js +6 -1
  213. package/dist/components/selected-outline-measurement.js +2 -1
  214. package/dist/components/selected-outline-snap.d.ts +36 -0
  215. package/dist/components/selected-outline-snap.js +158 -0
  216. package/dist/error-overlay/remotion-overlay/CalculateMetadataErrorExplainer.js +2 -2
  217. package/dist/error-overlay/remotion-overlay/CodeFrame.js +7 -5
  218. package/dist/error-overlay/remotion-overlay/CompositionIdListItem.js +2 -2
  219. package/dist/error-overlay/remotion-overlay/DismissButton.js +3 -2
  220. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +3 -2
  221. package/dist/error-overlay/remotion-overlay/ErrorMessage.js +4 -4
  222. package/dist/error-overlay/remotion-overlay/HelpLink.js +1 -1
  223. package/dist/error-overlay/remotion-overlay/MediaPlaybackErrorExplainer.js +4 -4
  224. package/dist/error-overlay/remotion-overlay/Overlay.js +3 -2
  225. package/dist/error-overlay/remotion-overlay/StackFrame.js +4 -3
  226. package/dist/error-overlay/remotion-overlay/Symbolicating.js +2 -1
  227. package/dist/error-overlay/remotion-overlay/carets.js +3 -2
  228. package/dist/esm/chunk-jefhcs5z.js +164 -0
  229. package/dist/esm/{chunk-103pp4n7.js → chunk-y2t24cx0.js} +10754 -6829
  230. package/dist/esm/internals.mjs +10755 -6796
  231. package/dist/esm/previewEntry.mjs +10554 -6591
  232. package/dist/esm/renderEntry.mjs +8 -5
  233. package/dist/helpers/checkerboard-background.js +4 -12
  234. package/dist/helpers/colors.d.ts +99 -7
  235. package/dist/helpers/colors.js +118 -10
  236. package/dist/helpers/inject-css.js +85 -83
  237. package/dist/helpers/retry-payload.js +1 -0
  238. package/dist/helpers/timeline-layout.d.ts +4 -2
  239. package/dist/helpers/use-menu-structure.js +74 -5
  240. package/dist/helpers/validate-folder-rename.js +2 -10
  241. package/dist/helpers/validate-new-folder-name.d.ts +5 -0
  242. package/dist/helpers/validate-new-folder-name.js +16 -0
  243. package/dist/hot-middleware-client/client.js +3 -2
  244. package/dist/icons/Checkmark.js +2 -1
  245. package/dist/icons/audio.js +2 -1
  246. package/dist/icons/caret.js +2 -2
  247. package/dist/icons/certificate.js +2 -1
  248. package/dist/icons/data.js +2 -1
  249. package/dist/icons/eyedropper.js +2 -1
  250. package/dist/icons/file.js +2 -1
  251. package/dist/icons/frame.js +2 -1
  252. package/dist/icons/gear.js +2 -1
  253. package/dist/icons/gif.js +2 -1
  254. package/dist/icons/jump-to-start.js +2 -1
  255. package/dist/icons/keys.js +4 -3
  256. package/dist/icons/magnet.d.ts +3 -0
  257. package/dist/icons/magnet.js +8 -0
  258. package/dist/icons/media-volume.js +1 -1
  259. package/dist/icons/minus.js +2 -1
  260. package/dist/icons/pause.js +2 -1
  261. package/dist/icons/play.js +2 -1
  262. package/dist/icons/react.d.ts +5 -0
  263. package/dist/icons/react.js +8 -0
  264. package/dist/icons/redo.js +2 -1
  265. package/dist/icons/step-back.js +2 -1
  266. package/dist/icons/step-forward.js +2 -1
  267. package/dist/icons/undo.js +2 -1
  268. package/dist/previewEntry.js +2 -1
  269. package/dist/renderEntry.js +4 -3
  270. package/dist/state/editor-guides.d.ts +2 -2
  271. package/dist/state/editor-snapping.d.ts +8 -0
  272. package/dist/state/editor-snapping.js +18 -0
  273. package/dist/state/modals.d.ts +6 -1
  274. package/package.json +12 -12
  275. package/dist/esm/chunk-6jf1natv.js +0 -25
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.SelectedOutlineElement = void 0;
36
+ exports.SelectedOutlineElement = exports.SelectedOutlineTransformOriginHandle = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const react_dom_1 = require("react-dom");
@@ -43,6 +43,7 @@ const client_id_1 = require("../helpers/client-id");
43
43
  const colors_1 = require("../helpers/colors");
44
44
  const format_file_location_1 = require("../helpers/format-file-location");
45
45
  const open_in_editor_1 = require("../helpers/open-in-editor");
46
+ const editor_snapping_1 = require("../state/editor-snapping");
46
47
  const modals_1 = require("../state/modals");
47
48
  const call_api_1 = require("./call-api");
48
49
  const ConfirmationDialog_1 = require("./ConfirmationDialog");
@@ -53,6 +54,7 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
53
54
  const options_sidebar_tabs_1 = require("./options-sidebar-tabs");
54
55
  const selected_outline_drag_1 = require("./selected-outline-drag");
55
56
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
57
+ const selected_outline_snap_1 = require("./selected-outline-snap");
56
58
  const selected_outline_types_1 = require("./selected-outline-types");
57
59
  const selected_outline_uv_1 = require("./selected-outline-uv");
58
60
  const call_add_keyframe_1 = require("./Timeline/call-add-keyframe");
@@ -70,6 +72,7 @@ const emptyContextMenuValues = [];
70
72
  const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, target }) => {
71
73
  var _a;
72
74
  const { setDragOverrides, clearDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
75
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
73
76
  const transformOriginDrag = (_a = target === null || target === void 0 ? void 0 : target.transformOriginDrag) !== null && _a !== void 0 ? _a : null;
74
77
  const parsed = (0, react_1.useMemo)(() => transformOriginDrag === null
75
78
  ? null
@@ -142,11 +145,13 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
142
145
  const snapPoint = lockedAxis === null
143
146
  ? point
144
147
  : (0, selected_outline_uv_1.getUvHandlePosition)(outline.points, axisLockedUv);
145
- const snappedUv = (0, selected_outline_drag_1.snapSelectedOutlineTransformOriginUv)({
146
- point: snapPoint,
147
- points: outline.points,
148
- uv: axisLockedUv,
149
- });
148
+ const snappedUv = editorSnapping
149
+ ? (0, selected_outline_drag_1.snapSelectedOutlineTransformOriginUv)({
150
+ point: snapPoint,
151
+ points: outline.points,
152
+ uv: axisLockedUv,
153
+ })
154
+ : axisLockedUv;
150
155
  const nextUv = (0, selected_outline_drag_1.applySelectedOutlineTransformOriginAxisLock)({
151
156
  lockedAxis,
152
157
  startUv: uv,
@@ -293,6 +298,7 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
293
298
  window.addEventListener('keyup', onKeyChange);
294
299
  }, [
295
300
  clearDragOverrides,
301
+ editorSnapping,
296
302
  onDraggingChange,
297
303
  outline,
298
304
  parsed,
@@ -308,15 +314,17 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
308
314
  return null;
309
315
  }
310
316
  return (jsx_runtime_1.jsxs("g", { pointerEvents: "all", cursor: "crosshair", onPointerDown: onPointerDown, "aria-hidden": "true", style: {
311
- filter: 'drop-shadow(0 0 1px rgba(255, 255, 255, 0.2))',
317
+ filter: colors_1.SELECTED_OUTLINE_DROP_SHADOW,
312
318
  }, children: [
313
319
  jsx_runtime_1.jsx("circle", { cx: position.x, cy: position.y, r: 4, stroke: colors_1.BLUE, fill: "none", strokeWidth: 2, vectorEffect: "non-scaling-stroke" }), jsx_runtime_1.jsx("line", { x1: position.x - 8, y1: position.y, x2: position.x + 8, y2: position.y, stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke" }), jsx_runtime_1.jsx("line", { x1: position.x, y1: position.y - 8, x2: position.x, y2: position.y + 8, stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke" })
314
320
  ] }));
315
321
  };
316
- const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, hovered, onContextMenuOpen, outline, onDraggingChange, onHoverChange, onSelect, onTextEditStart, scale, target, }) => {
322
+ exports.SelectedOutlineTransformOriginHandle = SelectedOutlineTransformOriginHandle;
323
+ const SelectedOutlinePolygon = ({ allDragTargets, allDragOutlines, contextMenuValues, dragging, hovered, onContextMenuOpen, outline, onDraggingChange, onHoverChange, onSnapPointsChange, onSelect, onTextEditStart, scale, snapTargets, target, }) => {
317
324
  var _a, _b, _c, _d;
318
325
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
319
326
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
327
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
320
328
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
321
329
  const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
322
330
  timelinePositionRef.current = timelinePosition;
@@ -357,6 +365,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
357
365
  let currentPointerY = startPointerY;
358
366
  let axisLocked = false;
359
367
  let dragStarted = false;
368
+ let snappingDisabled = event.metaKey || event.ctrlKey;
360
369
  const updateDragOverrides = () => {
361
370
  const screenDeltaX = currentPointerX - startPointerX;
362
371
  const screenDeltaY = currentPointerY - startPointerY;
@@ -369,16 +378,44 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
369
378
  }
370
379
  dragStarted = true;
371
380
  onDraggingChange(true);
381
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('default');
372
382
  }
383
+ const axisLockedDirection = axisLocked
384
+ ? Math.abs(screenDeltaX) >= Math.abs(screenDeltaY)
385
+ ? 'horizontal'
386
+ : 'vertical'
387
+ : null;
373
388
  const dragDelta = (0, selected_outline_drag_1.applySelectedOutlineDragAxisLock)({
374
389
  deltaX: screenDeltaX / scale,
375
390
  deltaY: screenDeltaY / scale,
376
391
  axisLocked,
377
392
  });
393
+ let { deltaX, deltaY } = dragDelta;
394
+ if (editorSnapping && !snappingDisabled) {
395
+ const snapResult = (0, selected_outline_snap_1.findSelectedOutlineSnap)({
396
+ allowX: axisLockedDirection !== 'vertical',
397
+ allowY: axisLockedDirection !== 'horizontal',
398
+ deltaX,
399
+ deltaY,
400
+ outlines: selected ? allDragOutlines : [outline],
401
+ scale,
402
+ targets: snapTargets,
403
+ });
404
+ if (snapResult.snapOffsetX !== null) {
405
+ deltaX += snapResult.snapOffsetX;
406
+ }
407
+ if (snapResult.snapOffsetY !== null) {
408
+ deltaY += snapResult.snapOffsetY;
409
+ }
410
+ onSnapPointsChange(snapResult.activeSnapPoints);
411
+ }
412
+ else {
413
+ onSnapPointsChange([]);
414
+ }
378
415
  lastValues = (0, selected_outline_drag_1.getSelectedOutlineDragValues)({
379
416
  dragStates,
380
- deltaX: dragDelta.deltaX,
381
- deltaY: dragDelta.deltaY,
417
+ deltaX,
418
+ deltaY,
382
419
  });
383
420
  for (const dragState of dragStates) {
384
421
  const value = lastValues.get(dragState.key);
@@ -402,6 +439,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
402
439
  currentPointerX = moveEvent.clientX;
403
440
  currentPointerY = moveEvent.clientY;
404
441
  axisLocked = moveEvent.shiftKey;
442
+ snappingDisabled = moveEvent.metaKey || moveEvent.ctrlKey;
405
443
  updateDragOverrides();
406
444
  };
407
445
  const onKeyChange = (keyEvent) => {
@@ -422,6 +460,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
422
460
  window.removeEventListener('keydown', onKeyChange);
423
461
  window.removeEventListener('keyup', onKeyChange);
424
462
  if (dragStarted) {
463
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
425
464
  onDraggingChange(false);
426
465
  }
427
466
  const changes = (0, selected_outline_drag_1.getSelectedOutlineDragChanges)({
@@ -473,15 +512,20 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
473
512
  window.addEventListener('keyup', onKeyChange);
474
513
  }, [
475
514
  allDragTargets,
515
+ allDragOutlines,
476
516
  clearDragOverrides,
477
517
  drag,
518
+ editorSnapping,
478
519
  getDragOverrides,
479
520
  onDraggingChange,
480
521
  onSelect,
522
+ onSnapPointsChange,
523
+ outline,
481
524
  scale,
482
525
  selected,
483
526
  setPropStatuses,
484
527
  setDragOverrides,
528
+ snapTargets,
485
529
  target,
486
530
  ]);
487
531
  const onDoubleClick = react_1.default.useCallback((event) => {
@@ -532,7 +576,7 @@ const SelectedOutlinePolygon = ({ allDragTargets, contextMenuValues, dragging, h
532
576
  });
533
577
  }, [effectDrop]);
534
578
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
535
- jsx_runtime_1.jsx("polygon", { ref: polygonRef, points: points, fill: effectDropHovered ? 'rgba(0, 155, 255, 0.12)' : 'transparent', stroke: colors_1.BLUE, strokeOpacity: visible || effectDropHovered ? 1 : 0, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: target === undefined ? undefined : 'all', onPointerEnter: () => {
579
+ jsx_runtime_1.jsx("polygon", { ref: polygonRef, points: points, fill: effectDropHovered ? colors_1.TIMELINE_DROP_BLUE_ALPHA_12 : colors_1.TRANSPARENT, stroke: colors_1.BLUE, strokeOpacity: visible || effectDropHovered ? 1 : 0, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: target === undefined ? undefined : 'all', onPointerEnter: () => {
536
580
  if (!dragging) {
537
581
  onHoverChange(outline.key);
538
582
  }
@@ -696,7 +740,7 @@ const SelectedOutlineScaleEdgeLine = ({ allScaleDragTargets, contextMenuValues,
696
740
  return null;
697
741
  }
698
742
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
699
- jsx_runtime_1.jsx("line", { ref: lineRef, 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: () => {
743
+ jsx_runtime_1.jsx("line", { ref: lineRef, x1: edgeInfo.start.x, y1: edgeInfo.start.y, x2: edgeInfo.end.x, y2: edgeInfo.end.y, stroke: colors_1.TRANSPARENT, strokeWidth: 12, vectorEffect: "non-scaling-stroke", pointerEvents: "stroke", cursor: edgeInfo.cursor, onPointerEnter: () => {
700
744
  if (!dragging) {
701
745
  onHoverChange(outline.key);
702
746
  }
@@ -717,6 +761,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
717
761
  var _a, _b;
718
762
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
719
763
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
764
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
720
765
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
721
766
  const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
722
767
  timelinePositionRef.current = timelinePosition;
@@ -769,7 +814,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
769
814
  let lastValues = new Map();
770
815
  let dragStarted = false;
771
816
  const updateRotationDragOverrides = () => {
772
- const rotationDeltaDegrees = rotationLocked
817
+ const rotationDeltaDegrees = rotationLocked && editorSnapping
773
818
  ? (0, selected_outline_drag_1.snapSelectedOutlineRotationDeltaDegrees)({
774
819
  dragStates,
775
820
  rotationDeltaDegrees: accumulatedDelta,
@@ -903,6 +948,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
903
948
  allRotationDragTargets,
904
949
  clearDragOverrides,
905
950
  cornerInfo,
951
+ editorSnapping,
906
952
  getDragOverrides,
907
953
  onDraggingChange,
908
954
  outline.dimensions,
@@ -918,7 +964,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
918
964
  return null;
919
965
  }
920
966
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
921
- jsx_runtime_1.jsx("circle", { ref: circleRef, cx: cornerInfo.point.x, cy: cornerInfo.point.y, r: 12, fill: "transparent", stroke: "transparent", vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: cornerInfo.cursor, onPointerEnter: () => {
967
+ jsx_runtime_1.jsx("circle", { ref: circleRef, cx: cornerInfo.point.x, cy: cornerInfo.point.y, r: 12, fill: colors_1.TRANSPARENT, stroke: colors_1.TRANSPARENT, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: cornerInfo.cursor, onPointerEnter: () => {
922
968
  if (!dragging) {
923
969
  onHoverChange(outline.key);
924
970
  }
@@ -929,7 +975,7 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
929
975
  }, onPointerDown: onPointerDown }), jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: circleRef, values: [...contextMenuValues], onOpen: onContextMenuOpen })
930
976
  ] }));
931
977
  };
932
- const SelectedOutlineElement = ({ allDragTargets, allRotationDragTargets, allScaleDragTargets, dragging, hovered, outline, onDraggingChange, onHoverChange, onSelect, scale, target, }) => {
978
+ const SelectedOutlineElement = ({ allDragTargets, allDragOutlines, allRotationDragTargets, allScaleDragTargets, dragging, hovered, outline, onDraggingChange, onHoverChange, onSnapPointsChange, onSelect, scale, snapTargets, target, }) => {
933
979
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
934
980
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
935
981
  const updateResolvedStackTrace = (0, react_1.useContext)(remotion_1.Internals.SequenceStackTracesUpdateContext);
@@ -1113,11 +1159,10 @@ const SelectedOutlineElement = ({ allDragTargets, allRotationDragTargets, allSca
1113
1159
  updateResolvedStackTrace,
1114
1160
  ]);
1115
1161
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1116
- jsx_runtime_1.jsx(SelectedOutlinePolygon, { allDragTargets: allDragTargets, contextMenuValues: emptyContextMenuValues, dragging: dragging, hovered: hovered, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSelect: onSelect, onTextEditStart: onTextEditStart, scale: scale, target: target }), (target === null || target === void 0 ? void 0 : target.containsSelection) || hovered
1162
+ jsx_runtime_1.jsx(SelectedOutlinePolygon, { allDragTargets: allDragTargets, allDragOutlines: allDragOutlines, contextMenuValues: emptyContextMenuValues, dragging: dragging, hovered: hovered, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSnapPointsChange: onSnapPointsChange, onSelect: onSelect, onTextEditStart: onTextEditStart, scale: scale, snapTargets: snapTargets, target: target }), (target === null || target === void 0 ? void 0 : target.containsSelection) || hovered
1117
1163
  ? ['top', 'right', 'bottom', 'left'].map((edge) => (jsx_runtime_1.jsx(SelectedOutlineScaleEdgeLine, { allScaleDragTargets: allScaleDragTargets, contextMenuValues: emptyContextMenuValues, dragging: dragging, edge: edge, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSelect: onSelect, target: target }, edge)))
1118
1164
  : null, (target === null || target === void 0 ? void 0 : target.containsSelection) || hovered
1119
1165
  ? ['top-left', 'top-right', 'bottom-right', 'bottom-left'].map((corner) => (jsx_runtime_1.jsx(SelectedOutlineRotationCornerHandle, { allRotationDragTargets: allRotationDragTargets, contextMenuValues: emptyContextMenuValues, corner: corner, dragging: dragging, outline: outline, onContextMenuOpen: onContextMenuOpen, onDraggingChange: onDraggingChange, onHoverChange: onHoverChange, onSelect: onSelect, target: target }, corner)))
1120
- : null, jsx_runtime_1.jsx(SelectedOutlineTransformOriginHandle, { outline: outline, onDraggingChange: onDraggingChange, target: target })
1121
- ] }));
1166
+ : null] }));
1122
1167
  };
1123
1168
  exports.SelectedOutlineElement = SelectedOutlineElement;
@@ -10,6 +10,8 @@ export declare const orderOutlinesForRendering: ({ outlines, targetsByKey, }: {
10
10
  readonly targetsByKey: ReadonlyMap<string, SelectedOutlineTarget>;
11
11
  }) => readonly SelectedOutline[];
12
12
  export declare const SelectedOutlineOverlay: React.FC<{
13
+ readonly compositionHeight: number;
14
+ readonly compositionWidth: number;
13
15
  readonly scale: number;
14
16
  readonly translationX: number;
15
17
  readonly translationY: number;
@@ -41,11 +41,13 @@ 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 use_keybinding_1 = require("../helpers/use-keybinding");
44
+ const editor_guides_1 = require("../state/editor-guides");
44
45
  const editor_outlines_1 = require("../state/editor-outlines");
45
46
  const scale_lock_1 = require("../state/scale-lock");
46
47
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
47
48
  const selected_outline_drag_1 = require("./selected-outline-drag");
48
49
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
50
+ const selected_outline_snap_1 = require("./selected-outline-snap");
49
51
  const selected_outline_types_1 = require("./selected-outline-types");
50
52
  const selected_outline_uv_1 = require("./selected-outline-uv");
51
53
  const SelectedOutlineElement_1 = require("./SelectedOutlineElement");
@@ -95,6 +97,19 @@ const outlineContainer = {
95
97
  pointerEvents: 'none',
96
98
  overflow: 'visible',
97
99
  };
100
+ const SelectedOutlineSnapIndicators = ({ activeSnapPoints, compositionHeight, compositionWidth, scale }) => {
101
+ if (activeSnapPoints.length === 0) {
102
+ return null;
103
+ }
104
+ return (jsx_runtime_1.jsx("g", { pointerEvents: "none", children: activeSnapPoints.map((snapPoint) => {
105
+ if (snapPoint.target.axis === 'x') {
106
+ const x = snapPoint.target.position * scale;
107
+ 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}`));
108
+ }
109
+ const y = snapPoint.target.position * scale;
110
+ 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}`));
111
+ }) }));
112
+ };
98
113
  const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
99
114
  return [...outlines].sort((a, b) => {
100
115
  var _a, _b;
@@ -105,9 +120,10 @@ const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
105
120
  });
106
121
  };
107
122
  exports.orderOutlinesForRendering = orderOutlinesForRendering;
108
- const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
123
+ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
109
124
  const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
110
125
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
126
+ const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
111
127
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
112
128
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
113
129
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
@@ -115,12 +131,14 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
115
131
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
116
132
  const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
117
133
  const { editorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
134
+ const { editorShowGuides, guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
118
135
  const { frameBack, frameForward, getCurrentFrame, seek } = player_1.PlayerInternals.usePlayer();
119
136
  const keybindings = (0, use_keybinding_1.useKeybinding)();
120
137
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
121
138
  const [outlines, setOutlines] = (0, react_1.useState)([]);
122
139
  const [hoveredOutlineKey, setHoveredOutlineKey] = (0, react_1.useState)(null);
123
140
  const [draggingOutline, setDraggingOutline] = (0, react_1.useState)(false);
141
+ const [activeSnapPoints, setActiveSnapPoints] = (0, react_1.useState)([]);
124
142
  const overlayRef = (0, react_1.useRef)(null);
125
143
  const keyboardNudgeSessionRef = (0, react_1.useRef)(null);
126
144
  const saveKeyboardNudgeSessionRef = (0, react_1.useRef)(() => undefined);
@@ -129,6 +147,12 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
129
147
  if (dragging) {
130
148
  setHoveredOutlineKey(null);
131
149
  }
150
+ else {
151
+ setActiveSnapPoints([]);
152
+ }
153
+ }, []);
154
+ const onSnapPointsChange = (0, react_1.useCallback)((snapPoints) => {
155
+ setActiveSnapPoints(snapPoints);
132
156
  }, []);
133
157
  const selectOutlineItem = (0, react_1.useCallback)((item, interaction) => {
134
158
  selectItem(item, interaction, undefined, { reveal: true });
@@ -391,11 +415,24 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
391
415
  const outlinesForRendering = (0, react_1.useMemo)(() => {
392
416
  return (0, exports.orderOutlinesForRendering)({ outlines, targetsByKey });
393
417
  }, [outlines, targetsByKey]);
418
+ const outlinesByKey = (0, react_1.useMemo)(() => {
419
+ return new Map(outlines.map((outline) => [outline.key, outline]));
420
+ }, [outlines]);
394
421
  const allDragTargets = (0, react_1.useMemo)(() => {
395
422
  return outlineTargets.flatMap((target) => (target.selected || target.containsSelection) && target.drag !== null
396
423
  ? [target.drag]
397
424
  : []);
398
425
  }, [outlineTargets]);
426
+ const allDragOutlines = (0, react_1.useMemo)(() => {
427
+ return outlineTargets.flatMap((target) => {
428
+ if ((!target.selected && !target.containsSelection) ||
429
+ target.drag === null) {
430
+ return [];
431
+ }
432
+ const outline = outlinesByKey.get(target.key);
433
+ return outline === undefined ? [] : [outline];
434
+ });
435
+ }, [outlineTargets, outlinesByKey]);
399
436
  const allScaleDragTargets = (0, react_1.useMemo)(() => {
400
437
  return outlineTargets.flatMap((target) => target.selected && target.scaleDrag !== null ? [target.scaleDrag] : []);
401
438
  }, [outlineTargets]);
@@ -404,6 +441,19 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
404
441
  ? [target.rotationDrag]
405
442
  : []);
406
443
  }, [outlineTargets]);
444
+ const guidesForSnap = (0, react_1.useMemo)(() => {
445
+ if (!editorShowGuides || (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition') {
446
+ return [];
447
+ }
448
+ return guidesList.filter((guide) => guide.compositionId === canvasContent.compositionId);
449
+ }, [canvasContent, editorShowGuides, guidesList]);
450
+ const snapTargets = (0, react_1.useMemo)(() => {
451
+ return (0, selected_outline_snap_1.getSelectedOutlineSnapTargets)({
452
+ compositionHeight,
453
+ compositionWidth,
454
+ guides: guidesForSnap,
455
+ });
456
+ }, [compositionHeight, compositionWidth, guidesForSnap]);
407
457
  const saveKeyboardNudgeSession = (0, react_1.useCallback)(() => {
408
458
  const session = keyboardNudgeSessionRef.current;
409
459
  if (session === null) {
@@ -671,6 +721,7 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
671
721
  if (outlineTargets.length === 0) {
672
722
  return null;
673
723
  }
674
- return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineElement, { allDragTargets: allDragTargets, allRotationDragTargets: allRotationDragTargets, allScaleDragTargets: allScaleDragTargets, dragging: draggingOutline, hovered: hoveredOutlineKey === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: setHoveredOutlineKey, onSelect: selectOutlineItem, scale: scale, target: targetsByKey.get(outline.key) }, outline.key))), 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`)))] }));
724
+ return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [
725
+ 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: hoveredOutlineKey === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: setHoveredOutlineKey, 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`)))] }));
675
726
  };
676
727
  exports.SelectedOutlineOverlay = SelectedOutlineOverlay;
@@ -38,6 +38,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
40
40
  const colors_1 = require("../helpers/colors");
41
+ const editor_snapping_1 = require("../state/editor-snapping");
41
42
  const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
42
43
  const selected_outline_drag_1 = require("./selected-outline-drag");
43
44
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
@@ -55,7 +56,7 @@ const uvHandleRadius = 4.25;
55
56
  const selectedUvHandleRadius = 6.8;
56
57
  const ellipseControlRadius = 5.2;
57
58
  const uvHandleStyle = {
58
- filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.28))',
59
+ filter: colors_1.SELECTED_OUTLINE_UV_DROP_SHADOW,
59
60
  };
60
61
  const getSelectedOutlineUvHandleTimelineSelection = ({ effectIndex, fieldKey, nodePathInfo, }) => {
61
62
  return {
@@ -254,7 +255,7 @@ const SelectedUvEllipseStartHandle = ({ control, onDraggingChange, outline }) =>
254
255
  if (startControl === null || field === undefined) {
255
256
  return null;
256
257
  }
257
- return (jsx_runtime_1.jsx("circle", { cx: startControl.position.x, cy: startControl.position.y, r: ellipseControlRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: startControl.cursor, onPointerDown: onPointerDown }));
258
+ return (jsx_runtime_1.jsx("circle", { cx: startControl.position.x, cy: startControl.position.y, r: ellipseControlRadius, fill: colors_1.WHITE, stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: startControl.cursor, onPointerDown: onPointerDown }));
258
259
  };
259
260
  const SelectedUvEllipseResizeHandle = ({ axis, control, onDraggingChange, outline }) => {
260
261
  const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
@@ -354,7 +355,7 @@ const SelectedUvEllipseResizeHandle = ({ axis, control, onDraggingChange, outlin
354
355
  if (resizeControl === undefined || field === undefined) {
355
356
  return null;
356
357
  }
357
- return (jsx_runtime_1.jsx("circle", { cx: resizeControl.position.x, cy: resizeControl.position.y, r: ellipseControlRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: resizeControl.cursor, onPointerDown: onPointerDown }));
358
+ return (jsx_runtime_1.jsx("circle", { cx: resizeControl.position.x, cy: resizeControl.position.y, r: ellipseControlRadius, fill: colors_1.WHITE, stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: resizeControl.cursor, onPointerDown: onPointerDown }));
358
359
  };
359
360
  const snapRotationDegrees = (value) => Math.round(value / selected_outline_drag_1.selectedOutlineRotationSnapStepDegrees) *
360
361
  selected_outline_drag_1.selectedOutlineRotationSnapStepDegrees;
@@ -384,6 +385,7 @@ const trimLineToCircleEdges = ({ from, fromRadius, to, toRadius, }) => {
384
385
  };
385
386
  const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
386
387
  const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
388
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
387
389
  const { rotationControl } = control;
388
390
  const field = rotationControl === null || rotationControl === void 0 ? void 0 : rotationControl.field;
389
391
  const onPointerDown = react_1.default.useCallback((event) => {
@@ -413,7 +415,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
413
415
  let lastValue = null;
414
416
  const updateRotationDragOverride = () => {
415
417
  const rawValue = control.rotation + accumulatedDelta;
416
- const snappedValue = rotationLocked
418
+ const snappedValue = rotationLocked && editorSnapping
417
419
  ? snapRotationDegrees(rawValue)
418
420
  : rawValue;
419
421
  const nextValue = (0, selected_outline_uv_1.roundNumericUvEllipseValue)(snappedValue, field.fieldSchema);
@@ -497,6 +499,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
497
499
  }, [
498
500
  clearEffectDragOverrides,
499
501
  control,
502
+ editorSnapping,
500
503
  field,
501
504
  onDraggingChange,
502
505
  rotationControl,
@@ -517,11 +520,12 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
517
520
  toRadius: ellipseControlRadius,
518
521
  });
519
522
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
520
- jsx_runtime_1.jsx("line", { x1: connector.from.x, y1: connector.from.y, x2: connector.to.x, y2: connector.to.y, stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: "none" }), jsx_runtime_1.jsx("circle", { cx: rotationControl.position.x, cy: rotationControl.position.y, r: ellipseControlRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: (0, selected_outline_measurement_2.getRotationCursor)((0, selected_outline_measurement_2.getAngleDegrees)(control.center, rotationControl.position)), onPointerDown: onPointerDown })
523
+ jsx_runtime_1.jsx("line", { x1: connector.from.x, y1: connector.from.y, x2: connector.to.x, y2: connector.to.y, stroke: colors_1.BLUE, strokeWidth: 2, vectorEffect: "non-scaling-stroke", pointerEvents: "none" }), jsx_runtime_1.jsx("circle", { cx: rotationControl.position.x, cy: rotationControl.position.y, r: ellipseControlRadius, fill: colors_1.WHITE, stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: (0, selected_outline_measurement_2.getRotationCursor)((0, selected_outline_measurement_2.getAngleDegrees)(control.center, rotationControl.position)), onPointerDown: onPointerDown })
521
524
  ] }));
522
525
  };
523
526
  const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSelect, outline }) => {
524
527
  const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
528
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
525
529
  const position = (0, react_1.useMemo)(() => (0, selected_outline_uv_1.getUvHandlePosition)(outline.points, handle.value), [handle.value, outline.points]);
526
530
  const onPointerDown = react_1.default.useCallback((event) => {
527
531
  if (event.button !== 0) {
@@ -556,11 +560,13 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
556
560
  rect: svgRect,
557
561
  });
558
562
  const rawUv = (0, selected_outline_uv_1.getUvCoordinateForPoint)(outline.points, point);
559
- const snappedUv = (0, selected_outline_drag_1.snapSelectedOutlineUv)({
560
- point,
561
- points: outline.points,
562
- uv: rawUv,
563
- });
563
+ const snappedUv = editorSnapping
564
+ ? (0, selected_outline_drag_1.snapSelectedOutlineUv)({
565
+ point,
566
+ points: outline.points,
567
+ uv: rawUv,
568
+ })
569
+ : rawUv;
564
570
  const nextValue = (0, selected_outline_uv_1.roundUvCoordinate)((0, selected_outline_uv_1.constrainUv)(snappedUv, handle.fieldSchema), handle.fieldSchema);
565
571
  lastValue = nextValue;
566
572
  setEffectDragOverrides(handle.nodePath, handle.effectIndex, handle.fieldKey, handle.propStatus.status === 'keyframed'
@@ -644,6 +650,7 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
644
650
  window.addEventListener('pointercancel', onPointerUp);
645
651
  }, [
646
652
  clearEffectDragOverrides,
653
+ editorSnapping,
647
654
  handle,
648
655
  nodePathInfo,
649
656
  onDraggingChange,
@@ -652,7 +659,7 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
652
659
  setPropStatuses,
653
660
  setEffectDragOverrides,
654
661
  ]);
655
- return (jsx_runtime_1.jsx("circle", { cx: position.x, cy: position.y, r: handle.isSelected ? selectedUvHandleRadius : uvHandleRadius, fill: "white", stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: "default", onPointerDown: onPointerDown }));
662
+ return (jsx_runtime_1.jsx("circle", { cx: position.x, cy: position.y, r: handle.isSelected ? selectedUvHandleRadius : uvHandleRadius, fill: colors_1.WHITE, stroke: colors_1.BLUE, strokeWidth: 2, style: uvHandleStyle, vectorEffect: "non-scaling-stroke", pointerEvents: "all", cursor: "default", onPointerDown: onPointerDown }));
656
663
  };
657
664
  const SelectedOutlineUvHandleConnectionLayer = ({ outline, target }) => {
658
665
  if (!(target === null || target === void 0 ? void 0 : target.containsSelection) || target.uvHandles.length === 0) {
@@ -4,6 +4,7 @@ exports.SidebarCollapserControls = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
7
+ const colors_1 = require("../helpers/colors");
7
8
  const use_keybinding_1 = require("../helpers/use-keybinding");
8
9
  const sidebar_1 = require("../state/sidebar");
9
10
  const InlineAction_1 = require("./InlineAction");
@@ -12,9 +13,9 @@ const style = {
12
13
  width: 16,
13
14
  height: 16,
14
15
  minWidth: 16,
15
- border: '1px solid currentColor',
16
+ border: colors_1.BORDER_CURRENT_COLOR,
16
17
  borderRadius: 3,
17
- color: 'currentColor',
18
+ color: colors_1.CURRENT_COLOR,
18
19
  position: 'relative',
19
20
  };
20
21
  const SidebarCollapserControls = () => {
@@ -26,7 +27,7 @@ const SidebarCollapserControls = () => {
26
27
  width: '35%',
27
28
  height: '100%',
28
29
  borderRight: '1px solid ' + color,
29
- background: leftSidebarStatus === 'expanded' ? color : 'transparent',
30
+ background: leftSidebarStatus === 'expanded' ? color : colors_1.TRANSPARENT,
30
31
  };
31
32
  }, [leftSidebarStatus]);
32
33
  const rightIcon = (0, react_1.useCallback)((color) => {
@@ -36,7 +37,7 @@ const SidebarCollapserControls = () => {
36
37
  right: 0,
37
38
  position: 'absolute',
38
39
  borderLeft: '1px solid ' + color,
39
- background: sidebarCollapsedStateRight === 'expanded' ? color : 'transparent',
40
+ background: sidebarCollapsedStateRight === 'expanded' ? color : colors_1.TRANSPARENT,
40
41
  };
41
42
  }, [sidebarCollapsedStateRight]);
42
43
  const toggleLeft = (0, react_1.useCallback)(() => {
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const SnappingProvider: React.FC<{
3
+ readonly children: React.ReactNode;
4
+ }>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnappingProvider = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const editor_snapping_1 = require("../state/editor-snapping");
7
+ const SnappingProvider = ({ children }) => {
8
+ const [editorSnapping, setEditorSnappingState] = (0, react_1.useState)(() => (0, editor_snapping_1.loadEditorSnappingOption)());
9
+ const setEditorSnapping = (0, react_1.useCallback)((newValue) => {
10
+ setEditorSnappingState((prevState) => {
11
+ const newVal = newValue(prevState);
12
+ (0, editor_snapping_1.persistEditorSnappingOption)(newVal);
13
+ return newVal;
14
+ });
15
+ }, []);
16
+ const editorSnappingCtx = (0, react_1.useMemo)(() => {
17
+ return {
18
+ editorSnapping,
19
+ setEditorSnapping,
20
+ };
21
+ }, [editorSnapping, setEditorSnapping]);
22
+ return (jsx_runtime_1.jsx(editor_snapping_1.EditorSnappingContext.Provider, { value: editorSnappingCtx, children: children }));
23
+ };
24
+ exports.SnappingProvider = SnappingProvider;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const SnappingToggle: React.FC;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnappingToggle = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const no_react_1 = require("remotion/no-react");
7
+ const colors_1 = require("../helpers/colors");
8
+ const use_keybinding_1 = require("../helpers/use-keybinding");
9
+ const magnet_1 = require("../icons/magnet");
10
+ const editor_snapping_1 = require("../state/editor-snapping");
11
+ const ControlButton_1 = require("./ControlButton");
12
+ const SnappingToggle = () => {
13
+ const { editorSnapping, setEditorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
14
+ const onClick = (0, react_1.useCallback)(() => {
15
+ setEditorSnapping((current) => !current);
16
+ }, [setEditorSnapping]);
17
+ const color = editorSnapping ? colors_1.BLUE : colors_1.WHITE;
18
+ const accessibilityLabel = [
19
+ editorSnapping ? 'Disable snapping' : 'Enable snapping',
20
+ (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(Shift+M)',
21
+ ]
22
+ .filter(no_react_1.NoReactInternals.truthy)
23
+ .join(' ');
24
+ return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, "aria-pressed": editorSnapping, "aria-keyshortcuts": "Shift+M", onClick: onClick, children: jsx_runtime_1.jsx(magnet_1.MagnetIcon, { style: { width: 17, height: 17 }, fill: color, "aria-hidden": "true", focusable: "false" }) }));
25
+ };
26
+ exports.SnappingToggle = SnappingToggle;
@@ -14,7 +14,7 @@ export type TSplitterContext = {
14
14
  defaultFlex: number;
15
15
  id: string;
16
16
  persistFlex: (value: number) => void;
17
- isDragging: React.MutableRefObject<false | {
17
+ isDragging: React.RefObject<false | {
18
18
  x: number;
19
19
  y: number;
20
20
  }>;
@@ -4,6 +4,7 @@ exports.SplitterElement = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const colors_1 = require("../../helpers/colors");
7
8
  const SplitterContext_1 = require("./SplitterContext");
8
9
  const SplitterElement = ({ children, type, sticky }) => {
9
10
  const context = (0, react_1.useContext)(SplitterContext_1.SplitterContext);
@@ -24,7 +25,7 @@ const SplitterElement = ({ children, type, sticky }) => {
24
25
  left: (type === 'flexer' ? 0 : context.flexValue) * 100 + '%',
25
26
  width: (type === 'flexer' ? context.flexValue : 1 - context.flexValue) * 100 +
26
27
  '%',
27
- backgroundColor: (0, remotion_1.interpolateColors)((0, remotion_1.random)(context.flexValue), [0, 1], ['red', 'blue']),
28
+ backgroundColor: (0, remotion_1.interpolateColors)((0, remotion_1.random)(context.flexValue), [0, 1], [colors_1.RED, 'blue']),
28
29
  };
29
30
  }, [context.flexValue, type]);
30
31
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
@@ -11,7 +11,7 @@ const FilePreview_1 = require("./FilePreview");
11
11
  const use_static_files_1 = require("./use-static-files");
12
12
  const msgStyle = {
13
13
  fontSize: 13,
14
- color: 'white',
14
+ color: colors_1.WHITE,
15
15
  fontFamily: 'sans-serif',
16
16
  display: 'flex',
17
17
  justifyContent: 'center',