@remotion/studio 4.0.476 → 4.0.478

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 (74) hide show
  1. package/dist/components/Canvas.js +40 -1
  2. package/dist/components/CanvasIfSizeIsAvailable.js +2 -6
  3. package/dist/components/ControlButton.d.ts +1 -0
  4. package/dist/components/ControlButton.js +7 -2
  5. package/dist/components/EditorGuides/Guide.js +151 -21
  6. package/dist/components/EditorRuler/Ruler.js +20 -24
  7. package/dist/components/EditorRuler/index.js +26 -13
  8. package/dist/components/InlineAction.js +1 -0
  9. package/dist/components/MenuToolbar.d.ts +1 -0
  10. package/dist/components/MenuToolbar.js +4 -1
  11. package/dist/components/OutlineToggle.js +1 -1
  12. package/dist/components/SelectedOutlineElement.d.ts +17 -0
  13. package/dist/components/SelectedOutlineElement.js +1009 -0
  14. package/dist/components/SelectedOutlineOverlay.d.ts +4 -210
  15. package/dist/components/SelectedOutlineOverlay.js +68 -1637
  16. package/dist/components/SelectedOutlineUvControls.js +1 -1
  17. package/dist/components/ShowGuidesProvider.js +4 -4
  18. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  19. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  20. package/dist/components/Timeline/Timeline.js +3 -1
  21. package/dist/components/Timeline/TimelineClipboardKeybindings.js +9 -10
  22. package/dist/components/Timeline/TimelineDeleteKeybindings.js +15 -4
  23. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +7 -11
  24. package/dist/components/Timeline/TimelineList.js +1 -1
  25. package/dist/components/Timeline/TimelineSelection.d.ts +27 -13
  26. package/dist/components/Timeline/TimelineSelection.js +47 -28
  27. package/dist/components/Timeline/TimelineSequence.js +156 -3
  28. package/dist/components/Timeline/TimelineSequenceFrame.d.ts +1 -0
  29. package/dist/components/Timeline/TimelineSequenceFrame.js +17 -6
  30. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  31. package/dist/components/Timeline/TimelineSequenceItem.js +90 -130
  32. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  33. package/dist/components/Timeline/TimelineVideoInfo.js +93 -8
  34. package/dist/components/Timeline/delete-selected-timeline-item.js +4 -0
  35. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +8 -2
  36. package/dist/components/Timeline/duplicate-selected-timeline-item.js +32 -3
  37. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +20 -0
  38. package/dist/components/Timeline/get-sequence-context-menu-items.js +160 -0
  39. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
  40. package/dist/components/Timeline/sequence-props-subscription-store.js +11 -3
  41. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  42. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +16 -2
  43. package/dist/components/Timeline/timeline-video-filmstrip-times.d.ts +17 -0
  44. package/dist/components/Timeline/timeline-video-filmstrip-times.js +22 -0
  45. package/dist/components/Timeline/update-selected-easing.d.ts +4 -6
  46. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +2 -1
  47. package/dist/components/Timeline/use-sequence-props-subscription.js +3 -1
  48. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +37 -1
  49. package/dist/components/Timeline/use-timeline-keyframe-drag.js +282 -1
  50. package/dist/components/import-assets.d.ts +45 -8
  51. package/dist/components/import-assets.js +227 -12
  52. package/dist/components/selected-outline-drag.d.ts +140 -0
  53. package/dist/components/selected-outline-drag.js +475 -0
  54. package/dist/components/selected-outline-measurement.d.ts +67 -0
  55. package/dist/components/selected-outline-measurement.js +355 -0
  56. package/dist/components/selected-outline-types.d.ts +121 -0
  57. package/dist/components/selected-outline-types.js +15 -0
  58. package/dist/components/selected-outline-uv.d.ts +1 -0
  59. package/dist/components/selected-outline-uv.js +12 -0
  60. package/dist/error-overlay/remotion-overlay/Overlay.js +3 -0
  61. package/dist/esm/{chunk-0atarw3p.js → chunk-hrw9799x.js} +12812 -11386
  62. package/dist/esm/internals.mjs +12812 -11386
  63. package/dist/esm/previewEntry.mjs +21059 -19629
  64. package/dist/esm/renderEntry.mjs +1 -1
  65. package/dist/helpers/editor-guide-selection.d.ts +31 -0
  66. package/dist/helpers/editor-guide-selection.js +58 -0
  67. package/dist/helpers/editor-ruler.d.ts +3 -3
  68. package/dist/helpers/editor-ruler.js +16 -18
  69. package/dist/helpers/get-preview-file-type.js +1 -1
  70. package/dist/helpers/ruler-canvas-size.d.ts +5 -0
  71. package/dist/helpers/ruler-canvas-size.js +17 -0
  72. package/dist/state/editor-guides.d.ts +2 -2
  73. package/dist/state/editor-guides.js +2 -2
  74. package/package.json +11 -11
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.insertComponent = exports.insertExistingAssets = exports.insertRemoteAudio = exports.importRemoteAsset = exports.importAssets = exports.pickFilesToImport = exports.getAssetElementFromPath = exports.getAssetElement = void 0;
3
+ exports.insertComponent = exports.insertExistingAssets = exports.insertRemoteAudio = exports.importRemoteAsset = exports.importAssets = exports.pickFilesToImport = exports.getComponentDimensions = 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,17 @@ const getAssetElement = ({ fileType, src, }) => {
18
20
  src,
19
21
  srcType: 'static',
20
22
  dimensions: fileType.dimensions,
23
+ position: null,
24
+ };
25
+ }
26
+ if (fileType.type === 'apng') {
27
+ return {
28
+ type: 'asset',
29
+ assetType: 'animated-image',
30
+ src,
31
+ srcType: 'static',
32
+ dimensions: fileType.dimensions,
33
+ position: null,
21
34
  };
22
35
  }
23
36
  if (fileType.type === 'gif') {
@@ -27,6 +40,7 @@ const getAssetElement = ({ fileType, src, }) => {
27
40
  src,
28
41
  srcType: 'static',
29
42
  dimensions: fileType.dimensions,
43
+ position: null,
30
44
  };
31
45
  }
32
46
  if (fileType.type === 'riff' ||
@@ -39,6 +53,7 @@ const getAssetElement = ({ fileType, src, }) => {
39
53
  src,
40
54
  srcType: 'static',
41
55
  dimensions: null,
56
+ position: null,
42
57
  };
43
58
  }
44
59
  if (fileType.type === 'wav' ||
@@ -51,6 +66,7 @@ const getAssetElement = ({ fileType, src, }) => {
51
66
  src,
52
67
  srcType: 'static',
53
68
  dimensions: null,
69
+ position: null,
54
70
  };
55
71
  }
56
72
  return null;
@@ -72,6 +88,17 @@ const getAssetElementFromPath = (assetPath) => {
72
88
  src: assetPath,
73
89
  srcType: 'static',
74
90
  dimensions: null,
91
+ position: null,
92
+ };
93
+ }
94
+ if (extension === 'apng') {
95
+ return {
96
+ type: 'asset',
97
+ assetType: 'animated-image',
98
+ src: assetPath,
99
+ srcType: 'static',
100
+ dimensions: null,
101
+ position: null,
75
102
  };
76
103
  }
77
104
  if (extension === 'gif') {
@@ -81,6 +108,7 @@ const getAssetElementFromPath = (assetPath) => {
81
108
  src: assetPath,
82
109
  srcType: 'static',
83
110
  dimensions: null,
111
+ position: null,
84
112
  };
85
113
  }
86
114
  if (['mp4', 'm4v', 'mov', 'avi', 'webm', 'ts', 'm2ts'].includes(extension)) {
@@ -90,6 +118,7 @@ const getAssetElementFromPath = (assetPath) => {
90
118
  src: assetPath,
91
119
  srcType: 'static',
92
120
  dimensions: null,
121
+ position: null,
93
122
  };
94
123
  }
95
124
  if (['wav', 'mp3', 'aac', 'flac'].includes(extension)) {
@@ -99,6 +128,7 @@ const getAssetElementFromPath = (assetPath) => {
99
128
  src: assetPath,
100
129
  srcType: 'static',
101
130
  dimensions: null,
131
+ position: null,
102
132
  };
103
133
  }
104
134
  return null;
@@ -117,6 +147,9 @@ const getAssetLabel = (element) => {
117
147
  if (element.assetType === 'gif') {
118
148
  return '<Gif>';
119
149
  }
150
+ if (element.assetType === 'animated-image') {
151
+ return '<AnimatedImage>';
152
+ }
120
153
  if (element.assetType === 'audio') {
121
154
  return '<Audio>';
122
155
  }
@@ -125,6 +158,153 @@ const getAssetLabel = (element) => {
125
158
  const getComponentLabel = (component) => {
126
159
  return `<${component.componentName}>`;
127
160
  };
161
+ const getCenteredPosition = ({ dimensions, dropPosition, }) => {
162
+ if (dropPosition === null) {
163
+ return null;
164
+ }
165
+ if (dimensions === null) {
166
+ return {
167
+ x: dropPosition.centerX,
168
+ y: dropPosition.centerY,
169
+ };
170
+ }
171
+ return {
172
+ x: dropPosition.centerX - dimensions.width / 2,
173
+ y: dropPosition.centerY - dimensions.height / 2,
174
+ };
175
+ };
176
+ const getComponentPropNumber = (props, name) => {
177
+ const prop = props.find((p) => p.name === name);
178
+ return typeof (prop === null || prop === void 0 ? void 0 : prop.value) === 'number' ? prop.value : null;
179
+ };
180
+ const getComponentDimensions = (component) => {
181
+ if (component.dimensions) {
182
+ return component.dimensions;
183
+ }
184
+ const width = getComponentPropNumber(component.props, 'width');
185
+ const height = getComponentPropNumber(component.props, 'height');
186
+ if (width !== null && height !== null) {
187
+ return { width, height };
188
+ }
189
+ const radius = getComponentPropNumber(component.props, 'radius');
190
+ if (radius !== null) {
191
+ return { width: radius * 2, height: radius * 2 };
192
+ }
193
+ return null;
194
+ };
195
+ exports.getComponentDimensions = getComponentDimensions;
196
+ const getImageDimensions = ({ revokeObjectUrl, src, }) => {
197
+ return new Promise((resolve, reject) => {
198
+ const image = new Image();
199
+ image.onload = () => {
200
+ if (revokeObjectUrl) {
201
+ URL.revokeObjectURL(src);
202
+ }
203
+ resolve({ width: image.naturalWidth, height: image.naturalHeight });
204
+ };
205
+ image.onerror = () => {
206
+ if (revokeObjectUrl) {
207
+ URL.revokeObjectURL(src);
208
+ }
209
+ reject(new Error('Failed to load image dimensions'));
210
+ };
211
+ image.src = src;
212
+ });
213
+ };
214
+ const getVideoDimensions = async (src) => {
215
+ const metadata = await (0, media_utils_1.getVideoMetadata)(src);
216
+ return { width: metadata.width, height: metadata.height };
217
+ };
218
+ const getFileDimensions = async ({ file, fileType, }) => {
219
+ if (fileType.type === 'wav' ||
220
+ fileType.type === 'mp3' ||
221
+ fileType.type === 'aac' ||
222
+ fileType.type === 'flac') {
223
+ return null;
224
+ }
225
+ if (fileType.type === 'png' ||
226
+ fileType.type === 'jpeg' ||
227
+ fileType.type === 'webp' ||
228
+ fileType.type === 'bmp' ||
229
+ fileType.type === 'apng' ||
230
+ fileType.type === 'gif') {
231
+ if (fileType.dimensions) {
232
+ return fileType.dimensions;
233
+ }
234
+ const objectUrl = URL.createObjectURL(file);
235
+ return getImageDimensions({ revokeObjectUrl: true, src: objectUrl });
236
+ }
237
+ if (fileType.type === 'riff' ||
238
+ fileType.type === 'webm' ||
239
+ fileType.type === 'iso-base-media' ||
240
+ fileType.type === 'transport-stream') {
241
+ const objectUrl = URL.createObjectURL(file);
242
+ try {
243
+ return await getVideoDimensions(objectUrl);
244
+ }
245
+ finally {
246
+ URL.revokeObjectURL(objectUrl);
247
+ }
248
+ }
249
+ return null;
250
+ };
251
+ const getStaticAssetDimensions = (assetPath) => {
252
+ var _a;
253
+ const extension = (_a = assetPath.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
254
+ const src = (0, remotion_1.staticFile)(assetPath);
255
+ if (extension &&
256
+ ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'gif', 'apng'].includes(extension)) {
257
+ return getImageDimensions({ revokeObjectUrl: false, src });
258
+ }
259
+ if (extension &&
260
+ ['mp4', 'm4v', 'mov', 'avi', 'webm', 'ts', 'm2ts'].includes(extension)) {
261
+ return getVideoDimensions(src);
262
+ }
263
+ return null;
264
+ };
265
+ const getFileDimensionsOrNull = async ({ file, fileType, }) => {
266
+ try {
267
+ return await getFileDimensions({ file, fileType });
268
+ }
269
+ catch (_a) {
270
+ return null;
271
+ }
272
+ };
273
+ const getStaticAssetDimensionsOrNull = async (assetPath) => {
274
+ try {
275
+ return await getStaticAssetDimensions(assetPath);
276
+ }
277
+ catch (_a) {
278
+ return null;
279
+ }
280
+ };
281
+ const getStaticAssetFileType = async (assetPath) => {
282
+ var _a;
283
+ const extension = (_a = assetPath.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
284
+ if (extension !== 'png' && extension !== 'apng') {
285
+ return null;
286
+ }
287
+ try {
288
+ const response = await fetch((0, remotion_1.staticFile)(assetPath));
289
+ if (!response.ok) {
290
+ return null;
291
+ }
292
+ return (0, studio_shared_1.detectFileType)(new Uint8Array(await response.arrayBuffer()));
293
+ }
294
+ catch (_b) {
295
+ return null;
296
+ }
297
+ };
298
+ const getAssetElementFromStaticAsset = async (assetPath) => {
299
+ const fileType = await getStaticAssetFileType(assetPath);
300
+ if (fileType) {
301
+ const element = (0, exports.getAssetElement)({ fileType, src: assetPath });
302
+ if (element) {
303
+ return element;
304
+ }
305
+ }
306
+ return (0, exports.getAssetElementFromPath)(assetPath);
307
+ };
128
308
  const pickFilesToImport = () => {
129
309
  return new Promise((resolve) => {
130
310
  const input = document.createElement('input');
@@ -184,16 +364,18 @@ const insertAssetElement = async ({ compositionFile, compositionId, element, })
184
364
  }
185
365
  return true;
186
366
  };
187
- const downloadRemoteAsset = async (url) => {
367
+ const downloadRemoteAsset = (url) => {
188
368
  return (0, call_api_1.callApi)('/api/download-remote-asset', { url });
189
369
  };
190
- const importAssets = async ({ compositionFile, compositionId, files, }) => {
370
+ const importAssets = async ({ compositionFile, compositionId, dropPosition, files, }) => {
371
+ var _a;
191
372
  if (files.length === 0) {
192
373
  return;
193
374
  }
194
375
  const staticFiles = (0, get_static_files_1.getStaticFiles)();
195
376
  const differentExistingFile = files.find((file) => {
196
- return staticFiles.some((staticFile) => staticFile.name === file.name && staticFile.sizeInBytes !== file.size);
377
+ return staticFiles.some((existingStaticFile) => existingStaticFile.name === file.name &&
378
+ existingStaticFile.sizeInBytes !== file.size);
197
379
  });
198
380
  if (differentExistingFile) {
199
381
  (0, NotificationCenter_1.showNotification)(`File with name ${differentExistingFile.name} already exists and is different`, 4000);
@@ -223,7 +405,8 @@ const importAssets = async ({ compositionFile, compositionId, files, }) => {
223
405
  unsupportedFiles.push(file.name);
224
406
  continue;
225
407
  }
226
- const alreadyExists = staticFiles.some((staticFile) => staticFile.name === file.name && staticFile.sizeInBytes === file.size);
408
+ const alreadyExists = staticFiles.some((existingStaticFile) => existingStaticFile.name === file.name &&
409
+ existingStaticFile.sizeInBytes === file.size);
227
410
  if (!alreadyExists) {
228
411
  await (0, write_static_file_1.writeStaticFile)({
229
412
  contents,
@@ -231,10 +414,18 @@ const importAssets = async ({ compositionFile, compositionId, files, }) => {
231
414
  });
232
415
  addedStaticFiles.push(file.name);
233
416
  }
417
+ const dimensions = await getFileDimensionsOrNull({ file, fileType });
234
418
  const inserted = await insertAssetElement({
235
419
  compositionFile,
236
420
  compositionId,
237
- element,
421
+ element: {
422
+ ...element,
423
+ dimensions: (_a = element.dimensions) !== null && _a !== void 0 ? _a : dimensions,
424
+ position: getCenteredPosition({
425
+ dimensions,
426
+ dropPosition,
427
+ }),
428
+ },
238
429
  });
239
430
  if (!inserted) {
240
431
  notifyAddedStaticFiles();
@@ -251,16 +442,26 @@ const importAssets = async ({ compositionFile, compositionId, files, }) => {
251
442
  }
252
443
  };
253
444
  exports.importAssets = importAssets;
254
- const importRemoteAsset = async ({ compositionFile, compositionId, url, }) => {
445
+ const importRemoteAsset = async ({ compositionFile, compositionId, dropPosition, url, }) => {
255
446
  try {
256
447
  const { assetPath, created, element } = await downloadRemoteAsset(url);
257
448
  if (created) {
258
449
  (0, NotificationCenter_1.showNotification)(`Created ${assetPath} in public folder`, 3000);
259
450
  }
451
+ if (element.type !== 'asset') {
452
+ (0, NotificationCenter_1.showNotification)('Cannot add remote asset: Unsupported asset type', 3000);
453
+ return;
454
+ }
260
455
  const inserted = await insertAssetElement({
261
456
  compositionFile,
262
457
  compositionId,
263
- element,
458
+ element: {
459
+ ...element,
460
+ position: getCenteredPosition({
461
+ dimensions: element.dimensions,
462
+ dropPosition,
463
+ }),
464
+ },
264
465
  });
265
466
  if (!inserted) {
266
467
  return;
@@ -283,6 +484,7 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, url, }) => {
283
484
  src: url,
284
485
  srcType: 'remote',
285
486
  dimensions: null,
487
+ position: null,
286
488
  };
287
489
  try {
288
490
  const inserted = await insertAssetElement({
@@ -300,7 +502,8 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, url, }) => {
300
502
  }
301
503
  };
302
504
  exports.insertRemoteAudio = insertRemoteAudio;
303
- const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId, }) => {
505
+ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId, dropPosition, }) => {
506
+ var _a;
304
507
  if (assetPaths.length === 0) {
305
508
  return;
306
509
  }
@@ -308,15 +511,23 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
308
511
  const unsupportedFiles = [];
309
512
  try {
310
513
  for (const assetPath of assetPaths) {
311
- const element = (0, exports.getAssetElementFromPath)(assetPath);
514
+ const element = await getAssetElementFromStaticAsset(assetPath);
312
515
  if (element === null) {
313
516
  unsupportedFiles.push(assetPath);
314
517
  continue;
315
518
  }
519
+ const dimensions = (_a = element.dimensions) !== null && _a !== void 0 ? _a : (await getStaticAssetDimensionsOrNull(assetPath));
316
520
  const inserted = await insertAssetElement({
317
521
  compositionFile,
318
522
  compositionId,
319
- element,
523
+ element: {
524
+ ...element,
525
+ dimensions,
526
+ position: getCenteredPosition({
527
+ dimensions,
528
+ dropPosition,
529
+ }),
530
+ },
320
531
  });
321
532
  if (!inserted) {
322
533
  return;
@@ -331,7 +542,7 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
331
542
  }
332
543
  };
333
544
  exports.insertExistingAssets = insertExistingAssets;
334
- const insertComponent = async ({ component, compositionFile, compositionId, }) => {
545
+ const insertComponent = async ({ component, compositionFile, compositionId, dropPosition, }) => {
335
546
  try {
336
547
  const inserted = await insertAssetElement({
337
548
  compositionFile,
@@ -342,6 +553,10 @@ const insertComponent = async ({ component, compositionFile, compositionId, }) =
342
553
  importName: component.importName,
343
554
  importPath: component.importPath,
344
555
  props: component.props,
556
+ position: getCenteredPosition({
557
+ dimensions: (0, exports.getComponentDimensions)(component),
558
+ dropPosition,
559
+ }),
345
560
  },
346
561
  });
347
562
  if (!inserted) {
@@ -0,0 +1,140 @@
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 UvCoordinate } from './selected-outline-uv';
5
+ import type { SaveSequencePropChange } from './Timeline/save-sequence-prop';
6
+ export declare const getSelectedOutlineDragStates: ({ dragTargets, getDragOverrides, timelinePosition, }: {
7
+ readonly dragTargets: readonly SelectedOutlineDragTarget[];
8
+ readonly getDragOverrides: GetDragOverrides;
9
+ readonly timelinePosition: number;
10
+ }) => SelectedOutlineDragState[];
11
+ export declare const getSelectedOutlineDragValues: ({ dragStates, deltaX, deltaY, }: {
12
+ readonly dragStates: readonly SelectedOutlineDragState[];
13
+ readonly deltaX: number;
14
+ readonly deltaY: number;
15
+ }) => Map<string, string>;
16
+ export declare const applySelectedOutlineDragAxisLock: ({ deltaX, deltaY, axisLocked, }: {
17
+ readonly deltaX: number;
18
+ readonly deltaY: number;
19
+ readonly axisLocked: boolean;
20
+ }) => {
21
+ deltaX: number;
22
+ deltaY: number;
23
+ };
24
+ export declare const isSelectedOutlineDragPastThreshold: ({ deltaX, deltaY, }: {
25
+ readonly deltaX: number;
26
+ readonly deltaY: number;
27
+ }) => boolean;
28
+ export type SelectedOutlineStaticDragChange = SaveSequencePropChange & {
29
+ readonly type: 'static';
30
+ };
31
+ export type SelectedOutlineKeyframedDragChange = {
32
+ readonly type: 'keyframed';
33
+ readonly fileName: string;
34
+ readonly nodePath: SequencePropsSubscriptionKey;
35
+ readonly fieldKey: string;
36
+ readonly sourceFrame: number;
37
+ readonly value: unknown;
38
+ readonly schema: SequenceSchema;
39
+ readonly clientId: string;
40
+ };
41
+ export type SelectedOutlineDragChange = SelectedOutlineStaticDragChange | SelectedOutlineKeyframedDragChange;
42
+ export declare const getSelectedOutlineDragChanges: ({ dragStates, lastValues, }: {
43
+ readonly dragStates: readonly SelectedOutlineDragState[];
44
+ readonly lastValues: ReadonlyMap<string, string>;
45
+ }) => SelectedOutlineDragChange[];
46
+ export type SelectedOutlineKeyboardNudgeDirection = 'left' | 'right' | 'up' | 'down';
47
+ export declare const getSelectedOutlineKeyboardNudgeDelta: ({ direction, shiftKey, }: {
48
+ readonly direction: SelectedOutlineKeyboardNudgeDirection;
49
+ readonly shiftKey: boolean;
50
+ }) => number;
51
+ export declare const getSelectedOutlineKeyboardNudgeDeltas: ({ deltaX, deltaY, direction, shiftKey, }: {
52
+ readonly deltaX: number;
53
+ readonly deltaY: number;
54
+ readonly direction: SelectedOutlineKeyboardNudgeDirection;
55
+ readonly shiftKey: boolean;
56
+ }) => {
57
+ deltaX: number;
58
+ deltaY: number;
59
+ };
60
+ export type SelectedOutlineScaleEdge = 'top' | 'right' | 'bottom' | 'left';
61
+ type SelectedOutlineScaleEdgeInfo = {
62
+ readonly axis: 'x' | 'y';
63
+ readonly cursor: string;
64
+ readonly end: OutlinePoint;
65
+ readonly extent: number;
66
+ readonly normal: OutlinePoint;
67
+ readonly start: OutlinePoint;
68
+ };
69
+ export declare const getSelectedOutlineScaleEdgeInfo: (points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint], edge: SelectedOutlineScaleEdge) => SelectedOutlineScaleEdgeInfo | null;
70
+ export declare const getSelectedOutlineScaleDragStates: ({ dragTargets, getDragOverrides, timelinePosition, }: {
71
+ readonly dragTargets: readonly SelectedOutlineScaleDragTarget[];
72
+ readonly getDragOverrides: GetDragOverrides;
73
+ readonly timelinePosition: number;
74
+ }) => SelectedOutlineScaleDragState[];
75
+ export declare const getSelectedOutlineScaleDragValues: ({ axis, dragStates, scaleFactor, }: {
76
+ readonly axis: "x" | "y";
77
+ readonly dragStates: readonly SelectedOutlineScaleDragState[];
78
+ readonly scaleFactor: number;
79
+ }) => Map<string, string | number>;
80
+ export declare const getSelectedOutlineScaleDragChanges: ({ dragStates, lastValues, }: {
81
+ readonly dragStates: readonly SelectedOutlineScaleDragState[];
82
+ readonly lastValues: ReadonlyMap<string, string | number>;
83
+ }) => SelectedOutlineDragChange[];
84
+ export declare const getSelectedOutlineRotationDragStates: ({ dragTargets, getDragOverrides, timelinePosition, }: {
85
+ readonly dragTargets: readonly SelectedOutlineRotationDragTarget[];
86
+ readonly getDragOverrides: GetDragOverrides;
87
+ readonly timelinePosition: number;
88
+ }) => SelectedOutlineRotationDragState[];
89
+ export declare const getSelectedOutlineRotationDragValues: ({ dragStates, rotationDeltaDegrees, }: {
90
+ readonly dragStates: readonly SelectedOutlineRotationDragState[];
91
+ readonly rotationDeltaDegrees: number;
92
+ }) => Map<string, string>;
93
+ export declare const getSelectedOutlineRotationDragChanges: ({ dragStates, lastValues, }: {
94
+ readonly dragStates: readonly SelectedOutlineRotationDragState[];
95
+ readonly lastValues: ReadonlyMap<string, string>;
96
+ }) => SelectedOutlineDragChange[];
97
+ export declare const clearSelectedOutlineDragOverrides: ({ clearDragOverrides, dragStates, }: {
98
+ readonly clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
99
+ readonly dragStates: readonly SelectedOutlineDragState[];
100
+ }) => void;
101
+ export declare const getSelectedOutlineKeyboardNudgeDirection: (key: string) => SelectedOutlineKeyboardNudgeDirection | null;
102
+ export declare const clearSelectedOutlineScaleDragOverrides: ({ clearDragOverrides, dragStates, }: {
103
+ readonly clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
104
+ readonly dragStates: readonly SelectedOutlineScaleDragState[];
105
+ }) => void;
106
+ export declare const clearSelectedOutlineRotationDragOverrides: ({ clearDragOverrides, dragStates, }: {
107
+ readonly clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
108
+ readonly dragStates: readonly SelectedOutlineRotationDragState[];
109
+ }) => void;
110
+ export declare const parseCssRotationToRadians: (value: string) => number | null;
111
+ export declare const compensateTranslateForTransformOrigin: ({ startTranslate, deltaOrigin, rotate, scale, }: {
112
+ readonly startTranslate: readonly [number, number];
113
+ readonly deltaOrigin: readonly [number, number];
114
+ readonly rotate: number;
115
+ readonly scale: readonly [number, number];
116
+ }) => readonly [number, number];
117
+ export declare const uvsEqual: (left: readonly [number, number], right: readonly [number, number]) => boolean;
118
+ export type SelectedOutlineTransformOriginLockedAxis = 'x' | 'y' | null;
119
+ export declare const getSelectedOutlineTransformOriginLockedAxis: ({ axisLocked, dimensions, startUv, uv, }: {
120
+ readonly axisLocked: boolean;
121
+ readonly dimensions: {
122
+ readonly width: number;
123
+ readonly height: number;
124
+ };
125
+ readonly startUv: UvCoordinate;
126
+ readonly uv: UvCoordinate;
127
+ }) => SelectedOutlineTransformOriginLockedAxis;
128
+ export declare const applySelectedOutlineTransformOriginAxisLock: ({ lockedAxis, startUv, uv, }: {
129
+ readonly lockedAxis: SelectedOutlineTransformOriginLockedAxis;
130
+ readonly startUv: UvCoordinate;
131
+ readonly uv: UvCoordinate;
132
+ }) => UvCoordinate;
133
+ export declare const selectedOutlineTransformOriginSnapThresholdPx = 10;
134
+ export declare const snapSelectedOutlineTransformOriginUv: ({ point, points, thresholdPx, uv, }: {
135
+ readonly point: OutlinePoint;
136
+ readonly points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint];
137
+ readonly thresholdPx?: number | undefined;
138
+ readonly uv: UvCoordinate;
139
+ }) => UvCoordinate;
140
+ export {};