@remotion/studio 4.0.518 → 4.0.519
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AppLaunchButton.d.ts +16 -0
- package/dist/components/AppLaunchButton.js +90 -0
- package/dist/components/AssetSelector.js +7 -6
- package/dist/components/AssetSelectorItem.d.ts +12 -0
- package/dist/components/AssetSelectorItem.js +180 -62
- package/dist/components/Button.js +20 -7
- package/dist/components/Canvas.js +109 -78
- package/dist/components/CanvasOrLoading.js +7 -7
- package/dist/components/CodingAgentButton.d.ts +7 -0
- package/dist/components/CodingAgentButton.js +59 -0
- package/dist/components/CompositionContextButton.d.ts +1 -0
- package/dist/components/CompositionContextButton.js +6 -3
- package/dist/components/CompositionSelector.js +15 -10
- package/dist/components/CompositionSelectorItem.js +16 -23
- package/dist/components/ConfigureLicenseModal.js +4 -48
- package/dist/components/CurrentAsset.js +1 -1
- package/dist/components/ElementInstallConfirmation.d.ts +20 -7
- package/dist/components/ElementInstallConfirmation.js +325 -32
- package/dist/components/FixComputedValueModal.js +5 -131
- package/dist/components/InitialCompositionLoader.js +3 -2
- package/dist/components/InspectorOpenInEditor.js +48 -33
- package/dist/components/InspectorPanel/CompositionInspector.js +35 -3
- package/dist/components/InspectorPanel/CompositionInspectorHeader.js +22 -14
- package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +3 -1
- package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
- package/dist/components/InspectorPanel/SequenceInspectorHeader.js +10 -5
- package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -1
- package/dist/components/InspectorPanel/common.js +1 -0
- package/dist/components/InspectorPanel/styles.js +1 -0
- package/dist/components/InspectorSequenceSection.js +8 -3
- package/dist/components/InspectorSourceLocation.js +5 -1
- package/dist/components/KnownBugs.d.ts +1 -1
- package/dist/components/KnownBugs.js +1 -1
- package/dist/components/LicenseExplanation.d.ts +2 -0
- package/dist/components/LicenseExplanation.js +63 -0
- package/dist/components/MenuToolbar.js +7 -1
- package/dist/components/Modals.js +1 -2
- package/dist/components/NewComposition/InputDragger.js +29 -2
- package/dist/components/NewComposition/NewCompDuration.js +1 -1
- package/dist/components/NewComposition/NewComposition.d.ts +23 -0
- package/dist/components/NewComposition/NewComposition.js +217 -80
- package/dist/components/{UpdateModal/OpenIssueButton.js → OpenIssueButton.js} +1 -1
- package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +2 -1
- package/dist/components/QuickSwitcher/QuickSwitcherContent.js +21 -13
- package/dist/components/RenderQueue/actions.d.ts +1 -0
- package/dist/components/RenderQueue/actions.js +5 -1
- package/dist/components/SelectedOutlineCanvasRotation.js +27 -1
- package/dist/components/SelectedOutlineElement.js +2 -1
- package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -2
- package/dist/components/SelectedOutlineOverlay.d.ts +3 -1
- package/dist/components/SelectedOutlineOverlay.js +21 -26
- package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
- package/dist/components/SelectedOutlinePolygon.js +12 -4
- package/dist/components/SelectedOutlineRenderer.js +88 -21
- package/dist/components/SettingsContext.js +2 -1
- package/dist/components/SettingsModal.d.ts +1 -1
- package/dist/components/SettingsModal.js +19 -3
- package/dist/components/SidebarRenderButton.d.ts +1 -0
- package/dist/components/SidebarRenderButton.js +14 -5
- package/dist/components/Timeline/SequencePropsObserver.js +29 -14
- package/dist/components/Timeline/TimelineKeyframeControls.js +3 -1
- package/dist/components/Timeline/TimelineRowChrome.js +4 -2
- package/dist/components/Timeline/TimelineSequence.js +40 -8
- package/dist/components/Timeline/TimelineSequenceItem.js +34 -1
- package/dist/components/Timeline/TimelineStack/get-stack.d.ts +1 -0
- package/dist/components/Timeline/TimelineStack/get-stack.js +35 -3
- package/dist/components/Timeline/duplicate-selected-timeline-item.js +23 -25
- package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -0
- package/dist/components/Timeline/get-sequence-context-menu-items.js +34 -1
- package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -0
- package/dist/components/Timeline/sequence-props-subscription-store.js +22 -1
- package/dist/components/Timeline/use-sequence-props-subscription.js +7 -0
- package/dist/components/TimelineCombobox.js +1 -0
- package/dist/components/UpdateCheck.d.ts +0 -8
- package/dist/components/UpdateCheck.js +7 -54
- package/dist/components/UpdateStatusContext.d.ts +18 -0
- package/dist/components/UpdateStatusContext.js +74 -0
- package/dist/components/UpdatesSettings.d.ts +2 -0
- package/dist/components/UpdatesSettings.js +251 -0
- package/dist/components/WebMcp.js +3 -3
- package/dist/components/get-open-in-menu-items.d.ts +4 -0
- package/dist/components/get-open-in-menu-items.js +28 -24
- package/dist/components/root-composition-menu-items.d.ts +4 -1
- package/dist/components/root-composition-menu-items.js +38 -1
- package/dist/components/selected-outline-geometry.d.ts +21 -2
- package/dist/components/selected-outline-geometry.js +16 -5
- package/dist/components/selected-outline-measurement.d.ts +40 -1
- package/dist/components/selected-outline-measurement.js +239 -1
- package/dist/components/selected-outline-order.d.ts +12 -0
- package/dist/components/selected-outline-order.js +251 -0
- package/dist/components/selected-outline-types.d.ts +15 -2
- package/dist/components/selected-outline-uv.js +106 -3
- package/dist/components/use-configure-default-apps.d.ts +1 -0
- package/dist/components/use-configure-default-apps.js +24 -0
- package/dist/error-overlay/remotion-overlay/CodeFrame.js +5 -6
- package/dist/error-overlay/remotion-overlay/CopyStackTrace.js +1 -1
- package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +47 -18
- package/dist/error-overlay/remotion-overlay/ErrorLoader.js +1 -1
- package/dist/error-overlay/remotion-overlay/ErrorTitle.js +5 -4
- package/dist/error-overlay/remotion-overlay/OpenInEditor.js +48 -76
- package/dist/error-overlay/remotion-overlay/SearchGitHubIssues.js +1 -1
- package/dist/error-overlay/remotion-overlay/ShortcutHint.js +2 -2
- package/dist/error-overlay/remotion-overlay/StackFrame.js +13 -8
- package/dist/error-overlay/remotion-overlay/Symbolicating.js +1 -1
- package/dist/esm/{chunk-7prjt5n5.js → chunk-1fkq5bfq.js} +15439 -11610
- package/dist/esm/chunk-6jf1natv.js +25 -0
- package/dist/esm/{chunk-4bxz1d3g.js → chunk-je0h1bgt.js} +1 -28
- package/dist/esm/chunk-m0jqdbkr.js +14571 -0
- package/dist/esm/index.mjs +0 -2
- package/dist/esm/internals.mjs +32140 -13755
- package/dist/esm/previewEntry.mjs +35408 -17021
- package/dist/esm/renderEntry.mjs +6 -3
- package/dist/helpers/can-show-updates.d.ts +5 -0
- package/dist/helpers/can-show-updates.js +7 -0
- package/dist/helpers/colors.d.ts +0 -3
- package/dist/helpers/colors.js +2 -5
- package/dist/helpers/create-folder-tree.d.ts +5 -0
- package/dist/helpers/create-folder-tree.js +24 -1
- package/dist/helpers/get-asset-metadata.js +1 -1
- package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
- package/dist/helpers/get-box-quads-polyfill-internals.js +2403 -0
- package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
- package/dist/helpers/get-box-quads-ponyfill.js +23 -0
- package/dist/helpers/get-git-menu-item.d.ts +5 -0
- package/dist/helpers/get-git-menu-item.js +15 -1
- package/dist/helpers/hoverable.js +10 -5
- package/dist/helpers/open-in-editor.js +51 -1
- package/dist/helpers/preview-server-events.js +3 -0
- package/dist/helpers/timeline-layout.d.ts +0 -1
- package/dist/helpers/timeline-layout.js +1 -5
- package/dist/helpers/url-state.d.ts +1 -0
- package/dist/helpers/url-state.js +12 -5
- package/dist/renderEntry.js +2 -0
- package/dist/state/folders.d.ts +3 -0
- package/dist/state/folders.js +40 -1
- package/dist/state/modals.d.ts +1 -6
- package/package.json +17 -14
- package/dist/components/UpdateModal/UpdateModal.d.ts +0 -6
- package/dist/components/UpdateModal/UpdateModal.js +0 -104
- /package/dist/components/{UpdateModal/OpenIssueButton.d.ts → OpenIssueButton.d.ts} +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSelectedRotationInfo = exports.getSelectedTransformOriginInfo = exports.getSelectedCropInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.getSequenceKeysContainingSelection = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationCornerInfo = exports.getRotationCursor = exports.getSelectedOutlineRotationDeltaDegrees = exports.getAngleDegrees = exports.vectorBetween = exports.vectorLength = exports.dot = exports.getOutlineCenter = exports.midpoint = exports.pointToString = void 0;
|
|
3
|
+
exports.outlinesAreEqual = exports.measureOutlineTargets = exports.measureOutlines = exports.getSequencesWithSelectableOutlines = exports.getSelectedRotationInfo = exports.getSelectedTransformOriginInfo = exports.getSelectedCropInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.getSequenceKeysContainingSelection = exports.getSelectedSequenceKeys = exports.cropOutlinePoints = exports.getTransformedSvgViewportPoints = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationCornerInfo = exports.getRotationCursor = exports.getSelectedOutlineRotationDeltaDegrees = exports.getAngleDegrees = exports.vectorBetween = exports.vectorLength = exports.dot = exports.getOutlineCenter = exports.midpoint = exports.pointToString = void 0;
|
|
4
|
+
const calculate_timeline_1 = require("../helpers/calculate-timeline");
|
|
4
5
|
const colors_1 = require("../helpers/colors");
|
|
6
|
+
const get_box_quads_polyfill_internals_js_1 = require("../helpers/get-box-quads-polyfill-internals.js");
|
|
7
|
+
const get_box_quads_ponyfill_1 = require("../helpers/get-box-quads-ponyfill");
|
|
8
|
+
const timeline_node_path_key_1 = require("../helpers/timeline-node-path-key");
|
|
5
9
|
const selected_outline_geometry_1 = require("./selected-outline-geometry");
|
|
6
10
|
const selected_outline_types_1 = require("./selected-outline-types");
|
|
7
11
|
const selected_outline_uv_1 = require("./selected-outline-uv");
|
|
@@ -104,6 +108,128 @@ const getSelectedOutlineRotationPivot = ({ dimensions, points, transformOriginVa
|
|
|
104
108
|
return (0, selected_outline_uv_1.getUvHandlePosition)(points, uv);
|
|
105
109
|
};
|
|
106
110
|
exports.getSelectedOutlineRotationPivot = getSelectedOutlineRotationPivot;
|
|
111
|
+
const rectToPoints = (elementRect, containerRect) => {
|
|
112
|
+
const left = elementRect.left - containerRect.left;
|
|
113
|
+
const top = elementRect.top - containerRect.top;
|
|
114
|
+
const right = elementRect.right - containerRect.left;
|
|
115
|
+
const bottom = elementRect.bottom - containerRect.top;
|
|
116
|
+
return [
|
|
117
|
+
{ x: left, y: top },
|
|
118
|
+
{ x: right, y: top },
|
|
119
|
+
{ x: right, y: bottom },
|
|
120
|
+
{ x: left, y: bottom },
|
|
121
|
+
];
|
|
122
|
+
};
|
|
123
|
+
const getTransformedSvgViewportPoints = ({ viewport, ctm, containerRect, }) => {
|
|
124
|
+
const transformPoint = (x, y) => ({
|
|
125
|
+
x: ctm.a * x + ctm.c * y + ctm.e - containerRect.left,
|
|
126
|
+
y: ctm.b * x + ctm.d * y + ctm.f - containerRect.top,
|
|
127
|
+
});
|
|
128
|
+
const left = viewport.x;
|
|
129
|
+
const top = viewport.y;
|
|
130
|
+
const right = viewport.x + viewport.width;
|
|
131
|
+
const bottom = viewport.y + viewport.height;
|
|
132
|
+
return [
|
|
133
|
+
transformPoint(left, top),
|
|
134
|
+
transformPoint(right, top),
|
|
135
|
+
transformPoint(right, bottom),
|
|
136
|
+
transformPoint(left, bottom),
|
|
137
|
+
];
|
|
138
|
+
};
|
|
139
|
+
exports.getTransformedSvgViewportPoints = getTransformedSvgViewportPoints;
|
|
140
|
+
const quadToPoints = (quad, containerRect) => {
|
|
141
|
+
// `getBoxQuads`/the ponyfill returns the quad in viewport coordinates.
|
|
142
|
+
// The overlay <svg> is unscaled (the canvas `scale()`/pan live on a sibling
|
|
143
|
+
// container, not the svg), so 1 user unit == 1 px and we only need to move
|
|
144
|
+
// the quad into the svg's local space by subtracting its viewport origin.
|
|
145
|
+
// We deliberately do not pass `relativeTo` to the ponyfill: when the target
|
|
146
|
+
// is not an ancestor of the element, the polyfill cannot resolve the
|
|
147
|
+
// coordinate space and leaves the quad in viewport coordinates.
|
|
148
|
+
return [
|
|
149
|
+
{ x: quad.p1.x - containerRect.left, y: quad.p1.y - containerRect.top },
|
|
150
|
+
{ x: quad.p2.x - containerRect.left, y: quad.p2.y - containerRect.top },
|
|
151
|
+
{ x: quad.p3.x - containerRect.left, y: quad.p3.y - containerRect.top },
|
|
152
|
+
{ x: quad.p4.x - containerRect.left, y: quad.p4.y - containerRect.top },
|
|
153
|
+
];
|
|
154
|
+
};
|
|
155
|
+
const isSvgSvgElement = (element) => {
|
|
156
|
+
var _a;
|
|
157
|
+
const ownerSvgSvgElement = (_a = element.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.SVGSVGElement;
|
|
158
|
+
return ((typeof SVGSVGElement !== 'undefined' &&
|
|
159
|
+
element instanceof SVGSVGElement) ||
|
|
160
|
+
(ownerSvgSvgElement !== undefined && element instanceof ownerSvgSvgElement));
|
|
161
|
+
};
|
|
162
|
+
const getSvgSvgElementViewport = (element) => {
|
|
163
|
+
const viewBox = element.viewBox.baseVal;
|
|
164
|
+
if (viewBox.width > 0 && viewBox.height > 0) {
|
|
165
|
+
return {
|
|
166
|
+
x: viewBox.x,
|
|
167
|
+
y: viewBox.y,
|
|
168
|
+
width: viewBox.width,
|
|
169
|
+
height: viewBox.height,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
x: 0,
|
|
174
|
+
y: 0,
|
|
175
|
+
width: element.width.baseVal.value,
|
|
176
|
+
height: element.height.baseVal.value,
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
const getSvgSvgElementOutlinePoints = (element, containerRect) => {
|
|
180
|
+
const ctm = element.getScreenCTM();
|
|
181
|
+
const viewport = getSvgSvgElementViewport(element);
|
|
182
|
+
if (ctm === null || (viewport.width === 0 && viewport.height === 0)) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
return (0, exports.getTransformedSvgViewportPoints)({
|
|
186
|
+
viewport,
|
|
187
|
+
ctm,
|
|
188
|
+
containerRect,
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
const getElementOutlinePoints = (element, containerRect, includeOutsideContainer) => {
|
|
192
|
+
const elementRect = element.getBoundingClientRect();
|
|
193
|
+
if (elementRect.width === 0 && elementRect.height === 0) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
if (!includeOutsideContainer &&
|
|
197
|
+
(elementRect.right <= containerRect.left ||
|
|
198
|
+
elementRect.left >= containerRect.right ||
|
|
199
|
+
elementRect.bottom <= containerRect.top ||
|
|
200
|
+
elementRect.top >= containerRect.bottom)) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
if (isSvgSvgElement(element)) {
|
|
204
|
+
return getSvgSvgElementOutlinePoints(element, containerRect);
|
|
205
|
+
}
|
|
206
|
+
const quads = (0, get_box_quads_ponyfill_1.getBoxQuadsPonyfill)(element, {
|
|
207
|
+
box: 'border',
|
|
208
|
+
});
|
|
209
|
+
const quad = quads === null || quads === void 0 ? void 0 : quads[0];
|
|
210
|
+
if (!quad) {
|
|
211
|
+
return rectToPoints(elementRect, containerRect);
|
|
212
|
+
}
|
|
213
|
+
return quadToPoints(quad, containerRect);
|
|
214
|
+
};
|
|
215
|
+
const cropOutlinePoints = (points, crop) => {
|
|
216
|
+
if (crop.left === 0 &&
|
|
217
|
+
crop.right === 0 &&
|
|
218
|
+
crop.top === 0 &&
|
|
219
|
+
crop.bottom === 0) {
|
|
220
|
+
return points;
|
|
221
|
+
}
|
|
222
|
+
const { left, top } = crop;
|
|
223
|
+
const right = 1 - crop.right;
|
|
224
|
+
const bottom = 1 - crop.bottom;
|
|
225
|
+
return [
|
|
226
|
+
(0, selected_outline_uv_1.getUvHandlePosition)(points, [left, top]),
|
|
227
|
+
(0, selected_outline_uv_1.getUvHandlePosition)(points, [right, top]),
|
|
228
|
+
(0, selected_outline_uv_1.getUvHandlePosition)(points, [right, bottom]),
|
|
229
|
+
(0, selected_outline_uv_1.getUvHandlePosition)(points, [left, bottom]),
|
|
230
|
+
];
|
|
231
|
+
};
|
|
232
|
+
exports.cropOutlinePoints = cropOutlinePoints;
|
|
107
233
|
const getSelectedSequenceKeys = (selectedItems) => {
|
|
108
234
|
return new Set(selectedItems
|
|
109
235
|
.filter((item) => item.type === 'sequence')
|
|
@@ -262,3 +388,115 @@ const getSelectedRotationInfo = (selectedItems) => {
|
|
|
262
388
|
};
|
|
263
389
|
};
|
|
264
390
|
exports.getSelectedRotationInfo = getSelectedRotationInfo;
|
|
391
|
+
const getSequencesWithSelectableOutlines = ({ sequences, overrideIdsToNodePaths, compositions = [], timelinePosition, }) => {
|
|
392
|
+
return (0, calculate_timeline_1.calculateTimeline)({
|
|
393
|
+
sequences: [...sequences],
|
|
394
|
+
overrideIdsToNodePaths,
|
|
395
|
+
compositions,
|
|
396
|
+
})
|
|
397
|
+
.filter((track) => {
|
|
398
|
+
if (track.nodePathInfo === null) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
return (track.sequence.showInTimeline &&
|
|
402
|
+
timelinePosition >= track.sequence.from &&
|
|
403
|
+
timelinePosition < track.sequence.from + track.sequence.duration &&
|
|
404
|
+
track.nodePathInfo.auxiliaryKeys.length === 0);
|
|
405
|
+
})
|
|
406
|
+
.filter((track) => track.sequence.refForOutline !== null)
|
|
407
|
+
.sort((a, b) => a.depth - b.depth)
|
|
408
|
+
.map((track) => {
|
|
409
|
+
if (track.nodePathInfo === null) {
|
|
410
|
+
throw new Error('Expected selected outline to have a node path');
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
depth: track.depth,
|
|
414
|
+
keyframeDisplayOffset: track.keyframeDisplayOffset,
|
|
415
|
+
key: (0, TimelineSelection_1.getTimelineSequenceSelectionKey)(track.nodePathInfo),
|
|
416
|
+
nodePathInfo: track.nodePathInfo,
|
|
417
|
+
sequence: track.sequence,
|
|
418
|
+
};
|
|
419
|
+
});
|
|
420
|
+
};
|
|
421
|
+
exports.getSequencesWithSelectableOutlines = getSequencesWithSelectableOutlines;
|
|
422
|
+
const measureOutlines = (container, targets, hoveredTimelineNodePathKey) => {
|
|
423
|
+
return (0, exports.measureOutlineTargets)(container, targets.map((target) => ({
|
|
424
|
+
crop: target.crop,
|
|
425
|
+
includeOutsideContainer: target.showSelectedOutline ||
|
|
426
|
+
(0, timeline_node_path_key_1.timelineSequenceNodePathToKey)(target.nodePathInfo.sequenceSubscriptionKey) === hoveredTimelineNodePathKey,
|
|
427
|
+
key: target.key,
|
|
428
|
+
ref: target.ref,
|
|
429
|
+
})));
|
|
430
|
+
};
|
|
431
|
+
exports.measureOutlines = measureOutlines;
|
|
432
|
+
const measureOutlineTargets = (container, targets) => {
|
|
433
|
+
// Reuse shared ancestor geometry within this synchronous batch only.
|
|
434
|
+
(0, get_box_quads_polyfill_internals_js_1.useCache)();
|
|
435
|
+
const containerRect = container.getBoundingClientRect();
|
|
436
|
+
const outlines = [];
|
|
437
|
+
for (const target of targets) {
|
|
438
|
+
const element = target.ref.current;
|
|
439
|
+
if (element === null) {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
const uncroppedPoints = getElementOutlinePoints(element, containerRect, target.includeOutsideContainer);
|
|
443
|
+
if (uncroppedPoints === null) {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
const points = (0, exports.cropOutlinePoints)(uncroppedPoints, target.crop);
|
|
447
|
+
outlines.push({
|
|
448
|
+
key: target.key,
|
|
449
|
+
dimensions: element instanceof HTMLElement
|
|
450
|
+
? {
|
|
451
|
+
width: element.offsetWidth,
|
|
452
|
+
height: element.offsetHeight,
|
|
453
|
+
}
|
|
454
|
+
: element instanceof SVGSVGElement
|
|
455
|
+
? {
|
|
456
|
+
width: element.width.baseVal.value,
|
|
457
|
+
height: element.height.baseVal.value,
|
|
458
|
+
}
|
|
459
|
+
: null,
|
|
460
|
+
uncroppedPoints,
|
|
461
|
+
points,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
return outlines;
|
|
465
|
+
};
|
|
466
|
+
exports.measureOutlineTargets = measureOutlineTargets;
|
|
467
|
+
const outlinesAreEqual = (a, b) => {
|
|
468
|
+
var _a, _b, _c, _d;
|
|
469
|
+
if (a.length !== b.length) {
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
for (let i = 0; i < a.length; i++) {
|
|
473
|
+
if (a[i].key !== b[i].key) {
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
if (((_a = a[i].dimensions) === null || _a === void 0 ? void 0 : _a.width) !== ((_b = b[i].dimensions) === null || _b === void 0 ? void 0 : _b.width) ||
|
|
477
|
+
((_c = a[i].dimensions) === null || _c === void 0 ? void 0 : _c.height) !== ((_d = b[i].dimensions) === null || _d === void 0 ? void 0 : _d.height)) {
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
const aUncropped = a[i].uncroppedPoints;
|
|
481
|
+
const bUncropped = b[i].uncroppedPoints;
|
|
482
|
+
if ((aUncropped === null) !== (bUncropped === null)) {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
if (aUncropped !== null && bUncropped !== null) {
|
|
486
|
+
for (let j = 0; j < aUncropped.length; j++) {
|
|
487
|
+
if (Math.abs(aUncropped[j].x - bUncropped[j].x) > 0.01 ||
|
|
488
|
+
Math.abs(aUncropped[j].y - bUncropped[j].y) > 0.01) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
for (let j = 0; j < a[i].points.length; j++) {
|
|
494
|
+
if (Math.abs(a[i].points[j].x - b[i].points[j].x) > 0.01 ||
|
|
495
|
+
Math.abs(a[i].points[j].y - b[i].points[j].y) > 0.01) {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return true;
|
|
501
|
+
};
|
|
502
|
+
exports.outlinesAreEqual = outlinesAreEqual;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SelectedOutline } from './selected-outline-geometry';
|
|
2
|
+
import type { SelectedOutlineLayoutTarget } from './selected-outline-types';
|
|
3
|
+
type OutlineSequenceParent = {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly parent: string | null;
|
|
6
|
+
};
|
|
7
|
+
export declare const orderOutlinesForRendering: ({ outlines, sequences, targetsByKey, }: {
|
|
8
|
+
readonly outlines: readonly SelectedOutline[];
|
|
9
|
+
readonly sequences: readonly OutlineSequenceParent[];
|
|
10
|
+
readonly targetsByKey: ReadonlyMap<string, SelectedOutlineLayoutTarget>;
|
|
11
|
+
}) => readonly SelectedOutline[];
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.orderOutlinesForRendering = void 0;
|
|
4
|
+
const outlinePointEqualityTolerance = 0.5;
|
|
5
|
+
const outlineAreaEqualityTolerance = 0.5;
|
|
6
|
+
const outlineBoundsOverlapTolerance = 0.5;
|
|
7
|
+
const outlinePointsAreEquivalent = (a, b) => {
|
|
8
|
+
return (Math.abs(a.x - b.x) <= outlinePointEqualityTolerance &&
|
|
9
|
+
Math.abs(a.y - b.y) <= outlinePointEqualityTolerance);
|
|
10
|
+
};
|
|
11
|
+
const outlinesHaveEquivalentHitArea = (a, b) => {
|
|
12
|
+
if (a.points.length !== b.points.length) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
for (let startIndex = 0; startIndex < b.points.length; startIndex++) {
|
|
16
|
+
for (const direction of [1, -1]) {
|
|
17
|
+
const pointsMatch = a.points.every((point, index) => {
|
|
18
|
+
const bIndex = (startIndex + direction * index + b.points.length) % b.points.length;
|
|
19
|
+
return outlinePointsAreEquivalent(point, b.points[bIndex]);
|
|
20
|
+
});
|
|
21
|
+
if (pointsMatch) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
28
|
+
const getOutlineHitArea = (outline) => {
|
|
29
|
+
let area = 0;
|
|
30
|
+
for (let i = 0; i < outline.points.length; i++) {
|
|
31
|
+
const current = outline.points[i];
|
|
32
|
+
const next = outline.points[(i + 1) % outline.points.length];
|
|
33
|
+
area += current.x * next.y - next.x * current.y;
|
|
34
|
+
}
|
|
35
|
+
return Math.abs(area) / 2;
|
|
36
|
+
};
|
|
37
|
+
const getOutlineBounds = (outline) => {
|
|
38
|
+
const xs = outline.points.map((point) => point.x);
|
|
39
|
+
const ys = outline.points.map((point) => point.y);
|
|
40
|
+
return {
|
|
41
|
+
maxX: Math.max(...xs),
|
|
42
|
+
maxY: Math.max(...ys),
|
|
43
|
+
minX: Math.min(...xs),
|
|
44
|
+
minY: Math.min(...ys),
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
const outlineBoundsOverlap = (a, b) => {
|
|
48
|
+
const aBounds = getOutlineBounds(a);
|
|
49
|
+
const bBounds = getOutlineBounds(b);
|
|
50
|
+
return (aBounds.minX <= bBounds.maxX + outlineBoundsOverlapTolerance &&
|
|
51
|
+
aBounds.maxX + outlineBoundsOverlapTolerance >= bBounds.minX &&
|
|
52
|
+
aBounds.minY <= bBounds.maxY + outlineBoundsOverlapTolerance &&
|
|
53
|
+
aBounds.maxY + outlineBoundsOverlapTolerance >= bBounds.minY);
|
|
54
|
+
};
|
|
55
|
+
const getSequenceId = (target) => {
|
|
56
|
+
var _a;
|
|
57
|
+
var _b;
|
|
58
|
+
return (_b = (_a = target === null || target === void 0 ? void 0 : target.sequence) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
|
|
59
|
+
};
|
|
60
|
+
const getParentBySequenceId = ({ sequences, targetsByKey, }) => {
|
|
61
|
+
const parentBySequenceId = new Map();
|
|
62
|
+
for (const sequence of sequences) {
|
|
63
|
+
parentBySequenceId.set(sequence.id, sequence.parent);
|
|
64
|
+
}
|
|
65
|
+
for (const target of targetsByKey.values()) {
|
|
66
|
+
const sequenceId = getSequenceId(target);
|
|
67
|
+
if (sequenceId !== null && !parentBySequenceId.has(sequenceId)) {
|
|
68
|
+
parentBySequenceId.set(sequenceId, target.sequence.parent);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return parentBySequenceId;
|
|
72
|
+
};
|
|
73
|
+
const isAncestorTarget = ({ ancestor, descendant, parentBySequenceId, }) => {
|
|
74
|
+
var _a;
|
|
75
|
+
var _b, _c;
|
|
76
|
+
const ancestorId = getSequenceId(ancestor);
|
|
77
|
+
if (ancestorId === null) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
let parentId = (_b = (_a = descendant.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
|
|
81
|
+
while (parentId !== null) {
|
|
82
|
+
if (parentId === ancestorId) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
parentId = (_c = parentBySequenceId.get(parentId)) !== null && _c !== void 0 ? _c : null;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
};
|
|
89
|
+
const orderOutlineGroup = ({ outlines, parentBySequenceId, targetsByKey, }) => {
|
|
90
|
+
var _a;
|
|
91
|
+
var _b, _c, _d, _e;
|
|
92
|
+
const incomingEdges = new Map();
|
|
93
|
+
const outgoingEdges = new Map();
|
|
94
|
+
const outlinesByKey = new Map(outlines.map((outline) => [outline.key, outline]));
|
|
95
|
+
for (const outline of outlines) {
|
|
96
|
+
incomingEdges.set(outline.key, new Set());
|
|
97
|
+
outgoingEdges.set(outline.key, new Set());
|
|
98
|
+
}
|
|
99
|
+
const hasPath = ({ fromKey, seen, toKey, }) => {
|
|
100
|
+
var _a;
|
|
101
|
+
if (fromKey === toKey) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
if (seen.has(fromKey)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
seen.add(fromKey);
|
|
108
|
+
for (const nextKey of (_a = outgoingEdges.get(fromKey)) !== null && _a !== void 0 ? _a : []) {
|
|
109
|
+
if (hasPath({ fromKey: nextKey, seen, toKey })) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
const addEdge = (before, after, options) => {
|
|
116
|
+
if (before.key === after.key) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const incoming = incomingEdges.get(after.key);
|
|
120
|
+
const outgoing = outgoingEdges.get(before.key);
|
|
121
|
+
if (incoming === undefined || outgoing === undefined) {
|
|
122
|
+
throw new Error('Expected outline to be registered before adding edge');
|
|
123
|
+
}
|
|
124
|
+
if (outgoing.has(after.key)) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (hasPath({ fromKey: after.key, seen: new Set(), toKey: before.key })) {
|
|
128
|
+
if (options === null || options === void 0 ? void 0 : options.skipIfCycle) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
throw new Error('Could not determine a stable outline rendering order');
|
|
132
|
+
}
|
|
133
|
+
incoming.add(before.key);
|
|
134
|
+
outgoing.add(after.key);
|
|
135
|
+
};
|
|
136
|
+
const addAncestorConstraint = ({ ancestor, descendant, descendantContainsSelection, equivalentHitArea, }) => {
|
|
137
|
+
// Usually, children should be above parents so nested elements are directly
|
|
138
|
+
// selectable. If an unselected child has the same hit area as its parent, put
|
|
139
|
+
// it below the parent so the wrapper can be selected. Once the child or
|
|
140
|
+
// one of its properties is selected, keep it above the parent so it remains
|
|
141
|
+
// directly draggable.
|
|
142
|
+
if (equivalentHitArea && !descendantContainsSelection) {
|
|
143
|
+
addEdge(descendant, ancestor);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
addEdge(ancestor, descendant);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const outlineBySequenceId = new Map();
|
|
150
|
+
for (const outline of outlines) {
|
|
151
|
+
const sequenceId = getSequenceId(targetsByKey.get(outline.key));
|
|
152
|
+
if (sequenceId !== null) {
|
|
153
|
+
outlineBySequenceId.set(sequenceId, outline);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Only constrain each outline against its nearest rendered ancestor. The
|
|
157
|
+
// resulting graph follows the sequence tree, so pairwise subpixel equivalence
|
|
158
|
+
// cannot introduce contradictory edges across three nested outlines.
|
|
159
|
+
for (const descendant of outlines) {
|
|
160
|
+
const descendantTarget = targetsByKey.get(descendant.key);
|
|
161
|
+
let parentId = (_b = (_a = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
|
|
162
|
+
while (parentId !== null) {
|
|
163
|
+
const ancestor = outlineBySequenceId.get(parentId);
|
|
164
|
+
if (ancestor !== undefined) {
|
|
165
|
+
addAncestorConstraint({
|
|
166
|
+
ancestor,
|
|
167
|
+
descendant,
|
|
168
|
+
descendantContainsSelection: ((_c = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.selected) !== null && _c !== void 0 ? _c : false) ||
|
|
169
|
+
((_d = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.containsSelection) !== null && _d !== void 0 ? _d : false),
|
|
170
|
+
equivalentHitArea: outlinesHaveEquivalentHitArea(ancestor, descendant),
|
|
171
|
+
});
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
parentId = (_e = parentBySequenceId.get(parentId)) !== null && _e !== void 0 ? _e : null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// For unrelated overlapping outlines, put broader hit targets below
|
|
178
|
+
// smaller ones so a large selected sequence cannot swallow clicks on
|
|
179
|
+
// a more specific element in the same canvas area.
|
|
180
|
+
for (let i = 0; i < outlines.length; i++) {
|
|
181
|
+
for (let j = i + 1; j < outlines.length; j++) {
|
|
182
|
+
const a = outlines[i];
|
|
183
|
+
const b = outlines[j];
|
|
184
|
+
const aTarget = targetsByKey.get(a.key);
|
|
185
|
+
const bTarget = targetsByKey.get(b.key);
|
|
186
|
+
if (aTarget === undefined || bTarget === undefined) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const aAncestorOfB = isAncestorTarget({
|
|
190
|
+
ancestor: aTarget,
|
|
191
|
+
descendant: bTarget,
|
|
192
|
+
parentBySequenceId,
|
|
193
|
+
});
|
|
194
|
+
const bAncestorOfA = isAncestorTarget({
|
|
195
|
+
ancestor: bTarget,
|
|
196
|
+
descendant: aTarget,
|
|
197
|
+
parentBySequenceId,
|
|
198
|
+
});
|
|
199
|
+
if (aAncestorOfB || bAncestorOfA || !outlineBoundsOverlap(a, b)) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const aArea = getOutlineHitArea(a);
|
|
203
|
+
const bArea = getOutlineHitArea(b);
|
|
204
|
+
if (Math.abs(aArea - bArea) <= outlineAreaEqualityTolerance) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (aArea > bArea) {
|
|
208
|
+
addEdge(a, b, { skipIfCycle: true });
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
addEdge(b, a, { skipIfCycle: true });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const emitted = new Set();
|
|
216
|
+
const visiting = new Set();
|
|
217
|
+
const ordered = [];
|
|
218
|
+
const visit = (outline) => {
|
|
219
|
+
var _a;
|
|
220
|
+
if (emitted.has(outline.key)) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (visiting.has(outline.key)) {
|
|
224
|
+
throw new Error('Could not determine a stable outline rendering order');
|
|
225
|
+
}
|
|
226
|
+
visiting.add(outline.key);
|
|
227
|
+
for (const dependencyKey of (_a = incomingEdges.get(outline.key)) !== null && _a !== void 0 ? _a : []) {
|
|
228
|
+
const dependency = outlinesByKey.get(dependencyKey);
|
|
229
|
+
if (dependency === undefined) {
|
|
230
|
+
throw new Error('Expected outline dependency to exist');
|
|
231
|
+
}
|
|
232
|
+
visit(dependency);
|
|
233
|
+
}
|
|
234
|
+
visiting.delete(outline.key);
|
|
235
|
+
emitted.add(outline.key);
|
|
236
|
+
ordered.push(outline);
|
|
237
|
+
};
|
|
238
|
+
for (const outline of outlines) {
|
|
239
|
+
visit(outline);
|
|
240
|
+
}
|
|
241
|
+
return ordered;
|
|
242
|
+
};
|
|
243
|
+
const orderOutlinesForRendering = ({ outlines, sequences, targetsByKey, }) => {
|
|
244
|
+
const parentBySequenceId = getParentBySequenceId({ sequences, targetsByKey });
|
|
245
|
+
return orderOutlineGroup({
|
|
246
|
+
outlines,
|
|
247
|
+
parentBySequenceId,
|
|
248
|
+
targetsByKey,
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
exports.orderOutlinesForRendering = orderOutlinesForRendering;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { CanvasOutlineTarget } from '@remotion/canvas';
|
|
2
1
|
import type { CanUpdateSequencePropStatus, CanUpdateSequencePropStatusKeyframed, CanUpdateSequencePropStatusStatic, InteractivitySchema, InteractivitySchemaField, SequencePropsSubscriptionKey, TSequence } from 'remotion';
|
|
3
2
|
import type { SequenceNodePathInfo } from '../helpers/get-timeline-sequence-sort-key';
|
|
4
3
|
import type { ComboboxValue } from './NewComposition/ComboBox';
|
|
5
4
|
import type { TimelineSelection } from './Timeline/TimelineSelection';
|
|
6
5
|
export type SelectedOutlineContextMenuOpenResult = false | readonly ComboboxValue[];
|
|
7
6
|
export type SelectedOutlineContextMenuOpenHandler = () => SelectedOutlineContextMenuOpenResult | Promise<SelectedOutlineContextMenuOpenResult>;
|
|
8
|
-
export type SelectedOutlineLayoutTarget =
|
|
7
|
+
export type SelectedOutlineLayoutTarget = {
|
|
9
8
|
readonly key: string;
|
|
10
9
|
readonly containsSelection: boolean;
|
|
11
10
|
readonly keyframeDisplayOffset: number;
|
|
12
11
|
readonly nodePathInfo: SequenceNodePathInfo;
|
|
12
|
+
readonly ref: React.RefObject<Element | null>;
|
|
13
13
|
readonly selected: boolean;
|
|
14
14
|
readonly selectedForCrop: boolean;
|
|
15
15
|
readonly selectedForRotation: boolean;
|
|
@@ -19,6 +19,12 @@ export type SelectedOutlineLayoutTarget = CanvasOutlineTarget & {
|
|
|
19
19
|
readonly transformOriginValue: string;
|
|
20
20
|
readonly selection: TimelineSelection;
|
|
21
21
|
readonly sequence: TSequence;
|
|
22
|
+
readonly crop: {
|
|
23
|
+
readonly left: number;
|
|
24
|
+
readonly right: number;
|
|
25
|
+
readonly top: number;
|
|
26
|
+
readonly bottom: number;
|
|
27
|
+
};
|
|
22
28
|
};
|
|
23
29
|
export type SelectedOutlineTarget = SelectedOutlineLayoutTarget & {
|
|
24
30
|
readonly canCrop: boolean;
|
|
@@ -139,6 +145,13 @@ export type SelectedOutlineRotationDragState = {
|
|
|
139
145
|
readonly startValue: string;
|
|
140
146
|
readonly target: SelectedOutlineRotationDragTarget;
|
|
141
147
|
};
|
|
148
|
+
export type SequenceWithSelectedOutline = {
|
|
149
|
+
readonly depth: number;
|
|
150
|
+
readonly keyframeDisplayOffset: number;
|
|
151
|
+
readonly key: string;
|
|
152
|
+
readonly nodePathInfo: SequenceNodePathInfo;
|
|
153
|
+
readonly sequence: TSequence;
|
|
154
|
+
};
|
|
142
155
|
export declare const translateFieldKey = "style.translate";
|
|
143
156
|
export declare const scaleFieldKey = "style.scale";
|
|
144
157
|
export declare const rotateFieldKey = "style.rotate";
|