@remotion/studio 4.0.476 → 4.0.477

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 (61) hide show
  1. package/dist/components/Canvas.js +40 -1
  2. package/dist/components/ControlButton.d.ts +1 -0
  3. package/dist/components/ControlButton.js +7 -2
  4. package/dist/components/EditorGuides/Guide.js +122 -20
  5. package/dist/components/EditorRuler/Ruler.js +21 -15
  6. package/dist/components/EditorRuler/index.js +18 -10
  7. package/dist/components/OutlineToggle.js +1 -1
  8. package/dist/components/SelectedOutlineElement.d.ts +17 -0
  9. package/dist/components/SelectedOutlineElement.js +938 -0
  10. package/dist/components/SelectedOutlineOverlay.d.ts +4 -210
  11. package/dist/components/SelectedOutlineOverlay.js +64 -1637
  12. package/dist/components/SelectedOutlineUvControls.js +1 -1
  13. package/dist/components/ShowGuidesProvider.js +4 -4
  14. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  15. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  16. package/dist/components/Timeline/Timeline.js +3 -1
  17. package/dist/components/Timeline/TimelineClipboardKeybindings.js +9 -10
  18. package/dist/components/Timeline/TimelineDeleteKeybindings.js +15 -4
  19. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +7 -11
  20. package/dist/components/Timeline/TimelineList.js +1 -1
  21. package/dist/components/Timeline/TimelineSelection.d.ts +27 -13
  22. package/dist/components/Timeline/TimelineSelection.js +47 -28
  23. package/dist/components/Timeline/TimelineSequence.js +169 -8
  24. package/dist/components/Timeline/TimelineSequenceFrame.d.ts +1 -0
  25. package/dist/components/Timeline/TimelineSequenceFrame.js +17 -6
  26. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  27. package/dist/components/Timeline/TimelineSequenceItem.js +90 -130
  28. package/dist/components/Timeline/delete-selected-timeline-item.js +4 -0
  29. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +1 -2
  30. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +20 -0
  31. package/dist/components/Timeline/get-sequence-context-menu-items.js +160 -0
  32. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
  33. package/dist/components/Timeline/sequence-props-subscription-store.js +11 -3
  34. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  35. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +16 -2
  36. package/dist/components/Timeline/update-selected-easing.d.ts +4 -6
  37. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +2 -1
  38. package/dist/components/Timeline/use-sequence-props-subscription.js +3 -1
  39. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +37 -1
  40. package/dist/components/Timeline/use-timeline-keyframe-drag.js +282 -1
  41. package/dist/components/import-assets.d.ts +36 -8
  42. package/dist/components/import-assets.js +170 -10
  43. package/dist/components/selected-outline-drag.d.ts +117 -0
  44. package/dist/components/selected-outline-drag.js +427 -0
  45. package/dist/components/selected-outline-measurement.d.ts +67 -0
  46. package/dist/components/selected-outline-measurement.js +355 -0
  47. package/dist/components/selected-outline-types.d.ts +121 -0
  48. package/dist/components/selected-outline-types.js +15 -0
  49. package/dist/components/selected-outline-uv.d.ts +1 -0
  50. package/dist/components/selected-outline-uv.js +12 -0
  51. package/dist/esm/{chunk-0atarw3p.js → chunk-t8fjnw2d.js} +12570 -11492
  52. package/dist/esm/internals.mjs +12570 -11492
  53. package/dist/esm/previewEntry.mjs +12580 -11502
  54. package/dist/esm/renderEntry.mjs +1 -1
  55. package/dist/helpers/editor-guide-selection.d.ts +31 -0
  56. package/dist/helpers/editor-guide-selection.js +58 -0
  57. package/dist/helpers/editor-ruler.d.ts +3 -3
  58. package/dist/helpers/editor-ruler.js +16 -18
  59. package/dist/state/editor-guides.d.ts +2 -2
  60. package/dist/state/editor-guides.js +2 -2
  61. package/package.json +11 -11
@@ -1,18 +1,44 @@
1
- import { type FileType, type InsertableCompositionElement } from '@remotion/studio-shared';
1
+ import { type ComponentProp, type FileType, type InsertableCompositionElementPosition } from '@remotion/studio-shared';
2
+ export type InsertElementDropPosition = {
3
+ readonly centerX: number;
4
+ readonly centerY: number;
5
+ };
2
6
  export declare const getAssetElement: ({ fileType, src, }: {
3
7
  fileType: FileType;
4
8
  src: string;
5
- }) => InsertableCompositionElement | null;
6
- export declare const getAssetElementFromPath: (assetPath: string) => InsertableCompositionElement | null;
9
+ }) => {
10
+ type: "asset";
11
+ assetType: "audio" | "gif" | "image" | "video";
12
+ src: string;
13
+ srcType: "remote" | "static";
14
+ dimensions: {
15
+ width: number;
16
+ height: number;
17
+ } | null;
18
+ position: InsertableCompositionElementPosition | null;
19
+ } | null;
20
+ export declare const getAssetElementFromPath: (assetPath: string) => {
21
+ type: "asset";
22
+ assetType: "audio" | "gif" | "image" | "video";
23
+ src: string;
24
+ srcType: "remote" | "static";
25
+ dimensions: {
26
+ width: number;
27
+ height: number;
28
+ } | null;
29
+ position: InsertableCompositionElementPosition | null;
30
+ } | null;
7
31
  export declare const pickFilesToImport: () => Promise<File[]>;
8
- export declare const importAssets: ({ compositionFile, compositionId, files, }: {
32
+ export declare const importAssets: ({ compositionFile, compositionId, dropPosition, files, }: {
9
33
  compositionFile: string;
10
34
  compositionId: string;
35
+ dropPosition: InsertElementDropPosition | null;
11
36
  files: File[];
12
37
  }) => Promise<void>;
13
- export declare const importRemoteAsset: ({ compositionFile, compositionId, url, }: {
38
+ export declare const importRemoteAsset: ({ compositionFile, compositionId, dropPosition, url, }: {
14
39
  compositionFile: string;
15
40
  compositionId: string;
41
+ dropPosition: InsertElementDropPosition | null;
16
42
  url: string;
17
43
  }) => Promise<void>;
18
44
  export declare const insertRemoteAudio: ({ compositionFile, compositionId, url, }: {
@@ -20,18 +46,20 @@ export declare const insertRemoteAudio: ({ compositionFile, compositionId, url,
20
46
  compositionId: string;
21
47
  url: string;
22
48
  }) => Promise<void>;
23
- export declare const insertExistingAssets: ({ assetPaths, compositionFile, compositionId, }: {
49
+ export declare const insertExistingAssets: ({ assetPaths, compositionFile, compositionId, dropPosition, }: {
24
50
  assetPaths: string[];
25
51
  compositionFile: string;
26
52
  compositionId: string;
53
+ dropPosition: InsertElementDropPosition | null;
27
54
  }) => Promise<void>;
28
- export declare const insertComponent: ({ component, compositionFile, compositionId, }: {
55
+ export declare const insertComponent: ({ component, compositionFile, compositionId, dropPosition, }: {
29
56
  component: {
30
57
  componentName: string;
31
58
  importName: string;
32
59
  importPath: string;
33
- props: import("@remotion/studio-shared").ComponentProp[];
60
+ props: ComponentProp[];
34
61
  };
35
62
  compositionFile: string;
36
63
  compositionId: string;
64
+ dropPosition: InsertElementDropPosition | null;
37
65
  }) => Promise<void>;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.insertComponent = exports.insertExistingAssets = exports.insertRemoteAudio = exports.importRemoteAsset = exports.importAssets = exports.pickFilesToImport = exports.getAssetElementFromPath = exports.getAssetElement = void 0;
4
+ const media_utils_1 = require("@remotion/media-utils");
4
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
+ const remotion_1 = require("remotion");
5
7
  const get_static_files_1 = require("../api/get-static-files");
6
8
  const write_static_file_1 = require("../api/write-static-file");
7
9
  const install_required_package_1 = require("../helpers/install-required-package");
@@ -18,6 +20,7 @@ const getAssetElement = ({ fileType, src, }) => {
18
20
  src,
19
21
  srcType: 'static',
20
22
  dimensions: fileType.dimensions,
23
+ position: null,
21
24
  };
22
25
  }
23
26
  if (fileType.type === 'gif') {
@@ -27,6 +30,7 @@ const getAssetElement = ({ fileType, src, }) => {
27
30
  src,
28
31
  srcType: 'static',
29
32
  dimensions: fileType.dimensions,
33
+ position: null,
30
34
  };
31
35
  }
32
36
  if (fileType.type === 'riff' ||
@@ -39,6 +43,7 @@ const getAssetElement = ({ fileType, src, }) => {
39
43
  src,
40
44
  srcType: 'static',
41
45
  dimensions: null,
46
+ position: null,
42
47
  };
43
48
  }
44
49
  if (fileType.type === 'wav' ||
@@ -51,6 +56,7 @@ const getAssetElement = ({ fileType, src, }) => {
51
56
  src,
52
57
  srcType: 'static',
53
58
  dimensions: null,
59
+ position: null,
54
60
  };
55
61
  }
56
62
  return null;
@@ -72,6 +78,7 @@ const getAssetElementFromPath = (assetPath) => {
72
78
  src: assetPath,
73
79
  srcType: 'static',
74
80
  dimensions: null,
81
+ position: null,
75
82
  };
76
83
  }
77
84
  if (extension === 'gif') {
@@ -81,6 +88,7 @@ const getAssetElementFromPath = (assetPath) => {
81
88
  src: assetPath,
82
89
  srcType: 'static',
83
90
  dimensions: null,
91
+ position: null,
84
92
  };
85
93
  }
86
94
  if (['mp4', 'm4v', 'mov', 'avi', 'webm', 'ts', 'm2ts'].includes(extension)) {
@@ -90,6 +98,7 @@ const getAssetElementFromPath = (assetPath) => {
90
98
  src: assetPath,
91
99
  srcType: 'static',
92
100
  dimensions: null,
101
+ position: null,
93
102
  };
94
103
  }
95
104
  if (['wav', 'mp3', 'aac', 'flac'].includes(extension)) {
@@ -99,6 +108,7 @@ const getAssetElementFromPath = (assetPath) => {
99
108
  src: assetPath,
100
109
  srcType: 'static',
101
110
  dimensions: null,
111
+ position: null,
102
112
  };
103
113
  }
104
114
  return null;
@@ -125,6 +135,121 @@ const getAssetLabel = (element) => {
125
135
  const getComponentLabel = (component) => {
126
136
  return `<${component.componentName}>`;
127
137
  };
138
+ const getCenteredPosition = ({ dimensions, dropPosition, }) => {
139
+ if (dropPosition === null) {
140
+ return null;
141
+ }
142
+ if (dimensions === null) {
143
+ return {
144
+ x: dropPosition.centerX,
145
+ y: dropPosition.centerY,
146
+ };
147
+ }
148
+ return {
149
+ x: dropPosition.centerX - dimensions.width / 2,
150
+ y: dropPosition.centerY - dimensions.height / 2,
151
+ };
152
+ };
153
+ const getComponentPropNumber = (props, name) => {
154
+ const prop = props.find((p) => p.name === name);
155
+ return typeof (prop === null || prop === void 0 ? void 0 : prop.value) === 'number' ? prop.value : null;
156
+ };
157
+ const getComponentDimensions = (component) => {
158
+ const width = getComponentPropNumber(component.props, 'width');
159
+ const height = getComponentPropNumber(component.props, 'height');
160
+ if (width !== null && height !== null) {
161
+ return { width, height };
162
+ }
163
+ const radius = getComponentPropNumber(component.props, 'radius');
164
+ if (radius !== null) {
165
+ return { width: radius * 2, height: radius * 2 };
166
+ }
167
+ return null;
168
+ };
169
+ const getImageDimensions = ({ revokeObjectUrl, src, }) => {
170
+ return new Promise((resolve, reject) => {
171
+ const image = new Image();
172
+ image.onload = () => {
173
+ if (revokeObjectUrl) {
174
+ URL.revokeObjectURL(src);
175
+ }
176
+ resolve({ width: image.naturalWidth, height: image.naturalHeight });
177
+ };
178
+ image.onerror = () => {
179
+ if (revokeObjectUrl) {
180
+ URL.revokeObjectURL(src);
181
+ }
182
+ reject(new Error('Failed to load image dimensions'));
183
+ };
184
+ image.src = src;
185
+ });
186
+ };
187
+ const getVideoDimensions = async (src) => {
188
+ const metadata = await (0, media_utils_1.getVideoMetadata)(src);
189
+ return { width: metadata.width, height: metadata.height };
190
+ };
191
+ const getFileDimensions = async ({ file, fileType, }) => {
192
+ if (fileType.type === 'wav' ||
193
+ fileType.type === 'mp3' ||
194
+ fileType.type === 'aac' ||
195
+ fileType.type === 'flac') {
196
+ return null;
197
+ }
198
+ if (fileType.type === 'png' ||
199
+ fileType.type === 'jpeg' ||
200
+ fileType.type === 'webp' ||
201
+ fileType.type === 'bmp' ||
202
+ fileType.type === 'gif') {
203
+ if (fileType.dimensions) {
204
+ return fileType.dimensions;
205
+ }
206
+ const objectUrl = URL.createObjectURL(file);
207
+ return getImageDimensions({ revokeObjectUrl: true, src: objectUrl });
208
+ }
209
+ if (fileType.type === 'riff' ||
210
+ fileType.type === 'webm' ||
211
+ fileType.type === 'iso-base-media' ||
212
+ fileType.type === 'transport-stream') {
213
+ const objectUrl = URL.createObjectURL(file);
214
+ try {
215
+ return await getVideoDimensions(objectUrl);
216
+ }
217
+ finally {
218
+ URL.revokeObjectURL(objectUrl);
219
+ }
220
+ }
221
+ return null;
222
+ };
223
+ const getStaticAssetDimensions = (assetPath) => {
224
+ var _a;
225
+ const extension = (_a = assetPath.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
226
+ const src = (0, remotion_1.staticFile)(assetPath);
227
+ if (extension &&
228
+ ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'gif'].includes(extension)) {
229
+ return getImageDimensions({ revokeObjectUrl: false, src });
230
+ }
231
+ if (extension &&
232
+ ['mp4', 'm4v', 'mov', 'avi', 'webm', 'ts', 'm2ts'].includes(extension)) {
233
+ return getVideoDimensions(src);
234
+ }
235
+ return null;
236
+ };
237
+ const getFileDimensionsOrNull = async ({ file, fileType, }) => {
238
+ try {
239
+ return await getFileDimensions({ file, fileType });
240
+ }
241
+ catch (_a) {
242
+ return null;
243
+ }
244
+ };
245
+ const getStaticAssetDimensionsOrNull = async (assetPath) => {
246
+ try {
247
+ return await getStaticAssetDimensions(assetPath);
248
+ }
249
+ catch (_a) {
250
+ return null;
251
+ }
252
+ };
128
253
  const pickFilesToImport = () => {
129
254
  return new Promise((resolve) => {
130
255
  const input = document.createElement('input');
@@ -184,16 +309,18 @@ const insertAssetElement = async ({ compositionFile, compositionId, element, })
184
309
  }
185
310
  return true;
186
311
  };
187
- const downloadRemoteAsset = async (url) => {
312
+ const downloadRemoteAsset = (url) => {
188
313
  return (0, call_api_1.callApi)('/api/download-remote-asset', { url });
189
314
  };
190
- const importAssets = async ({ compositionFile, compositionId, files, }) => {
315
+ const importAssets = async ({ compositionFile, compositionId, dropPosition, files, }) => {
316
+ var _a;
191
317
  if (files.length === 0) {
192
318
  return;
193
319
  }
194
320
  const staticFiles = (0, get_static_files_1.getStaticFiles)();
195
321
  const differentExistingFile = files.find((file) => {
196
- return staticFiles.some((staticFile) => staticFile.name === file.name && staticFile.sizeInBytes !== file.size);
322
+ return staticFiles.some((existingStaticFile) => existingStaticFile.name === file.name &&
323
+ existingStaticFile.sizeInBytes !== file.size);
197
324
  });
198
325
  if (differentExistingFile) {
199
326
  (0, NotificationCenter_1.showNotification)(`File with name ${differentExistingFile.name} already exists and is different`, 4000);
@@ -223,7 +350,8 @@ const importAssets = async ({ compositionFile, compositionId, files, }) => {
223
350
  unsupportedFiles.push(file.name);
224
351
  continue;
225
352
  }
226
- const alreadyExists = staticFiles.some((staticFile) => staticFile.name === file.name && staticFile.sizeInBytes === file.size);
353
+ const alreadyExists = staticFiles.some((existingStaticFile) => existingStaticFile.name === file.name &&
354
+ existingStaticFile.sizeInBytes === file.size);
227
355
  if (!alreadyExists) {
228
356
  await (0, write_static_file_1.writeStaticFile)({
229
357
  contents,
@@ -231,10 +359,18 @@ const importAssets = async ({ compositionFile, compositionId, files, }) => {
231
359
  });
232
360
  addedStaticFiles.push(file.name);
233
361
  }
362
+ const dimensions = await getFileDimensionsOrNull({ file, fileType });
234
363
  const inserted = await insertAssetElement({
235
364
  compositionFile,
236
365
  compositionId,
237
- element,
366
+ element: {
367
+ ...element,
368
+ dimensions: (_a = element.dimensions) !== null && _a !== void 0 ? _a : dimensions,
369
+ position: getCenteredPosition({
370
+ dimensions,
371
+ dropPosition,
372
+ }),
373
+ },
238
374
  });
239
375
  if (!inserted) {
240
376
  notifyAddedStaticFiles();
@@ -251,16 +387,26 @@ const importAssets = async ({ compositionFile, compositionId, files, }) => {
251
387
  }
252
388
  };
253
389
  exports.importAssets = importAssets;
254
- const importRemoteAsset = async ({ compositionFile, compositionId, url, }) => {
390
+ const importRemoteAsset = async ({ compositionFile, compositionId, dropPosition, url, }) => {
255
391
  try {
256
392
  const { assetPath, created, element } = await downloadRemoteAsset(url);
257
393
  if (created) {
258
394
  (0, NotificationCenter_1.showNotification)(`Created ${assetPath} in public folder`, 3000);
259
395
  }
396
+ if (element.type !== 'asset') {
397
+ (0, NotificationCenter_1.showNotification)('Cannot add remote asset: Unsupported asset type', 3000);
398
+ return;
399
+ }
260
400
  const inserted = await insertAssetElement({
261
401
  compositionFile,
262
402
  compositionId,
263
- element,
403
+ element: {
404
+ ...element,
405
+ position: getCenteredPosition({
406
+ dimensions: element.dimensions,
407
+ dropPosition,
408
+ }),
409
+ },
264
410
  });
265
411
  if (!inserted) {
266
412
  return;
@@ -283,6 +429,7 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, url, }) => {
283
429
  src: url,
284
430
  srcType: 'remote',
285
431
  dimensions: null,
432
+ position: null,
286
433
  };
287
434
  try {
288
435
  const inserted = await insertAssetElement({
@@ -300,7 +447,8 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, url, }) => {
300
447
  }
301
448
  };
302
449
  exports.insertRemoteAudio = insertRemoteAudio;
303
- const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId, }) => {
450
+ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId, dropPosition, }) => {
451
+ var _a;
304
452
  if (assetPaths.length === 0) {
305
453
  return;
306
454
  }
@@ -313,10 +461,18 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
313
461
  unsupportedFiles.push(assetPath);
314
462
  continue;
315
463
  }
464
+ const dimensions = await getStaticAssetDimensionsOrNull(assetPath);
316
465
  const inserted = await insertAssetElement({
317
466
  compositionFile,
318
467
  compositionId,
319
- element,
468
+ element: {
469
+ ...element,
470
+ dimensions: (_a = element.dimensions) !== null && _a !== void 0 ? _a : dimensions,
471
+ position: getCenteredPosition({
472
+ dimensions,
473
+ dropPosition,
474
+ }),
475
+ },
320
476
  });
321
477
  if (!inserted) {
322
478
  return;
@@ -331,7 +487,7 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
331
487
  }
332
488
  };
333
489
  exports.insertExistingAssets = insertExistingAssets;
334
- const insertComponent = async ({ component, compositionFile, compositionId, }) => {
490
+ const insertComponent = async ({ component, compositionFile, compositionId, dropPosition, }) => {
335
491
  try {
336
492
  const inserted = await insertAssetElement({
337
493
  compositionFile,
@@ -342,6 +498,10 @@ const insertComponent = async ({ component, compositionFile, compositionId, }) =
342
498
  importName: component.importName,
343
499
  importPath: component.importPath,
344
500
  props: component.props,
501
+ position: getCenteredPosition({
502
+ dimensions: getComponentDimensions(component),
503
+ dropPosition,
504
+ }),
345
505
  },
346
506
  });
347
507
  if (!inserted) {
@@ -0,0 +1,117 @@
1
+ import type { GetDragOverrides, SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
2
+ import { type OutlinePoint } from './selected-outline-geometry';
3
+ import type { SelectedOutlineDragState, SelectedOutlineRotationDragState, SelectedOutlineRotationDragTarget, SelectedOutlineScaleDragState, SelectedOutlineScaleDragTarget, SelectedOutlineDragTarget } from './selected-outline-types';
4
+ import type { SaveSequencePropChange } from './Timeline/save-sequence-prop';
5
+ export declare const getSelectedOutlineDragStates: ({ dragTargets, getDragOverrides, timelinePosition, }: {
6
+ readonly dragTargets: readonly SelectedOutlineDragTarget[];
7
+ readonly getDragOverrides: GetDragOverrides;
8
+ readonly timelinePosition: number;
9
+ }) => SelectedOutlineDragState[];
10
+ export declare const getSelectedOutlineDragValues: ({ dragStates, deltaX, deltaY, }: {
11
+ readonly dragStates: readonly SelectedOutlineDragState[];
12
+ readonly deltaX: number;
13
+ readonly deltaY: number;
14
+ }) => Map<string, string>;
15
+ export declare const applySelectedOutlineDragAxisLock: ({ deltaX, deltaY, axisLocked, }: {
16
+ readonly deltaX: number;
17
+ readonly deltaY: number;
18
+ readonly axisLocked: boolean;
19
+ }) => {
20
+ deltaX: number;
21
+ deltaY: number;
22
+ };
23
+ export declare const isSelectedOutlineDragPastThreshold: ({ deltaX, deltaY, }: {
24
+ readonly deltaX: number;
25
+ readonly deltaY: number;
26
+ }) => boolean;
27
+ export type SelectedOutlineStaticDragChange = SaveSequencePropChange & {
28
+ readonly type: 'static';
29
+ };
30
+ export type SelectedOutlineKeyframedDragChange = {
31
+ readonly type: 'keyframed';
32
+ readonly fileName: string;
33
+ readonly nodePath: SequencePropsSubscriptionKey;
34
+ readonly fieldKey: string;
35
+ readonly sourceFrame: number;
36
+ readonly value: unknown;
37
+ readonly schema: SequenceSchema;
38
+ readonly clientId: string;
39
+ };
40
+ export type SelectedOutlineDragChange = SelectedOutlineStaticDragChange | SelectedOutlineKeyframedDragChange;
41
+ export declare const getSelectedOutlineDragChanges: ({ dragStates, lastValues, }: {
42
+ readonly dragStates: readonly SelectedOutlineDragState[];
43
+ readonly lastValues: ReadonlyMap<string, string>;
44
+ }) => SelectedOutlineDragChange[];
45
+ export type SelectedOutlineKeyboardNudgeDirection = 'left' | 'right' | 'up' | 'down';
46
+ export declare const getSelectedOutlineKeyboardNudgeDelta: ({ direction, shiftKey, }: {
47
+ readonly direction: SelectedOutlineKeyboardNudgeDirection;
48
+ readonly shiftKey: boolean;
49
+ }) => number;
50
+ export declare const getSelectedOutlineKeyboardNudgeDeltas: ({ deltaX, deltaY, direction, shiftKey, }: {
51
+ readonly deltaX: number;
52
+ readonly deltaY: number;
53
+ readonly direction: SelectedOutlineKeyboardNudgeDirection;
54
+ readonly shiftKey: boolean;
55
+ }) => {
56
+ deltaX: number;
57
+ deltaY: number;
58
+ };
59
+ export type SelectedOutlineScaleEdge = 'top' | 'right' | 'bottom' | 'left';
60
+ type SelectedOutlineScaleEdgeInfo = {
61
+ readonly axis: 'x' | 'y';
62
+ readonly cursor: string;
63
+ readonly end: OutlinePoint;
64
+ readonly extent: number;
65
+ readonly normal: OutlinePoint;
66
+ readonly start: OutlinePoint;
67
+ };
68
+ export declare const getSelectedOutlineScaleEdgeInfo: (points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint], edge: SelectedOutlineScaleEdge) => SelectedOutlineScaleEdgeInfo | null;
69
+ export declare const getSelectedOutlineScaleDragStates: ({ dragTargets, getDragOverrides, timelinePosition, }: {
70
+ readonly dragTargets: readonly SelectedOutlineScaleDragTarget[];
71
+ readonly getDragOverrides: GetDragOverrides;
72
+ readonly timelinePosition: number;
73
+ }) => SelectedOutlineScaleDragState[];
74
+ export declare const getSelectedOutlineScaleDragValues: ({ axis, dragStates, scaleFactor, }: {
75
+ readonly axis: "x" | "y";
76
+ readonly dragStates: readonly SelectedOutlineScaleDragState[];
77
+ readonly scaleFactor: number;
78
+ }) => Map<string, string | number>;
79
+ export declare const getSelectedOutlineScaleDragChanges: ({ dragStates, lastValues, }: {
80
+ readonly dragStates: readonly SelectedOutlineScaleDragState[];
81
+ readonly lastValues: ReadonlyMap<string, string | number>;
82
+ }) => SelectedOutlineDragChange[];
83
+ export declare const getSelectedOutlineRotationDragStates: ({ dragTargets, getDragOverrides, timelinePosition, }: {
84
+ readonly dragTargets: readonly SelectedOutlineRotationDragTarget[];
85
+ readonly getDragOverrides: GetDragOverrides;
86
+ readonly timelinePosition: number;
87
+ }) => SelectedOutlineRotationDragState[];
88
+ export declare const getSelectedOutlineRotationDragValues: ({ dragStates, rotationDeltaDegrees, }: {
89
+ readonly dragStates: readonly SelectedOutlineRotationDragState[];
90
+ readonly rotationDeltaDegrees: number;
91
+ }) => Map<string, string>;
92
+ export declare const getSelectedOutlineRotationDragChanges: ({ dragStates, lastValues, }: {
93
+ readonly dragStates: readonly SelectedOutlineRotationDragState[];
94
+ readonly lastValues: ReadonlyMap<string, string>;
95
+ }) => SelectedOutlineDragChange[];
96
+ export declare const clearSelectedOutlineDragOverrides: ({ clearDragOverrides, dragStates, }: {
97
+ readonly clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
98
+ readonly dragStates: readonly SelectedOutlineDragState[];
99
+ }) => void;
100
+ export declare const getSelectedOutlineKeyboardNudgeDirection: (key: string) => SelectedOutlineKeyboardNudgeDirection | null;
101
+ export declare const clearSelectedOutlineScaleDragOverrides: ({ clearDragOverrides, dragStates, }: {
102
+ readonly clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
103
+ readonly dragStates: readonly SelectedOutlineScaleDragState[];
104
+ }) => void;
105
+ export declare const clearSelectedOutlineRotationDragOverrides: ({ clearDragOverrides, dragStates, }: {
106
+ readonly clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
107
+ readonly dragStates: readonly SelectedOutlineRotationDragState[];
108
+ }) => void;
109
+ export declare const parseCssRotationToRadians: (value: string) => number | null;
110
+ export declare const compensateTranslateForTransformOrigin: ({ startTranslate, deltaOrigin, rotate, scale, }: {
111
+ readonly startTranslate: readonly [number, number];
112
+ readonly deltaOrigin: readonly [number, number];
113
+ readonly rotate: number;
114
+ readonly scale: readonly [number, number];
115
+ }) => readonly [number, number];
116
+ export declare const uvsEqual: (left: readonly [number, number], right: readonly [number, number]) => boolean;
117
+ export {};