@remotion/studio-shared 4.0.474 → 4.0.476

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.
@@ -9,6 +9,9 @@ import type { ProjectInfo } from './project-info';
9
9
  import type { CompletedClientRender, RequiredChromiumOptions } from './render-job';
10
10
  import type { SymbolicatedStackFrame } from './stack-types';
11
11
  import type { EnumPath } from './stringify-default-props';
12
+ type KeyframeEasing = Extract<CanUpdateSequencePropStatus, {
13
+ status: 'keyframed';
14
+ }>['easing'][number];
12
15
  export type OpenInFileExplorerRequest = {
13
16
  directory: string;
14
17
  };
@@ -330,6 +333,7 @@ export type AddSequenceKeyframeRequest = {
330
333
  clientId: string;
331
334
  };
332
335
  export type AddSequenceKeyframeResponse = SaveSequencePropsResponse;
336
+ export type AddSequenceKeyframe = Omit<AddSequenceKeyframeRequest, 'clientId'>;
333
337
  export type DeleteEffectKeyframe = {
334
338
  fileName: string;
335
339
  sequenceNodePath: SequencePropsSubscriptionKey;
@@ -374,12 +378,26 @@ export type AddEffectKeyframeRequest = {
374
378
  clientId: string;
375
379
  };
376
380
  export type AddEffectKeyframeResponse = SaveEffectPropsResponse;
381
+ export type AddEffectKeyframe = Omit<AddEffectKeyframeRequest, 'clientId'>;
382
+ export type AddKeyframesRequest = {
383
+ sequenceKeyframes: AddSequenceKeyframe[];
384
+ effectKeyframes: AddEffectKeyframe[];
385
+ clientId: string;
386
+ };
387
+ export type AddKeyframesResponse = {
388
+ success: true;
389
+ };
377
390
  export type KeyframeSettings = {
391
+ type: 'settings';
378
392
  clamping: {
379
393
  left: ExtrapolateType;
380
394
  right: ExtrapolateType;
381
395
  } | undefined;
382
396
  posterize: number | undefined;
397
+ } | {
398
+ type: 'easing';
399
+ segmentIndex: number;
400
+ easing: KeyframeEasing;
383
401
  };
384
402
  export type UpdateSequenceKeyframeSettingsRequest = {
385
403
  fileName: string;
@@ -565,6 +583,7 @@ export type ApiRoutes = {
565
583
  '/api/move-keyframes': ReqAndRes<MoveKeyframesRequest, MoveKeyframesResponse>;
566
584
  '/api/add-sequence-keyframe': ReqAndRes<AddSequenceKeyframeRequest, AddSequenceKeyframeResponse>;
567
585
  '/api/add-effect-keyframe': ReqAndRes<AddEffectKeyframeRequest, AddEffectKeyframeResponse>;
586
+ '/api/add-keyframes': ReqAndRes<AddKeyframesRequest, AddKeyframesResponse>;
568
587
  '/api/update-sequence-keyframe-settings': ReqAndRes<UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse>;
569
588
  '/api/update-effect-keyframe-settings': ReqAndRes<UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse>;
570
589
  '/api/delete-effect': ReqAndRes<DeleteEffectRequest, DeleteEffectResponse>;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  export { splitAnsi, stripAnsi } from './ansi';
2
- export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddEffectRequest, AddEffectResponse, AddRenderRequest, AddSequenceKeyframeRequest, AddSequenceKeyframeResponse, ApiRoutes, ApplyCodemodRequest, ApplyCodemodResponse, ApplyVisualControlRequest, ApplyVisualControlResponse, CanUpdateDefaultPropsResponse, CanUpdateSequencePropsRequest, CancelRenderRequest, CancelRenderResponse, CompositionComponentInfoRequest, CompositionComponentInfoResponse, CopyStillToClipboardRequest, DeleteEffectKeyframe, DeleteEffectRequest, DeleteEffectRequestItem, DeleteEffectResponse, DeleteJsxNodeRequest, DeleteJsxNodeRequestItem, DeleteJsxNodeResponse, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe, DeleteStaticFileRequest, DeleteStaticFileResponse, DownloadRemoteAssetRequest, DownloadRemoteAssetResponse, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, InsertJsxElementRequest, InsertJsxElementResponse, InsertableCompositionElement, InstallPackageRequest, InstallPackageResponse, LogStudioErrorRequest, LogStudioErrorResponse, MoveEffectKeyframe, MoveKeyframesRequest, MoveKeyframesResponse, MoveSequenceKeyframe, OpenInEditorRequest, OpenInEditorResponse, OpenInFileExplorerRequest, PasteEffectsRequest, PasteEffectsResponse, ProjectInfoRequest, ProjectInfoResponse, RedoRequest, RedoResponse, RemoveRenderRequest, RenameStaticFileRequest, RenameStaticFileResponse, ReorderEffectRequest, ReorderEffectResponse, ReorderSequencePosition, ReorderSequenceRequest, ReorderSequenceResponse, RestartStudioRequest, RestartStudioResponse, SaveEffectPropsRequest, SaveEffectPropsResponse, SaveSequencePropEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse, UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse, type KeyframeSettings, } from './api-requests';
2
+ export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddKeyframesRequest, AddKeyframesResponse, AddEffectRequest, AddEffectResponse, AddRenderRequest, AddSequenceKeyframeRequest, AddSequenceKeyframeResponse, ApiRoutes, ApplyCodemodRequest, ApplyCodemodResponse, ApplyVisualControlRequest, ApplyVisualControlResponse, CanUpdateDefaultPropsResponse, CanUpdateSequencePropsRequest, CancelRenderRequest, CancelRenderResponse, CompositionComponentInfoRequest, CompositionComponentInfoResponse, CopyStillToClipboardRequest, DeleteEffectKeyframe, DeleteEffectRequest, DeleteEffectRequestItem, DeleteEffectResponse, DeleteJsxNodeRequest, DeleteJsxNodeRequestItem, DeleteJsxNodeResponse, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe, DeleteStaticFileRequest, DeleteStaticFileResponse, DownloadRemoteAssetRequest, DownloadRemoteAssetResponse, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, InsertJsxElementRequest, InsertJsxElementResponse, InsertableCompositionElement, InstallPackageRequest, InstallPackageResponse, LogStudioErrorRequest, LogStudioErrorResponse, MoveEffectKeyframe, MoveKeyframesRequest, MoveKeyframesResponse, MoveSequenceKeyframe, OpenInEditorRequest, OpenInEditorResponse, OpenInFileExplorerRequest, PasteEffectsRequest, PasteEffectsResponse, ProjectInfoRequest, ProjectInfoResponse, RedoRequest, RedoResponse, RemoveRenderRequest, RenameStaticFileRequest, RenameStaticFileResponse, ReorderEffectRequest, ReorderEffectResponse, ReorderSequencePosition, ReorderSequenceRequest, ReorderSequenceResponse, RestartStudioRequest, RestartStudioResponse, SaveEffectPropsRequest, SaveEffectPropsResponse, SaveSequencePropEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse, UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse, type KeyframeSettings, type AddEffectKeyframe, type AddSequenceKeyframe, } from './api-requests';
3
3
  export { ASSET_DRAG_MIME_TYPE, makeAssetDragData, parseAssetDragData, type AssetDragData, } from './asset-drag-data';
4
4
  export type { ApplyVisualControlCodemod, RecastCodemod } from './codemods';
5
5
  export { COMPONENT_DRAG_MIME_TYPE, areComponentProps, isComponentIdentifier, isComponentImportPath, makeComponentDragData, parseComponentDragData, type ComponentDragData, type ComponentProp, } from './component-drag-data';
6
6
  export { DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS } from './default-buffer-state-delay-in-milliseconds';
7
+ export { KEYFRAME_EASING_PRESETS, type KeyframeEasingPreset, } from './keyframe-easing-presets';
7
8
  export { detectFileType, isImageFileType, type FileDimensions, type FileType, type ImageFileType, } from './detect-file-type';
8
9
  export { parseEffectClipboardData, parseEffectClipboardDataResult, parseEffectPropClipboardData, parseEffectPropClipboardDataResult, type EffectClipboardClamping, type EffectClipboardData, type EffectClipboardDataParseResult, type EffectClipboardEasing, type EffectClipboardExtrapolateType, type EffectClipboardInterpolationFunction, type EffectClipboardKeyframe, type EffectClipboardKeyframedParam, type EffectClipboardParam, type EffectClipboardPasteType, type EffectClipboardSnapshot, type EffectClipboardStaticParam, type EffectPropClipboardData, type EffectPropClipboardDataParseResult, } from './effect-clipboard-data';
9
10
  export { EFFECT_DRAG_MIME_TYPE, parseEffectDragData, type EffectDragData, } from './effect-drag-data';
@@ -32,7 +33,7 @@ export { EnumPath, stringifyDefaultProps } from './stringify-default-props';
32
33
  export type { VisualControlChange } from './codemods';
33
34
  export { optimisticAddEffectKeyframe, optimisticAddSequenceKeyframe, } from './optimistic-add-keyframe';
34
35
  export { optimisticDeleteEffectKeyframe, optimisticDeleteEffectKeyframes, optimisticDeleteSequenceKeyframe, optimisticDeleteSequenceKeyframes, } from './optimistic-delete-keyframe';
35
- export { canMoveKeyframesWithoutCollisions, optimisticMoveEffectKeyframes, optimisticMoveSequenceKeyframes, type OptimisticKeyframeMove, } from './optimistic-move-keyframe';
36
+ export { canMoveKeyframesWithoutCollisions, moveKeyframesInPropStatus, optimisticMoveEffectKeyframes, optimisticMoveSequenceKeyframes, type OptimisticKeyframeMove, } from './optimistic-move-keyframe';
36
37
  export { optimisticUpdateForEffectPropStatuses } from './optimistic-update-for-effect-prop-statuses';
37
38
  export { optimisticUpdateForPropStatuses } from './optimistic-update-for-prop-statuses';
38
39
  export { optimisticUpdateEffectKeyframeSettings, optimisticUpdateSequenceKeyframeSettings, } from './optimistic-update-keyframe-settings';
package/dist/index.js CHANGED
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.optimisticDeleteEffectKeyframes = exports.optimisticDeleteEffectKeyframe = exports.optimisticAddSequenceKeyframe = exports.optimisticAddEffectKeyframe = exports.stringifyDefaultProps = exports.parseSfxDragData = exports.SFX_DRAG_MIME_TYPE = exports.getFieldsToShow = exports.getEffectFieldsToShow = exports.SCHEMA_FIELD_ROW_HEIGHT = exports.getRequiredPackageForInsertableElement = exports.getRequiredPackageForEffectImportPath = exports.packages = exports.installableMap = exports.extraPackages = exports.descriptions = exports.apiDocs = exports.DEFAULT_TIMELINE_TRACKS = exports.keyframeInterpolationFunctions = exports.isSequenceFieldSchemaKeyframable = exports.isSchemaFieldKeyframable = exports.isKeyframeInterpolationFunction = exports.getKeyframeInterpolationFunctionForSchemaField = exports.getKeyframeInterpolationFunction = exports.hotMiddlewareOptions = exports.getProjectName = exports.getLocationFromBuildError = exports.getDefaultOutLocation = exports.getAllSchemaKeys = exports.formatBytes = exports.parseEffectDragData = exports.EFFECT_DRAG_MIME_TYPE = exports.parseEffectPropClipboardDataResult = exports.parseEffectPropClipboardData = exports.parseEffectClipboardDataResult = exports.parseEffectClipboardData = exports.isImageFileType = exports.detectFileType = exports.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = exports.parseComponentDragData = exports.makeComponentDragData = exports.isComponentImportPath = exports.isComponentIdentifier = exports.areComponentProps = exports.COMPONENT_DRAG_MIME_TYPE = exports.parseAssetDragData = exports.makeAssetDragData = exports.ASSET_DRAG_MIME_TYPE = exports.stripAnsi = exports.splitAnsi = void 0;
18
- exports.isUrl = exports.stringifySequenceSubscriptionKey = exports.stringifySequenceExpandedRowKey = exports.optimisticUpdateSequenceKeyframeSettings = exports.optimisticUpdateEffectKeyframeSettings = exports.optimisticUpdateForPropStatuses = exports.optimisticUpdateForEffectPropStatuses = exports.optimisticMoveSequenceKeyframes = exports.optimisticMoveEffectKeyframes = exports.canMoveKeyframesWithoutCollisions = exports.optimisticDeleteSequenceKeyframes = exports.optimisticDeleteSequenceKeyframe = void 0;
17
+ exports.optimisticDeleteEffectKeyframe = exports.optimisticAddSequenceKeyframe = exports.optimisticAddEffectKeyframe = exports.stringifyDefaultProps = exports.parseSfxDragData = exports.SFX_DRAG_MIME_TYPE = exports.getFieldsToShow = exports.getEffectFieldsToShow = exports.SCHEMA_FIELD_ROW_HEIGHT = exports.getRequiredPackageForInsertableElement = exports.getRequiredPackageForEffectImportPath = exports.packages = exports.installableMap = exports.extraPackages = exports.descriptions = exports.apiDocs = exports.DEFAULT_TIMELINE_TRACKS = exports.keyframeInterpolationFunctions = exports.isSequenceFieldSchemaKeyframable = exports.isSchemaFieldKeyframable = exports.isKeyframeInterpolationFunction = exports.getKeyframeInterpolationFunctionForSchemaField = exports.getKeyframeInterpolationFunction = exports.hotMiddlewareOptions = exports.getProjectName = exports.getLocationFromBuildError = exports.getDefaultOutLocation = exports.getAllSchemaKeys = exports.formatBytes = exports.parseEffectDragData = exports.EFFECT_DRAG_MIME_TYPE = exports.parseEffectPropClipboardDataResult = exports.parseEffectPropClipboardData = exports.parseEffectClipboardDataResult = exports.parseEffectClipboardData = exports.isImageFileType = exports.detectFileType = exports.KEYFRAME_EASING_PRESETS = exports.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = exports.parseComponentDragData = exports.makeComponentDragData = exports.isComponentImportPath = exports.isComponentIdentifier = exports.areComponentProps = exports.COMPONENT_DRAG_MIME_TYPE = exports.parseAssetDragData = exports.makeAssetDragData = exports.ASSET_DRAG_MIME_TYPE = exports.stripAnsi = exports.splitAnsi = void 0;
18
+ exports.isUrl = exports.stringifySequenceSubscriptionKey = exports.stringifySequenceExpandedRowKey = exports.optimisticUpdateSequenceKeyframeSettings = exports.optimisticUpdateEffectKeyframeSettings = exports.optimisticUpdateForPropStatuses = exports.optimisticUpdateForEffectPropStatuses = exports.optimisticMoveSequenceKeyframes = exports.optimisticMoveEffectKeyframes = exports.moveKeyframesInPropStatus = exports.canMoveKeyframesWithoutCollisions = exports.optimisticDeleteSequenceKeyframes = exports.optimisticDeleteSequenceKeyframe = exports.optimisticDeleteEffectKeyframes = void 0;
19
19
  const ansi_1 = require("./ansi");
20
20
  Object.defineProperty(exports, "splitAnsi", { enumerable: true, get: function () { return ansi_1.splitAnsi; } });
21
21
  Object.defineProperty(exports, "stripAnsi", { enumerable: true, get: function () { return ansi_1.stripAnsi; } });
@@ -33,6 +33,8 @@ Object.defineProperty(exports, "makeComponentDragData", { enumerable: true, get:
33
33
  Object.defineProperty(exports, "parseComponentDragData", { enumerable: true, get: function () { return component_drag_data_1.parseComponentDragData; } });
34
34
  const default_buffer_state_delay_in_milliseconds_1 = require("./default-buffer-state-delay-in-milliseconds");
35
35
  Object.defineProperty(exports, "DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS", { enumerable: true, get: function () { return default_buffer_state_delay_in_milliseconds_1.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS; } });
36
+ const keyframe_easing_presets_1 = require("./keyframe-easing-presets");
37
+ Object.defineProperty(exports, "KEYFRAME_EASING_PRESETS", { enumerable: true, get: function () { return keyframe_easing_presets_1.KEYFRAME_EASING_PRESETS; } });
36
38
  const detect_file_type_1 = require("./detect-file-type");
37
39
  Object.defineProperty(exports, "detectFileType", { enumerable: true, get: function () { return detect_file_type_1.detectFileType; } });
38
40
  Object.defineProperty(exports, "isImageFileType", { enumerable: true, get: function () { return detect_file_type_1.isImageFileType; } });
@@ -93,6 +95,7 @@ Object.defineProperty(exports, "optimisticDeleteSequenceKeyframe", { enumerable:
93
95
  Object.defineProperty(exports, "optimisticDeleteSequenceKeyframes", { enumerable: true, get: function () { return optimistic_delete_keyframe_1.optimisticDeleteSequenceKeyframes; } });
94
96
  const optimistic_move_keyframe_1 = require("./optimistic-move-keyframe");
95
97
  Object.defineProperty(exports, "canMoveKeyframesWithoutCollisions", { enumerable: true, get: function () { return optimistic_move_keyframe_1.canMoveKeyframesWithoutCollisions; } });
98
+ Object.defineProperty(exports, "moveKeyframesInPropStatus", { enumerable: true, get: function () { return optimistic_move_keyframe_1.moveKeyframesInPropStatus; } });
96
99
  Object.defineProperty(exports, "optimisticMoveEffectKeyframes", { enumerable: true, get: function () { return optimistic_move_keyframe_1.optimisticMoveEffectKeyframes; } });
97
100
  Object.defineProperty(exports, "optimisticMoveSequenceKeyframes", { enumerable: true, get: function () { return optimistic_move_keyframe_1.optimisticMoveSequenceKeyframes; } });
98
101
  const optimistic_update_for_effect_prop_statuses_1 = require("./optimistic-update-for-effect-prop-statuses");
@@ -0,0 +1,7 @@
1
+ export type KeyframeEasing = 'linear' | [number, number, number, number];
2
+ export type KeyframeEasingPreset = {
3
+ readonly id: 'ease-in' | 'ease-out' | 'ease-in-out';
4
+ readonly label: string;
5
+ readonly easing: KeyframeEasing;
6
+ };
7
+ export declare const KEYFRAME_EASING_PRESETS: KeyframeEasingPreset[];
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KEYFRAME_EASING_PRESETS = void 0;
4
+ exports.KEYFRAME_EASING_PRESETS = [
5
+ { id: 'ease-in', label: 'Ease in', easing: [0.42, 0, 1, 1] },
6
+ { id: 'ease-out', label: 'Ease out', easing: [0, 0, 0.58, 1] },
7
+ { id: 'ease-in-out', label: 'Ease in-out', easing: [0.42, 0, 0.58, 1] },
8
+ ];
@@ -48,6 +48,7 @@ const getKeyframeInterpolationFunctionForSchemaField = ({ schema, key, }) => {
48
48
  }
49
49
  if ((field === null || field === void 0 ? void 0 : field.type) === 'scale' ||
50
50
  (field === null || field === void 0 ? void 0 : field.type) === 'translate' ||
51
+ (field === null || field === void 0 ? void 0 : field.type) === 'transform-origin' ||
51
52
  (field === null || field === void 0 ? void 0 : field.type) === 'rotation-css') {
52
53
  return 'interpolate';
53
54
  }
@@ -11,6 +11,13 @@ export declare const canMoveKeyframesWithoutCollisions: ({ status, moves, }: {
11
11
  toFrame: number;
12
12
  }[];
13
13
  }) => boolean;
14
+ export declare const moveKeyframesInPropStatus: ({ status, moves, }: {
15
+ status: CanUpdateSequencePropStatus;
16
+ moves: readonly {
17
+ fromFrame: number;
18
+ toFrame: number;
19
+ }[];
20
+ }) => CanUpdateSequencePropStatus;
14
21
  export declare const optimisticMoveSequenceKeyframes: ({ previous, keyframes, }: {
15
22
  previous: CanUpdateSequencePropsResponse;
16
23
  keyframes: readonly OptimisticKeyframeMove[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.optimisticMoveEffectKeyframes = exports.optimisticMoveSequenceKeyframes = exports.canMoveKeyframesWithoutCollisions = void 0;
3
+ exports.optimisticMoveEffectKeyframes = exports.optimisticMoveSequenceKeyframes = exports.moveKeyframesInPropStatus = exports.canMoveKeyframesWithoutCollisions = void 0;
4
4
  const getMoveMap = (moves) => {
5
5
  const moveMap = new Map();
6
6
  for (const move of moves) {
@@ -14,62 +14,86 @@ const getMoveMap = (moves) => {
14
14
  }
15
15
  return moveMap;
16
16
  };
17
- const canMoveKeyframesWithoutCollisions = ({ status, moves, }) => {
18
- var _a;
17
+ const getMovedKeyframes = ({ status, moves, }) => {
19
18
  if (status.status !== 'keyframed') {
20
- return false;
19
+ return null;
21
20
  }
22
21
  const moveMap = getMoveMap(moves);
23
22
  if (moveMap === null) {
24
- return false;
23
+ return null;
25
24
  }
26
25
  if (moveMap.size === 0) {
27
- return true;
26
+ return { keyframes: status.keyframes, removedKeyframeIndexes: [] };
28
27
  }
29
28
  const frames = new Set(status.keyframes.map((keyframe) => keyframe.frame));
30
29
  for (const fromFrame of moveMap.keys()) {
31
30
  if (!frames.has(fromFrame)) {
32
- return false;
31
+ return null;
33
32
  }
34
33
  }
34
+ const movedFromFrames = new Set(moveMap.keys());
35
+ const movedToFrames = new Set(moveMap.values());
36
+ const removedKeyframeIndexes = [];
37
+ const nextKeyframes = status.keyframes.flatMap((keyframe, index) => {
38
+ const movedFrame = moveMap.get(keyframe.frame);
39
+ if (movedFrame !== undefined) {
40
+ return [{ ...keyframe, frame: movedFrame }];
41
+ }
42
+ if (movedToFrames.has(keyframe.frame) &&
43
+ !movedFromFrames.has(keyframe.frame)) {
44
+ removedKeyframeIndexes.push(index);
45
+ return [];
46
+ }
47
+ return [keyframe];
48
+ });
35
49
  const nextFrames = new Set();
36
- for (const keyframe of status.keyframes) {
37
- const frame = (_a = moveMap.get(keyframe.frame)) !== null && _a !== void 0 ? _a : keyframe.frame;
38
- if (nextFrames.has(frame)) {
39
- return false;
50
+ for (const keyframe of nextKeyframes) {
51
+ if (nextFrames.has(keyframe.frame)) {
52
+ return null;
53
+ }
54
+ nextFrames.add(keyframe.frame);
55
+ }
56
+ return {
57
+ keyframes: nextKeyframes.sort((a, b) => a.frame - b.frame),
58
+ removedKeyframeIndexes,
59
+ };
60
+ };
61
+ const removeEasingForRemovedKeyframes = ({ easing, removedKeyframeIndexes, }) => {
62
+ const nextEasing = [...easing];
63
+ for (const removedKeyframeIndex of [...removedKeyframeIndexes].sort((a, b) => b - a)) {
64
+ if (nextEasing.length === 0) {
65
+ break;
40
66
  }
41
- nextFrames.add(frame);
67
+ const easingIndexToRemove = removedKeyframeIndex === 0 ? 0 : removedKeyframeIndex - 1;
68
+ nextEasing.splice(easingIndexToRemove, 1);
42
69
  }
43
- return true;
70
+ return nextEasing;
71
+ };
72
+ const canMoveKeyframesWithoutCollisions = ({ status, moves, }) => {
73
+ return getMovedKeyframes({ status, moves }) !== null;
44
74
  };
45
75
  exports.canMoveKeyframesWithoutCollisions = canMoveKeyframesWithoutCollisions;
46
76
  const moveKeyframesInPropStatus = ({ status, moves, }) => {
47
77
  if (status.status !== 'keyframed') {
48
78
  return status;
49
79
  }
50
- if (!(0, exports.canMoveKeyframesWithoutCollisions)({ status, moves })) {
51
- return status;
52
- }
53
- const moveMap = getMoveMap(moves);
54
- if (moveMap === null) {
55
- return status;
56
- }
57
- if (moveMap.size === 0) {
80
+ const moved = getMovedKeyframes({ status, moves });
81
+ if (moved === null ||
82
+ (moved.removedKeyframeIndexes.length === 0 &&
83
+ moved.keyframes === status.keyframes)) {
58
84
  return status;
59
85
  }
86
+ const easing = removeEasingForRemovedKeyframes({
87
+ easing: status.easing,
88
+ removedKeyframeIndexes: moved.removedKeyframeIndexes,
89
+ });
60
90
  return {
61
91
  ...status,
62
- keyframes: status.keyframes
63
- .map((keyframe) => {
64
- var _a;
65
- return ({
66
- ...keyframe,
67
- frame: (_a = moveMap.get(keyframe.frame)) !== null && _a !== void 0 ? _a : keyframe.frame,
68
- });
69
- })
70
- .sort((a, b) => a.frame - b.frame),
92
+ keyframes: moved.keyframes,
93
+ easing,
71
94
  };
72
95
  };
96
+ exports.moveKeyframesInPropStatus = moveKeyframesInPropStatus;
73
97
  const optimisticMoveSequenceKeyframes = ({ previous, keyframes, }) => {
74
98
  var _a;
75
99
  if (!previous.canUpdate) {
@@ -87,7 +111,7 @@ const optimisticMoveSequenceKeyframes = ({ previous, keyframes, }) => {
87
111
  if (!status) {
88
112
  continue;
89
113
  }
90
- props[fieldKey] = moveKeyframesInPropStatus({ status, moves });
114
+ props[fieldKey] = (0, exports.moveKeyframesInPropStatus)({ status, moves });
91
115
  }
92
116
  return {
93
117
  ...previous,
@@ -127,7 +151,7 @@ const optimisticMoveEffectKeyframes = ({ previous, keyframes, }) => {
127
151
  if (!status) {
128
152
  continue;
129
153
  }
130
- props[fieldKey] = moveKeyframesInPropStatus({ status, moves });
154
+ props[fieldKey] = (0, exports.moveKeyframesInPropStatus)({ status, moves });
131
155
  }
132
156
  return {
133
157
  ...effect,
@@ -1,14 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.optimisticUpdateEffectKeyframeSettings = exports.optimisticUpdateSequenceKeyframeSettings = void 0;
4
+ const updateEasing = ({ easing, segmentCount, segmentIndex, value, }) => {
5
+ if (!Number.isInteger(segmentIndex) ||
6
+ segmentIndex < 0 ||
7
+ segmentIndex >= segmentCount) {
8
+ throw new Error('Cannot update easing: segment index out of range');
9
+ }
10
+ const nextEasing = Array.from({ length: segmentCount }, (_, index) => {
11
+ var _a;
12
+ return (_a = easing[index]) !== null && _a !== void 0 ? _a : 'linear';
13
+ });
14
+ nextEasing[segmentIndex] = value;
15
+ return nextEasing;
16
+ };
4
17
  const applySettingsToStatus = (status, settings) => {
5
18
  if (!status || status.status !== 'keyframed') {
6
19
  throw new Error('Expected keyframed status');
7
20
  }
8
21
  return {
9
22
  ...status,
10
- ...(settings.clamping ? { clamping: settings.clamping } : {}),
11
- posterize: settings.posterize,
23
+ ...(settings.type === 'settings' && settings.clamping
24
+ ? { clamping: settings.clamping }
25
+ : {}),
26
+ ...(settings.type === 'settings' ? { posterize: settings.posterize } : {}),
27
+ ...(settings.type === 'easing'
28
+ ? {
29
+ easing: updateEasing({
30
+ easing: status.easing,
31
+ segmentCount: Math.max(0, status.keyframes.length - 1),
32
+ segmentIndex: settings.segmentIndex,
33
+ value: settings.easing,
34
+ }),
35
+ }
36
+ : {}),
12
37
  };
13
38
  };
14
39
  const optimisticUpdateSequenceKeyframeSettings = ({ previous, fieldKey, settings, }) => {
@@ -1,4 +1,4 @@
1
- export declare const packages: readonly ["svg-3d-engine", "animation-utils", "animated-emoji", "astro-example", "babel-loader", "bugs", "brand", "bundler", "cli", "cloudrun", "codex-plugin", "compositor-darwin-arm64", "compositor-darwin-x64", "compositor-linux-arm64-gnu", "compositor-linux-arm64-musl", "compositor-linux-x64-gnu", "compositor-linux-x64-musl", "compositor-win32-x64-msvc", "core", "create-video", "discord-poster", "docusaurus-plugin", "docs", "enable-scss", "eslint-config", "eslint-config-flat", "eslint-config-internal", "eslint-plugin", "example-without-zod", "example", "fonts", "gif", "google-fonts", "install-whisper-cpp", "it-tests", "react18-tests", "lambda-go-example", "lambda-go", "lambda-php", "lambda-ruby", "lambda-python", "lambda", "lambda-client", "layout-utils", "rounded-text-box", "licensing", "lottie", "mcp", "media-utils", "motion-blur", "noise", "paths", "player-a11y", "player-example", "player", "preload", "renderer", "rive", "shapes", "skia", "promo-pages", "streaming", "serverless", "serverless-client", "skills", "skills-evals", "studio-server", "studio-shared", "studio", "tailwind", "tailwind-v4", "timeline-utils", "test-utils", "three", "transitions", "media-parser", "zod-types", "zod-types-v3", "webcodecs", "convert", "captions", "openai-whisper", "elevenlabs", "compositor", "example-videos", "whisper-web", "media", "remotion-media", "web-renderer", "design", "light-leaks", "starburst", "vercel", "sfx", "effects"];
1
+ export declare const packages: readonly ["svg-3d-engine", "animation-utils", "animated-emoji", "astro-example", "babel-loader", "bugs", "brand", "bundler", "canvas-capture", "cli", "cloudrun", "codex-plugin", "compositor-darwin-arm64", "compositor-darwin-x64", "compositor-linux-arm64-gnu", "compositor-linux-arm64-musl", "compositor-linux-x64-gnu", "compositor-linux-x64-musl", "compositor-win32-x64-msvc", "core", "create-video", "discord-poster", "docusaurus-plugin", "docs", "enable-scss", "eslint-config", "eslint-config-flat", "eslint-config-internal", "eslint-plugin", "example-without-zod", "example", "fonts", "gif", "google-fonts", "install-whisper-cpp", "it-tests", "react18-tests", "lambda-go-example", "lambda-go", "lambda-php", "lambda-ruby", "lambda-python", "lambda", "lambda-client", "layout-utils", "rounded-text-box", "licensing", "lottie", "mcp", "media-utils", "motion-blur", "noise", "paths", "player-a11y", "player-example", "player", "preload", "renderer", "rive", "shapes", "skia", "promo-pages", "streaming", "serverless", "serverless-client", "skills", "skills-evals", "studio-server", "studio-shared", "studio", "tailwind", "tailwind-v4", "timeline-utils", "test-utils", "three", "transitions", "media-parser", "zod-types", "zod-types-v3", "webcodecs", "convert", "captions", "openai-whisper", "elevenlabs", "compositor", "example-videos", "whisper-web", "media", "remotion-media", "web-renderer", "design", "light-leaks", "starburst", "vercel", "sfx", "effects"];
2
2
  export type Pkgs = (typeof packages)[number];
3
3
  export type ExtraPackage = {
4
4
  name: string;
@@ -10,6 +10,7 @@ exports.packages = [
10
10
  'bugs',
11
11
  'brand',
12
12
  'bundler',
13
+ 'canvas-capture',
13
14
  'cli',
14
15
  'cloudrun',
15
16
  'codex-plugin',
@@ -128,6 +129,7 @@ exports.descriptions = {
128
129
  core: 'Make videos programmatically',
129
130
  lambda: 'Render Remotion videos on AWS Lambda',
130
131
  bundler: 'Bundle Remotion compositions using Webpack',
132
+ 'canvas-capture': 'Capture HTML-in-canvas content as a video',
131
133
  'studio-server': 'Run a Remotion Studio with a server backend',
132
134
  'install-whisper-cpp': 'Helpers for installing and using Whisper.cpp',
133
135
  'whisper-web': 'Helpers for using Whisper.cpp in browser using WASM',
@@ -224,6 +226,7 @@ exports.installableMap = {
224
226
  bugs: false,
225
227
  brand: false,
226
228
  bundler: false,
229
+ 'canvas-capture': false,
227
230
  cli: false,
228
231
  cloudrun: true,
229
232
  'codex-plugin': false,
@@ -321,6 +324,7 @@ exports.apiDocs = {
321
324
  core: 'https://www.remotion.dev/docs/remotion',
322
325
  lambda: 'https://www.remotion.dev/docs/lambda',
323
326
  bundler: 'https://www.remotion.dev/docs/bundler',
327
+ 'canvas-capture': null,
324
328
  'lambda-client': null,
325
329
  'serverless-client': null,
326
330
  'studio-server': null,
@@ -17,7 +17,7 @@ export type EffectSchemaFieldInfo = SchemaFieldInfo & {
17
17
  };
18
18
  export type AnySchemaFieldInfo = SequenceSchemaFieldInfo | EffectSchemaFieldInfo;
19
19
  export declare const SCHEMA_FIELD_ROW_HEIGHT = 22;
20
- declare const SUPPORTED_SCHEMA_TYPES: readonly ["number", "boolean", "rotation-css", "rotation-degrees", "translate", "scale", "uv-coordinate", "color", "array", "enum", "hidden"];
20
+ declare const SUPPORTED_SCHEMA_TYPES: readonly ["number", "boolean", "rotation-css", "rotation-degrees", "translate", "transform-origin", "scale", "uv-coordinate", "color", "array", "enum", "hidden"];
21
21
  type SupportedSchemaType = (typeof SUPPORTED_SCHEMA_TYPES)[number];
22
22
  export declare const getFieldsToShow: ({ getDragOverrides, propStatuses, nodePath, schema, currentRuntimeValueDotNotation, }: {
23
23
  schema: SequenceSchema;
@@ -10,6 +10,7 @@ const SUPPORTED_SCHEMA_TYPES = [
10
10
  'rotation-css',
11
11
  'rotation-degrees',
12
12
  'translate',
13
+ 'transform-origin',
13
14
  'scale',
14
15
  'uv-coordinate',
15
16
  'color',
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-shared"
4
4
  },
5
5
  "name": "@remotion/studio-shared",
6
- "version": "4.0.474",
6
+ "version": "4.0.476",
7
7
  "description": "Internal package for shared objects between the Studio backend and frontend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -20,11 +20,11 @@
20
20
  "url": "https://github.com/remotion-dev/remotion/issues"
21
21
  },
22
22
  "dependencies": {
23
- "remotion": "4.0.474"
23
+ "remotion": "4.0.476"
24
24
  },
25
25
  "devDependencies": {
26
- "@remotion/renderer": "4.0.474",
27
- "@remotion/eslint-config-internal": "4.0.474",
26
+ "@remotion/renderer": "4.0.476",
27
+ "@remotion/eslint-config-internal": "4.0.476",
28
28
  "eslint": "9.19.0",
29
29
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
30
30
  },