@remotion/studio 4.0.492 → 4.0.494

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 (75) hide show
  1. package/dist/ResolveCompositionConfigInStudio.js +16 -6
  2. package/dist/components/Canvas.js +3 -0
  3. package/dist/components/CompositionSelector.js +1 -1
  4. package/dist/components/CompositionSelectorItem.js +1 -1
  5. package/dist/components/CurrentComposition.d.ts +1 -1
  6. package/dist/components/CurrentComposition.js +3 -4
  7. package/dist/components/InitialCompositionLoader.d.ts +1 -1
  8. package/dist/components/InitialCompositionLoader.js +6 -1
  9. package/dist/components/InspectorInfoHeader.d.ts +1 -0
  10. package/dist/components/InspectorInfoHeader.js +7 -2
  11. package/dist/components/InspectorPanel/CompositionDimensions.d.ts +6 -0
  12. package/dist/components/InspectorPanel/CompositionDimensions.js +173 -0
  13. package/dist/components/InspectorPanel/ConnectedCompositionsSection.d.ts +9 -0
  14. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +32 -0
  15. package/dist/components/InspectorPanel/DefaultInspector.js +6 -3
  16. package/dist/components/InspectorPanel/EasingInspector.js +3 -3
  17. package/dist/components/InspectorPanel/KeyframeInspector.js +6 -4
  18. package/dist/components/InspectorPanel/KeyframeSettings.js +1 -1
  19. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
  20. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +9 -6
  21. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +5 -2
  22. package/dist/components/InspectorPanel/common.d.ts +2 -1
  23. package/dist/components/InspectorPanel/common.js +11 -7
  24. package/dist/components/InspectorPanel/optimistic-composition-metadata.d.ts +22 -0
  25. package/dist/components/InspectorPanel/optimistic-composition-metadata.js +41 -0
  26. package/dist/components/InspectorPanel/styles.d.ts +2 -0
  27. package/dist/components/InspectorPanel/styles.js +7 -2
  28. package/dist/components/InspectorSequenceSection.js +2 -5
  29. package/dist/components/SelectedOutlineElement.js +21 -2
  30. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  31. package/dist/components/SelectedOutlineOverlay.js +4 -3
  32. package/dist/components/Timeline/Timeline.js +9 -1
  33. package/dist/components/Timeline/TimelineClipboardKeybindings.js +136 -1
  34. package/dist/components/Timeline/TimelineDeleteKeybindings.js +2 -0
  35. package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
  36. package/dist/components/Timeline/TimelineList.js +2 -1
  37. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -3
  38. package/dist/components/Timeline/TimelineSelection.js +19 -5
  39. package/dist/components/Timeline/TimelineSequence.d.ts +1 -0
  40. package/dist/components/Timeline/TimelineSequence.js +42 -6
  41. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -1
  42. package/dist/components/Timeline/TimelineSequenceItem.js +43 -8
  43. package/dist/components/Timeline/TimelineSequenceName.js +4 -0
  44. package/dist/components/Timeline/TimelineTrack.js +2 -1
  45. package/dist/components/Timeline/call-delete-keyframe.d.ts +1 -0
  46. package/dist/components/Timeline/call-delete-keyframe.js +4 -0
  47. package/dist/components/Timeline/delete-selected-keyframe.d.ts +4 -2
  48. package/dist/components/Timeline/delete-selected-keyframe.js +48 -5
  49. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +3 -1
  50. package/dist/components/Timeline/delete-selected-timeline-item.js +3 -1
  51. package/dist/components/Timeline/keyframe-clipboard.d.ts +34 -0
  52. package/dist/components/Timeline/keyframe-clipboard.js +278 -0
  53. package/dist/components/Timeline/timeline-field-display-utils.js +2 -1
  54. package/dist/components/Timeline/update-selected-easing.d.ts +1 -1
  55. package/dist/components/Timeline/update-selected-easing.js +4 -5
  56. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +3 -4
  57. package/dist/components/import-assets.d.ts +25 -3
  58. package/dist/components/import-assets.js +54 -15
  59. package/dist/components/selected-outline-measurement.d.ts +2 -5
  60. package/dist/components/selected-outline-measurement.js +3 -4
  61. package/dist/esm/{chunk-ewx0568t.js → chunk-tdncqycp.js} +5397 -4402
  62. package/dist/esm/internals.mjs +5397 -4402
  63. package/dist/esm/previewEntry.mjs +5987 -4996
  64. package/dist/esm/renderEntry.mjs +1 -1
  65. package/dist/helpers/calculate-timeline.d.ts +2 -1
  66. package/dist/helpers/calculate-timeline.js +36 -5
  67. package/dist/{components/InspectorPanel/get-compositions-matching-single-child.d.ts → helpers/get-connected-compositions.d.ts} +1 -1
  68. package/dist/{components/InspectorPanel/get-compositions-matching-single-child.js → helpers/get-connected-compositions.js} +3 -3
  69. package/dist/helpers/get-sequence-double-click-action.d.ts +12 -0
  70. package/dist/helpers/get-sequence-double-click-action.js +22 -0
  71. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -1
  72. package/dist/helpers/inject-css.js +0 -2
  73. package/package.json +11 -11
  74. package/dist/components/InspectorPanel/SequenceCompositionsSection.d.ts +0 -5
  75. package/dist/components/InspectorPanel/SequenceCompositionsSection.js +0 -37
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPasteKeyframeTarget = exports.getKeyframeClipboardDataFromSelections = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
5
+ const remotion_1 = require("remotion");
6
+ const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
7
+ const parse_keyframe_field_from_node_path_1 = require("./parse-keyframe-field-from-node-path");
8
+ const getKeyframeClipboardFieldType = ({ schema, fieldKey, }) => {
9
+ const field = remotion_1.Internals.getFlatSchemaWithAllKeys(schema)[fieldKey];
10
+ if (!field) {
11
+ return null;
12
+ }
13
+ return (0, studio_shared_1.isKeyframeClipboardFieldType)(field.type) ? field.type : null;
14
+ };
15
+ const getKeyframeFieldIdentity = (selection) => {
16
+ if (selection.type === 'keyframe' || selection.type === 'easing') {
17
+ return (0, parse_keyframe_field_from_node_path_1.parseKeyframeFieldFromNodePath)(selection.nodePathInfo.auxiliaryKeys);
18
+ }
19
+ if (selection.type === 'sequence-prop') {
20
+ return { type: 'sequence', fieldKey: selection.key };
21
+ }
22
+ if (selection.type === 'sequence-effect-prop') {
23
+ return {
24
+ type: 'effect',
25
+ effectIndex: selection.i,
26
+ fieldKey: selection.key,
27
+ };
28
+ }
29
+ return null;
30
+ };
31
+ const resolveKeyframeField = ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }) => {
32
+ var _a, _b;
33
+ if (selection.type !== 'keyframe' &&
34
+ selection.type !== 'easing' &&
35
+ selection.type !== 'sequence-prop' &&
36
+ selection.type !== 'sequence-effect-prop') {
37
+ return null;
38
+ }
39
+ const identity = getKeyframeFieldIdentity(selection);
40
+ if (identity === null) {
41
+ return null;
42
+ }
43
+ const track = (0, find_track_for_node_path_info_1.findTrackForNodePathInfo)({
44
+ sequences,
45
+ overrideIdsToNodePaths,
46
+ nodePathInfo: selection.nodePathInfo,
47
+ });
48
+ if (!track || track.nodePathInfo === null) {
49
+ return null;
50
+ }
51
+ const nodePath = track.nodePathInfo.sequenceSubscriptionKey;
52
+ if (identity.type === 'sequence') {
53
+ if (!track.sequence.controls) {
54
+ return null;
55
+ }
56
+ const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _a === void 0 ? void 0 : _a[identity.fieldKey];
57
+ if (!sequencePropStatus || sequencePropStatus.status === 'computed') {
58
+ return null;
59
+ }
60
+ const { schema } = track.sequence.controls;
61
+ return {
62
+ identity,
63
+ nodePath,
64
+ fileName: nodePath.absolutePath,
65
+ schema,
66
+ fieldType: getKeyframeClipboardFieldType({
67
+ schema,
68
+ fieldKey: identity.fieldKey,
69
+ }),
70
+ propStatus: sequencePropStatus,
71
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
72
+ };
73
+ }
74
+ const effect = track.sequence.effects[identity.effectIndex];
75
+ const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
76
+ propStatuses,
77
+ nodePath,
78
+ effectIndex: identity.effectIndex,
79
+ });
80
+ const effectPropStatus = effectStatus.type === 'can-update-effect'
81
+ ? (_b = effectStatus.props) === null || _b === void 0 ? void 0 : _b[identity.fieldKey]
82
+ : null;
83
+ if (!effect || !effectPropStatus || effectPropStatus.status === 'computed') {
84
+ return null;
85
+ }
86
+ return {
87
+ identity,
88
+ nodePath,
89
+ fileName: nodePath.absolutePath,
90
+ schema: effect.schema,
91
+ fieldType: getKeyframeClipboardFieldType({
92
+ schema: effect.schema,
93
+ fieldKey: identity.fieldKey,
94
+ }),
95
+ propStatus: effectPropStatus,
96
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
97
+ };
98
+ };
99
+ const areResolvedFieldsEqual = (first, second) => {
100
+ if (remotion_1.Internals.makeSequencePropsSubscriptionKey(first.nodePath) !==
101
+ remotion_1.Internals.makeSequencePropsSubscriptionKey(second.nodePath)) {
102
+ return false;
103
+ }
104
+ if (first.identity.type !== second.identity.type) {
105
+ return false;
106
+ }
107
+ if (first.identity.fieldKey !== second.identity.fieldKey) {
108
+ return false;
109
+ }
110
+ return (first.identity.type === 'sequence' ||
111
+ (second.identity.type === 'effect' &&
112
+ first.identity.effectIndex === second.identity.effectIndex));
113
+ };
114
+ const getKeyframeClipboardDataFromSelections = ({ selections, sequences, overrideIdsToNodePaths, propStatuses, }) => {
115
+ var _a, _b;
116
+ const keyframeSelections = selections.filter((selection) => selection.type === 'keyframe');
117
+ const easingSelections = selections.filter((selection) => selection.type === 'easing');
118
+ if (keyframeSelections.length + easingSelections.length !==
119
+ selections.length) {
120
+ return null;
121
+ }
122
+ const resolvedFields = keyframeSelections.map((selection) => ({
123
+ selection,
124
+ resolved: resolveKeyframeField({
125
+ selection,
126
+ sequences,
127
+ overrideIdsToNodePaths,
128
+ propStatuses,
129
+ }),
130
+ }));
131
+ const firstResolved = (_a = resolvedFields[0]) === null || _a === void 0 ? void 0 : _a.resolved;
132
+ if (firstResolved === null ||
133
+ firstResolved === undefined ||
134
+ resolvedFields.some(({ resolved }) => resolved === null || !areResolvedFieldsEqual(firstResolved, resolved))) {
135
+ return null;
136
+ }
137
+ const keyframedPropStatus = firstResolved.propStatus;
138
+ if (keyframedPropStatus.status !== 'keyframed') {
139
+ return null;
140
+ }
141
+ const keyframes = [];
142
+ for (const { selection } of resolvedFields) {
143
+ const sourceFrame = selection.frame - firstResolved.keyframeDisplayOffset;
144
+ const keyframe = keyframedPropStatus.keyframes.find((item) => item.frame === sourceFrame);
145
+ if (keyframe === undefined ||
146
+ JSON.stringify(keyframe.value) === undefined) {
147
+ return null;
148
+ }
149
+ keyframes.push({ frame: sourceFrame, value: keyframe.value });
150
+ }
151
+ keyframes.sort((first, second) => first.frame - second.frame);
152
+ const firstFrame = (_b = keyframes[0]) === null || _b === void 0 ? void 0 : _b.frame;
153
+ if (firstFrame === undefined) {
154
+ return null;
155
+ }
156
+ const keyframeIndexes = keyframes.map((keyframe) => keyframedPropStatus.keyframes.findIndex((item) => item.frame === keyframe.frame));
157
+ if (keyframeIndexes.some((index, position) => index === -1 ||
158
+ (position > 0 && index !== keyframeIndexes[position - 1] + 1))) {
159
+ return null;
160
+ }
161
+ const firstKeyframeIndex = keyframeIndexes[0];
162
+ const lastKeyframeIndex = keyframeIndexes.at(-1);
163
+ if (firstKeyframeIndex === undefined || lastKeyframeIndex === undefined) {
164
+ return null;
165
+ }
166
+ for (const easingSelection of easingSelections) {
167
+ const resolved = resolveKeyframeField({
168
+ selection: easingSelection,
169
+ sequences,
170
+ overrideIdsToNodePaths,
171
+ propStatuses,
172
+ });
173
+ if (resolved === null ||
174
+ !areResolvedFieldsEqual(firstResolved, resolved) ||
175
+ easingSelection.segmentIndex < firstKeyframeIndex ||
176
+ easingSelection.segmentIndex >= lastKeyframeIndex) {
177
+ return null;
178
+ }
179
+ }
180
+ return {
181
+ type: 'keyframe',
182
+ version: 1,
183
+ remotionClipboard: 'keyframe',
184
+ fieldType: firstResolved.fieldType,
185
+ keyframes: keyframes.map((keyframe) => {
186
+ return {
187
+ frameOffset: keyframe.frame - firstFrame,
188
+ value: keyframe.value,
189
+ };
190
+ }),
191
+ easing: keyframeIndexes.slice(0, -1).map((index) => {
192
+ var _a;
193
+ return (_a = keyframedPropStatus.easing[index]) !== null && _a !== void 0 ? _a : studio_shared_1.LINEAR_KEYFRAME_EASING;
194
+ }),
195
+ };
196
+ };
197
+ exports.getKeyframeClipboardDataFromSelections = getKeyframeClipboardDataFromSelections;
198
+ const isKeyframeValueCompatible = ({ value, fieldType, }) => {
199
+ if (fieldType === null) {
200
+ return true;
201
+ }
202
+ if (fieldType === 'number' || fieldType === 'rotation-degrees') {
203
+ return typeof value === 'number' && Number.isFinite(value);
204
+ }
205
+ if (fieldType === 'scale') {
206
+ return ((typeof value === 'number' && Number.isFinite(value)) ||
207
+ typeof value === 'string');
208
+ }
209
+ if (fieldType === 'uv-coordinate') {
210
+ return (Array.isArray(value) &&
211
+ value.length === 2 &&
212
+ value.every((item) => typeof item === 'number' && Number.isFinite(item)));
213
+ }
214
+ return typeof value === 'string';
215
+ };
216
+ const getPasteKeyframeTarget = ({ selectedItems, payload, timelinePosition, sequences, overrideIdsToNodePaths, propStatuses, }) => {
217
+ var _a, _b;
218
+ if (selectedItems.length === 0) {
219
+ return { type: 'none' };
220
+ }
221
+ const selection = selectedItems[0];
222
+ if (!selection || getKeyframeFieldIdentity(selection) === null) {
223
+ return { type: 'none' };
224
+ }
225
+ const resolvedFields = selectedItems.map((item) => resolveKeyframeField({
226
+ selection: item,
227
+ sequences,
228
+ overrideIdsToNodePaths,
229
+ propStatuses,
230
+ }));
231
+ const resolved = resolvedFields[0];
232
+ if (resolved === null) {
233
+ return { type: 'uncopyable' };
234
+ }
235
+ if (resolvedFields.some((field) => field === null || !areResolvedFieldsEqual(resolved, field))) {
236
+ return { type: 'multiple' };
237
+ }
238
+ const keyframes = payload.keyframes.map((keyframe) => ({
239
+ sourceFrame: timelinePosition - resolved.keyframeDisplayOffset + keyframe.frameOffset,
240
+ value: keyframe.value,
241
+ }));
242
+ const firstFrame = (_a = keyframes[0]) === null || _a === void 0 ? void 0 : _a.sourceFrame;
243
+ const lastFrame = (_b = keyframes.at(-1)) === null || _b === void 0 ? void 0 : _b.sourceFrame;
244
+ if (firstFrame === undefined || lastFrame === undefined) {
245
+ return { type: 'incompatible' };
246
+ }
247
+ const existingFrames = resolved.propStatus.status === 'keyframed'
248
+ ? resolved.propStatus.keyframes.map((keyframe) => keyframe.frame)
249
+ : [];
250
+ const keyframesToDelete = existingFrames.filter((frame) => frame >= firstFrame && frame <= lastFrame);
251
+ const finalFrames = [
252
+ ...existingFrames.filter((frame) => frame < firstFrame || frame > lastFrame),
253
+ ...keyframes.map((keyframe) => keyframe.sourceFrame),
254
+ ].sort((first, second) => first - second);
255
+ const firstEasingSegmentIndex = finalFrames.indexOf(firstFrame);
256
+ if (resolved.fieldType !== payload.fieldType ||
257
+ payload.keyframes.some((keyframe) => !isKeyframeValueCompatible({
258
+ value: keyframe.value,
259
+ fieldType: payload.fieldType,
260
+ }))) {
261
+ return { type: 'incompatible' };
262
+ }
263
+ return {
264
+ type: 'valid',
265
+ fileName: resolved.fileName,
266
+ nodePath: resolved.nodePath,
267
+ fieldKey: resolved.identity.fieldKey,
268
+ effectIndex: resolved.identity.type === 'effect'
269
+ ? resolved.identity.effectIndex
270
+ : null,
271
+ keyframes,
272
+ keyframesToDelete,
273
+ easing: payload.easing,
274
+ firstEasingSegmentIndex,
275
+ schema: resolved.schema,
276
+ };
277
+ };
278
+ exports.getPasteKeyframeTarget = getPasteKeyframeTarget;
@@ -241,10 +241,11 @@ const formatTimelineFieldValueForDisplay = ({ fieldSchema, value, }) => {
241
241
  case 'boolean':
242
242
  case 'color':
243
243
  case 'enum':
244
+ case 'font-family':
244
245
  case 'hidden':
245
246
  return formatUnknownTimelineValueForDisplay(value);
246
247
  default:
247
- return formatUnknownTimelineValueForDisplay(value);
248
+ throw new Error(`Unsupported field type: ${fieldSchema}`);
248
249
  }
249
250
  };
250
251
  exports.formatTimelineFieldValueForDisplay = formatTimelineFieldValueForDisplay;
@@ -1,3 +1,4 @@
1
+ export { canEditEasingForInterpolationFunction } from '@remotion/studio-shared';
1
2
  import type { CanUpdateSequencePropStatusKeyframed, CanUpdateSequencePropStatusEasing, DragOverrideValue, OverrideIdToNodePaths, PropStatuses, SequencePropsSubscriptionKey, InteractivitySchema, TSequence } from 'remotion';
2
3
  import type { SetPropStatuses } from './save-sequence-prop';
3
4
  import type { TimelineEasingSelection, TimelineSelection } from './TimelineSelection';
@@ -23,7 +24,6 @@ export type SelectedEasingUpdate = {
23
24
  readonly currentEasing: TimelineEasingValue;
24
25
  readonly propStatus: CanUpdateSequencePropStatusKeyframed;
25
26
  };
26
- export declare const canEditEasingForInterpolationFunction: (interpolationFunction: string) => boolean;
27
27
  export declare const getSelectedEasingUpdate: ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }: {
28
28
  selection: {
29
29
  readonly type: "easing";
@@ -2,13 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.updateSelectedTimelineEasings = exports.getTimelineEasingValueForSelection = exports.getEasingSelections = exports.makeEasingDragOverride = exports.getSelectedEasingUpdates = exports.getSelectedEasingUpdate = exports.canEditEasingForInterpolationFunction = void 0;
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
+ const studio_shared_2 = require("@remotion/studio-shared");
6
+ Object.defineProperty(exports, "canEditEasingForInterpolationFunction", { enumerable: true, get: function () { return studio_shared_2.canEditEasingForInterpolationFunction; } });
5
7
  const remotion_1 = require("remotion");
6
8
  const call_update_keyframe_settings_1 = require("./call-update-keyframe-settings");
7
9
  const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
8
10
  const parse_keyframe_field_from_node_path_1 = require("./parse-keyframe-field-from-node-path");
9
- const canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
10
- interpolationFunction === 'interpolateColors';
11
- exports.canEditEasingForInterpolationFunction = canEditEasingForInterpolationFunction;
12
11
  const isEasingSelection = (selection) => selection.type === 'easing';
13
12
  const getSelectedEasingUpdate = ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }) => {
14
13
  var _a;
@@ -34,7 +33,7 @@ const getSelectedEasingUpdate = ({ selection, sequences, overrideIdsToNodePaths,
34
33
  }
35
34
  const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _a === void 0 ? void 0 : _a[field.fieldKey];
36
35
  if ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) !== 'keyframed' ||
37
- !(0, exports.canEditEasingForInterpolationFunction)(sequencePropStatus.interpolationFunction)) {
36
+ !(0, studio_shared_1.canEditEasingForInterpolationFunction)(sequencePropStatus.interpolationFunction)) {
38
37
  return null;
39
38
  }
40
39
  return {
@@ -61,7 +60,7 @@ const getSelectedEasingUpdate = ({ selection, sequences, overrideIdsToNodePaths,
61
60
  ? effectStatus.props[field.fieldKey]
62
61
  : null;
63
62
  if ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) !== 'keyframed' ||
64
- !(0, exports.canEditEasingForInterpolationFunction)(effectPropStatus.interpolationFunction)) {
63
+ !(0, studio_shared_1.canEditEasingForInterpolationFunction)(effectPropStatus.interpolationFunction)) {
65
64
  return null;
66
65
  }
67
66
  return {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useExpandedTrackKeyframeRows = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
4
5
  const react_1 = require("react");
5
6
  const remotion_1 = require("remotion");
6
7
  const timeline_layout_1 = require("../../helpers/timeline-layout");
@@ -9,8 +10,6 @@ const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
9
10
  const get_node_keyframes_1 = require("./get-node-keyframes");
10
11
  const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
11
12
  const TimelineSelection_1 = require("./TimelineSelection");
12
- const canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
13
- interpolationFunction === 'interpolateColors';
14
13
  const getNodeCanEditEasing = ({ node, nodePath, propStatuses, }) => {
15
14
  var _a;
16
15
  if (node.kind !== 'field' || node.field === null) {
@@ -19,7 +18,7 @@ const getNodeCanEditEasing = ({ node, nodePath, propStatuses, }) => {
19
18
  if (node.field.kind === 'sequence-field') {
20
19
  const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _a === void 0 ? void 0 : _a[node.field.key];
21
20
  return ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) === 'keyframed' &&
22
- canEditEasingForInterpolationFunction(sequencePropStatus.interpolationFunction));
21
+ (0, studio_shared_1.canEditEasingForInterpolationFunction)(sequencePropStatus.interpolationFunction));
23
22
  }
24
23
  const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
25
24
  propStatuses,
@@ -30,7 +29,7 @@ const getNodeCanEditEasing = ({ node, nodePath, propStatuses, }) => {
30
29
  ? effectStatus.props[node.field.key]
31
30
  : null;
32
31
  return ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) === 'keyframed' &&
33
- canEditEasingForInterpolationFunction(effectPropStatus.interpolationFunction));
32
+ (0, studio_shared_1.canEditEasingForInterpolationFunction)(effectPropStatus.interpolationFunction));
34
33
  };
35
34
  const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayOffset, }) => {
36
35
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
@@ -29,6 +29,20 @@ export declare const getAssetElementFromPath: (assetPath: string) => {
29
29
  } | null;
30
30
  position: InsertableCompositionElementPosition | null;
31
31
  } | null;
32
+ export declare const getAssetElementForDroppedFile: ({ fileType, src, }: {
33
+ fileType: FileType;
34
+ src: string;
35
+ }) => {
36
+ type: "asset";
37
+ assetType: "animated-image" | "audio" | "gif" | "image" | "video";
38
+ src: string;
39
+ srcType: "remote" | "static";
40
+ dimensions: {
41
+ width: number;
42
+ height: number;
43
+ } | null;
44
+ position: InsertableCompositionElementPosition | null;
45
+ } | null;
32
46
  export declare const getElementPositionForDrop: ({ dimensions, dropPosition, }: {
33
47
  dimensions: Dimensions | null;
34
48
  dropPosition: InsertElementDropPosition | null;
@@ -38,6 +52,11 @@ export declare const getCompositionPositionForDrop: ({ compositionDimensions, de
38
52
  destinationDimensions: Dimensions | null;
39
53
  dropPosition: InsertElementDropPosition | null;
40
54
  }) => InsertableCompositionElementPosition | null;
55
+ export declare const getAssetPositionForDrop: ({ assetDimensions, destinationDimensions, dropPosition, }: {
56
+ assetDimensions: Dimensions | null;
57
+ destinationDimensions: Dimensions | null;
58
+ dropPosition: InsertElementDropPosition | null;
59
+ }) => InsertableCompositionElementPosition | null;
41
60
  export declare const getComponentDimensions: (component: {
42
61
  componentName: string;
43
62
  dimensions?: import("@remotion/studio-shared").ComponentDimensions | undefined;
@@ -48,15 +67,17 @@ export declare const getComponentDimensions: (component: {
48
67
  export declare const pickFilesToImport: ({ multiple, }?: {
49
68
  readonly multiple?: boolean | undefined;
50
69
  }) => Promise<File[]>;
51
- export declare const importAssets: ({ compositionFile, compositionId, dropPosition, files, }: {
70
+ export declare const importAssets: ({ compositionFile, compositionId, destinationDimensions, dropPosition, files, }: {
52
71
  compositionFile: string;
53
72
  compositionId: string;
73
+ destinationDimensions: Dimensions | null;
54
74
  dropPosition: InsertElementDropPosition | null;
55
75
  files: File[];
56
76
  }) => Promise<void>;
57
- export declare const importRemoteAsset: ({ compositionFile, compositionId, dropPosition, url, }: {
77
+ export declare const importRemoteAsset: ({ compositionFile, compositionId, destinationDimensions, dropPosition, url, }: {
58
78
  compositionFile: string;
59
79
  compositionId: string;
80
+ destinationDimensions: Dimensions | null;
60
81
  dropPosition: InsertElementDropPosition | null;
61
82
  url: string;
62
83
  }) => Promise<void>;
@@ -65,10 +86,11 @@ export declare const insertRemoteAudio: ({ compositionFile, compositionId, url,
65
86
  compositionId: string;
66
87
  url: string;
67
88
  }) => Promise<void>;
68
- export declare const insertExistingAssets: ({ assetPaths, compositionFile, compositionId, dropPosition, }: {
89
+ export declare const insertExistingAssets: ({ assetPaths, compositionFile, compositionId, destinationDimensions, dropPosition, }: {
69
90
  assetPaths: string[];
70
91
  compositionFile: string;
71
92
  compositionId: string;
93
+ destinationDimensions: Dimensions | null;
72
94
  dropPosition: InsertElementDropPosition | null;
73
95
  }) => Promise<void>;
74
96
  export declare const insertComponent: ({ component, compositionFile, compositionId, dropPosition, }: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.insertElement = exports.insertComposition = exports.insertComponent = exports.insertExistingAssets = exports.insertRemoteAudio = exports.importRemoteAsset = exports.importAssets = exports.pickFilesToImport = exports.getComponentDimensions = exports.getCompositionPositionForDrop = exports.getElementPositionForDrop = exports.getAssetElementFromPath = exports.getAssetElement = void 0;
3
+ exports.insertElement = exports.insertComposition = exports.insertComponent = exports.insertExistingAssets = exports.insertRemoteAudio = exports.importRemoteAsset = exports.importAssets = exports.pickFilesToImport = exports.getComponentDimensions = exports.getAssetPositionForDrop = exports.getCompositionPositionForDrop = exports.getElementPositionForDrop = exports.getAssetElementForDroppedFile = exports.getAssetElementFromPath = exports.getAssetElement = void 0;
4
4
  const media_utils_1 = require("@remotion/media-utils");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const remotion_1 = require("remotion");
@@ -11,6 +11,16 @@ const install_required_package_1 = require("../helpers/install-required-package"
11
11
  const call_api_1 = require("./call-api");
12
12
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
13
13
  const getAssetElement = ({ fileType, src, }) => {
14
+ if (fileType.type === 'webp' && fileType.animated) {
15
+ return {
16
+ type: 'asset',
17
+ assetType: 'animated-image',
18
+ src,
19
+ srcType: 'static',
20
+ dimensions: fileType.dimensions,
21
+ position: null,
22
+ };
23
+ }
14
24
  if (fileType.type === 'png' ||
15
25
  fileType.type === 'jpeg' ||
16
26
  fileType.type === 'webp' ||
@@ -82,7 +92,7 @@ const getAssetElementFromPath = (assetPath) => {
82
92
  if (!extension || extension === assetPath.toLowerCase()) {
83
93
  return null;
84
94
  }
85
- if (['png', 'jpg', 'jpeg', 'webp', 'bmp'].includes(extension)) {
95
+ if (['png', 'jpg', 'jpeg', 'webp', 'bmp', 'svg'].includes(extension)) {
86
96
  return {
87
97
  type: 'asset',
88
98
  assetType: 'image',
@@ -135,6 +145,17 @@ const getAssetElementFromPath = (assetPath) => {
135
145
  return null;
136
146
  };
137
147
  exports.getAssetElementFromPath = getAssetElementFromPath;
148
+ const getAssetElementForDroppedFile = ({ fileType, src, }) => {
149
+ const detectedElement = (0, exports.getAssetElement)({ fileType, src });
150
+ if (detectedElement !== null) {
151
+ return detectedElement;
152
+ }
153
+ if (fileType.type !== 'unknown' || !src.toLowerCase().endsWith('.svg')) {
154
+ return null;
155
+ }
156
+ return (0, exports.getAssetElementFromPath)(src);
157
+ };
158
+ exports.getAssetElementForDroppedFile = getAssetElementForDroppedFile;
138
159
  const getAssetLabel = (element) => {
139
160
  if (element.type !== 'asset') {
140
161
  throw new Error('Expected asset element');
@@ -194,6 +215,16 @@ const getCompositionPositionForDrop = ({ compositionDimensions, destinationDimen
194
215
  });
195
216
  };
196
217
  exports.getCompositionPositionForDrop = getCompositionPositionForDrop;
218
+ const getAssetPositionForDrop = ({ assetDimensions, destinationDimensions, dropPosition, }) => {
219
+ if (assetDimensions !== null &&
220
+ destinationDimensions !== null &&
221
+ assetDimensions.width === destinationDimensions.width &&
222
+ assetDimensions.height === destinationDimensions.height) {
223
+ return null;
224
+ }
225
+ return getCenteredPosition({ dimensions: assetDimensions, dropPosition });
226
+ };
227
+ exports.getAssetPositionForDrop = getAssetPositionForDrop;
197
228
  const getComponentPropNumber = (props, name) => {
198
229
  const prop = props.find((p) => p.name === name);
199
230
  return typeof (prop === null || prop === void 0 ? void 0 : prop.value) === 'number' ? prop.value : null;
@@ -237,6 +268,10 @@ const getVideoDimensions = async (src) => {
237
268
  return { width: metadata.width, height: metadata.height };
238
269
  };
239
270
  const getFileDimensions = async ({ file, fileType, }) => {
271
+ if (fileType.type === 'unknown' && file.name.toLowerCase().endsWith('.svg')) {
272
+ const objectUrl = URL.createObjectURL(file);
273
+ return getImageDimensions({ revokeObjectUrl: true, src: objectUrl });
274
+ }
240
275
  if (fileType.type === 'wav' ||
241
276
  fileType.type === 'mp3' ||
242
277
  fileType.type === 'aac' ||
@@ -274,7 +309,7 @@ const getStaticAssetDimensions = (assetPath) => {
274
309
  const extension = (_a = assetPath.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
275
310
  const src = (0, remotion_1.staticFile)(assetPath);
276
311
  if (extension &&
277
- ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'gif', 'apng'].includes(extension)) {
312
+ ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'gif', 'apng', 'svg'].includes(extension)) {
278
313
  return getImageDimensions({ revokeObjectUrl: false, src });
279
314
  }
280
315
  if (extension &&
@@ -302,7 +337,7 @@ const getStaticAssetDimensionsOrNull = async (assetPath) => {
302
337
  const getStaticAssetFileType = async (assetPath) => {
303
338
  var _a;
304
339
  const extension = (_a = assetPath.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
305
- if (extension !== 'png' && extension !== 'apng') {
340
+ if (extension !== 'png' && extension !== 'apng' && extension !== 'webp') {
306
341
  return null;
307
342
  }
308
343
  try {
@@ -388,7 +423,7 @@ const insertAssetElement = async ({ compositionFile, compositionId, element, })
388
423
  const downloadRemoteAsset = (url) => {
389
424
  return (0, call_api_1.callApi)('/api/download-remote-asset', { url });
390
425
  };
391
- const importAssets = async ({ compositionFile, compositionId, dropPosition, files, }) => {
426
+ const importAssets = async ({ compositionFile, compositionId, destinationDimensions, dropPosition, files, }) => {
392
427
  var _a;
393
428
  if (files.length === 0) {
394
429
  return;
@@ -418,7 +453,7 @@ const importAssets = async ({ compositionFile, compositionId, dropPosition, file
418
453
  for (const file of files) {
419
454
  const contents = await file.arrayBuffer();
420
455
  const fileType = (0, studio_shared_1.detectFileType)(new Uint8Array(contents));
421
- const element = (0, exports.getAssetElement)({
456
+ const element = (0, exports.getAssetElementForDroppedFile)({
422
457
  fileType,
423
458
  src: file.name,
424
459
  });
@@ -436,14 +471,16 @@ const importAssets = async ({ compositionFile, compositionId, dropPosition, file
436
471
  addedStaticFiles.push(file.name);
437
472
  }
438
473
  const dimensions = await getFileDimensionsOrNull({ file, fileType });
474
+ const resolvedDimensions = (_a = element.dimensions) !== null && _a !== void 0 ? _a : dimensions;
439
475
  const inserted = await insertAssetElement({
440
476
  compositionFile,
441
477
  compositionId,
442
478
  element: {
443
479
  ...element,
444
- dimensions: (_a = element.dimensions) !== null && _a !== void 0 ? _a : dimensions,
445
- position: getCenteredPosition({
446
- dimensions,
480
+ dimensions: resolvedDimensions,
481
+ position: (0, exports.getAssetPositionForDrop)({
482
+ assetDimensions: resolvedDimensions,
483
+ destinationDimensions,
447
484
  dropPosition,
448
485
  }),
449
486
  },
@@ -463,7 +500,7 @@ const importAssets = async ({ compositionFile, compositionId, dropPosition, file
463
500
  }
464
501
  };
465
502
  exports.importAssets = importAssets;
466
- const importRemoteAsset = async ({ compositionFile, compositionId, dropPosition, url, }) => {
503
+ const importRemoteAsset = async ({ compositionFile, compositionId, destinationDimensions, dropPosition, url, }) => {
467
504
  try {
468
505
  const { assetPath, created, element } = await downloadRemoteAsset(url);
469
506
  if (created) {
@@ -478,8 +515,9 @@ const importRemoteAsset = async ({ compositionFile, compositionId, dropPosition,
478
515
  compositionId,
479
516
  element: {
480
517
  ...element,
481
- position: getCenteredPosition({
482
- dimensions: element.dimensions,
518
+ position: (0, exports.getAssetPositionForDrop)({
519
+ assetDimensions: element.dimensions,
520
+ destinationDimensions,
483
521
  dropPosition,
484
522
  }),
485
523
  },
@@ -523,7 +561,7 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, url, }) => {
523
561
  }
524
562
  };
525
563
  exports.insertRemoteAudio = insertRemoteAudio;
526
- const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId, dropPosition, }) => {
564
+ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId, destinationDimensions, dropPosition, }) => {
527
565
  var _a;
528
566
  if (assetPaths.length === 0) {
529
567
  return;
@@ -544,8 +582,9 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
544
582
  element: {
545
583
  ...element,
546
584
  dimensions,
547
- position: getCenteredPosition({
548
- dimensions,
585
+ position: (0, exports.getAssetPositionForDrop)({
586
+ assetDimensions: dimensions,
587
+ destinationDimensions,
549
588
  dropPosition,
550
589
  }),
551
590
  },
@@ -48,10 +48,6 @@ export declare const getOutlineSelectionInteraction: ({ shiftKey, metaKey, ctrlK
48
48
  readonly metaKey: boolean;
49
49
  readonly ctrlKey: boolean;
50
50
  }) => TimelineSelectionInteraction;
51
- export declare const getOutlineDoubleClickAction: ({ button, canOpenInEditor, }: {
52
- readonly button: number;
53
- readonly canOpenInEditor: boolean;
54
- }) => "open-in-editor" | null;
55
51
  type SelectedEffectFields = {
56
52
  allFields: boolean;
57
53
  fieldKeys: Set<string>;
@@ -62,9 +58,10 @@ type SelectedTransformOriginInfo = {
62
58
  readonly displayFrame: number | null;
63
59
  };
64
60
  export declare const getSelectedTransformOriginInfo: (selectedItems: readonly TimelineSelection[]) => SelectedTransformOriginInfo | null;
65
- export declare const getSequencesWithSelectableOutlines: ({ sequences, overrideIdsToNodePaths, }: {
61
+ export declare const getSequencesWithSelectableOutlines: ({ sequences, overrideIdsToNodePaths, compositions, }: {
66
62
  readonly sequences: readonly TSequence[];
67
63
  readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
64
+ readonly compositions?: readonly import("remotion").AnyComposition[] | undefined;
68
65
  }) => SequenceWithSelectedOutline[];
69
66
  export declare const measureOutlines: (container: SVGSVGElement, targets: readonly SelectedOutlineTarget[]) => SelectedOutline[];
70
67
  export declare const outlinesAreEqual: (a: readonly SelectedOutline[], b: readonly SelectedOutline[]) => boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.outlinesAreEqual = exports.measureOutlines = exports.getSequencesWithSelectableOutlines = exports.getSelectedTransformOriginInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineDoubleClickAction = exports.getOutlineSelectionInteraction = exports.getSequenceKeysContainingSelection = exports.getSelectedSequenceKeys = 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;
3
+ exports.outlinesAreEqual = exports.measureOutlines = exports.getSequencesWithSelectableOutlines = exports.getSelectedTransformOriginInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.getSequenceKeysContainingSelection = exports.getSelectedSequenceKeys = 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
4
  const calculate_timeline_1 = require("../helpers/calculate-timeline");
5
5
  const colors_1 = require("../helpers/colors");
6
6
  const get_box_quads_ponyfill_1 = require("../helpers/get-box-quads-ponyfill");
@@ -220,8 +220,6 @@ const getOutlineSelectionInteraction = ({ shiftKey, metaKey, ctrlKey, }) => ({
220
220
  toggleKey: metaKey || ctrlKey,
221
221
  });
222
222
  exports.getOutlineSelectionInteraction = getOutlineSelectionInteraction;
223
- const getOutlineDoubleClickAction = ({ button, canOpenInEditor, }) => button === 0 && canOpenInEditor ? 'open-in-editor' : null;
224
- exports.getOutlineDoubleClickAction = getOutlineDoubleClickAction;
225
223
  const getKeyframeOrEasingField = (item) => {
226
224
  if (item.type !== 'keyframe' && item.type !== 'easing') {
227
225
  return null;
@@ -308,10 +306,11 @@ const getSelectedTransformOriginInfo = (selectedItems) => {
308
306
  };
309
307
  };
310
308
  exports.getSelectedTransformOriginInfo = getSelectedTransformOriginInfo;
311
- const getSequencesWithSelectableOutlines = ({ sequences, overrideIdsToNodePaths, }) => {
309
+ const getSequencesWithSelectableOutlines = ({ sequences, overrideIdsToNodePaths, compositions = [], }) => {
312
310
  return (0, calculate_timeline_1.calculateTimeline)({
313
311
  sequences: [...sequences],
314
312
  overrideIdsToNodePaths,
313
+ compositions,
315
314
  })
316
315
  .filter((track) => {
317
316
  if (track.nodePathInfo === null) {