@remotion/studio 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.
Files changed (94) hide show
  1. package/dist/components/Canvas.js +6 -0
  2. package/dist/components/ColorPicker/ColorPicker.js +4 -31
  3. package/dist/components/ColorPicker/ColorPickerPopup.d.ts +6 -0
  4. package/dist/components/ColorPicker/ColorPickerPopup.js +11 -6
  5. package/dist/components/CompositionSelectorItem.js +4 -4
  6. package/dist/components/Editor.js +4 -1
  7. package/dist/components/GlobalKeybindings.js +12 -0
  8. package/dist/components/KeyboardShortcutsExplainer.js +24 -0
  9. package/dist/components/Modals.js +2 -1
  10. package/dist/components/NewComposition/ComboBox.js +1 -0
  11. package/dist/components/NewComposition/InputDragger.d.ts +6 -0
  12. package/dist/components/NewComposition/InputDragger.js +40 -14
  13. package/dist/components/NewComposition/RenameComposition.js +8 -1
  14. package/dist/components/NewComposition/RenameFolder.js +8 -1
  15. package/dist/components/NewComposition/RenameStaticFile.js +11 -1
  16. package/dist/components/Notifications/Notification.js +5 -4
  17. package/dist/components/Notifications/NotificationCenter.js +1 -1
  18. package/dist/components/ObserveDefaultPropsContext.js +6 -2
  19. package/dist/components/PlayPause.js +22 -66
  20. package/dist/components/PreviewToolbar.js +17 -3
  21. package/dist/components/RenderModal/RenderModalJSONPropsEditor.js +2 -1
  22. package/dist/components/SelectedOutlineOverlay.d.ts +104 -42
  23. package/dist/components/SelectedOutlineOverlay.js +1278 -336
  24. package/dist/components/SelectedOutlineUvControls.d.ts +17 -0
  25. package/dist/components/SelectedOutlineUvControls.js +167 -0
  26. package/dist/components/StudioCanvasCapture.d.ts +5 -0
  27. package/dist/components/StudioCanvasCapture.js +40 -0
  28. package/dist/components/Timeline/EasingEditorModal.d.ts +11 -0
  29. package/dist/components/Timeline/EasingEditorModal.js +247 -0
  30. package/dist/components/Timeline/KeyframeSettingsModal.js +1 -0
  31. package/dist/components/Timeline/Timeline.js +10 -7
  32. package/dist/components/Timeline/TimelineDeleteKeybindings.js +64 -35
  33. package/dist/components/Timeline/TimelineDragHandler.js +2 -2
  34. package/dist/components/Timeline/TimelineEffectItem.js +1 -2
  35. package/dist/components/Timeline/TimelineEffectPropItem.js +1 -1
  36. package/dist/components/Timeline/TimelineExpandedKeyframeRow.d.ts +1 -0
  37. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +2 -2
  38. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +1 -1
  39. package/dist/components/Timeline/TimelineHeightContainer.js +2 -0
  40. package/dist/components/Timeline/TimelineItemStack.js +3 -56
  41. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +7 -0
  42. package/dist/components/Timeline/TimelineKeyframeControls.js +259 -62
  43. package/dist/components/Timeline/TimelineKeyframeDiamond.js +4 -2
  44. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +128 -3
  45. package/dist/components/Timeline/TimelineKeyframeTracksContext.d.ts +7 -0
  46. package/dist/components/Timeline/TimelineKeyframeTracksContext.js +17 -0
  47. package/dist/components/Timeline/TimelineMediaInfo.js +4 -24
  48. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  49. package/dist/components/Timeline/TimelineRotationField.js +21 -39
  50. package/dist/components/Timeline/TimelineScaleField.js +1 -1
  51. package/dist/components/Timeline/TimelineScrollable.js +19 -3
  52. package/dist/components/Timeline/TimelineSelection.d.ts +67 -3
  53. package/dist/components/Timeline/TimelineSelection.js +289 -32
  54. package/dist/components/Timeline/TimelineSequence.js +17 -9
  55. package/dist/components/Timeline/TimelineSequenceItem.js +328 -168
  56. package/dist/components/Timeline/TimelineSequenceName.d.ts +4 -2
  57. package/dist/components/Timeline/TimelineSequenceName.js +70 -19
  58. package/dist/components/Timeline/TimelineSequencePropItem.js +1 -1
  59. package/dist/components/Timeline/TimelineTimeIndicators.js +4 -2
  60. package/dist/components/Timeline/TimelineTransformOriginField.d.ts +11 -0
  61. package/dist/components/Timeline/TimelineTransformOriginField.js +138 -0
  62. package/dist/components/Timeline/TimelineTranslateField.js +1 -1
  63. package/dist/components/Timeline/TimelineUvCoordinateField.js +1 -1
  64. package/dist/components/Timeline/call-add-keyframe.d.ts +17 -0
  65. package/dist/components/Timeline/call-add-keyframe.js +65 -1
  66. package/dist/components/Timeline/delete-selected-timeline-item.js +23 -13
  67. package/dist/components/Timeline/disable-sequence-interactivity.d.ts +8 -0
  68. package/dist/components/Timeline/disable-sequence-interactivity.js +24 -0
  69. package/dist/components/Timeline/reset-selected-timeline-props.js +15 -7
  70. package/dist/components/Timeline/timeline-rotation-utils.d.ts +2 -0
  71. package/dist/components/Timeline/timeline-rotation-utils.js +34 -0
  72. package/dist/components/Timeline/transform-origin-utils.d.ts +24 -0
  73. package/dist/components/Timeline/transform-origin-utils.js +170 -0
  74. package/dist/components/Timeline/update-selected-easing.d.ts +35 -0
  75. package/dist/components/Timeline/update-selected-easing.js +133 -0
  76. package/dist/components/Timeline/use-expanded-track-keyframe-rows.d.ts +1 -0
  77. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +28 -0
  78. package/dist/components/Timeline/use-timeline-keyframe-drag.js +8 -13
  79. package/dist/components/canvas-capture-enabled.d.ts +1 -0
  80. package/dist/components/canvas-capture-enabled.js +4 -0
  81. package/dist/components/effect-drag-and-drop.d.ts +11 -0
  82. package/dist/components/effect-drag-and-drop.js +73 -0
  83. package/dist/components/selected-outline-geometry.d.ts +20 -0
  84. package/dist/components/selected-outline-geometry.js +18 -0
  85. package/dist/components/selected-outline-uv.d.ts +46 -0
  86. package/dist/components/selected-outline-uv.js +240 -0
  87. package/dist/esm/{chunk-xjvc8qen.js → chunk-0atarw3p.js} +8779 -5352
  88. package/dist/esm/internals.mjs +8779 -5352
  89. package/dist/esm/previewEntry.mjs +8789 -5362
  90. package/dist/esm/renderEntry.mjs +1 -1
  91. package/dist/helpers/colors.d.ts +0 -1
  92. package/dist/helpers/colors.js +1 -2
  93. package/dist/state/modals.d.ts +2 -1
  94. package/package.json +11 -10
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformOriginPercentToUv = exports.parsedTransformOriginToPercent = exports.serializeTransformOrigin = exports.parsedTransformOriginToUv = exports.axisValueToUv = exports.parseTransformOrigin = void 0;
4
+ const timeline_field_utils_1 = require("./timeline-field-utils");
5
+ const cssNumberWithUnit = /^([+-]?(?:\d+\.?\d*|\.\d+))(px|%)$/i;
6
+ const cssLength = /^([+-]?(?:\d+\.?\d*|\.\d+))[a-zA-Z]+$/;
7
+ const keywords = new Set(['left', 'center', 'right', 'top', 'bottom']);
8
+ const center = { value: 50, unit: '%' };
9
+ const keywordOptions = (keyword) => {
10
+ if (keyword === 'left') {
11
+ return [{ axis: 'x', value: { value: 0, unit: '%' } }];
12
+ }
13
+ if (keyword === 'right') {
14
+ return [{ axis: 'x', value: { value: 100, unit: '%' } }];
15
+ }
16
+ if (keyword === 'top') {
17
+ return [{ axis: 'y', value: { value: 0, unit: '%' } }];
18
+ }
19
+ if (keyword === 'bottom') {
20
+ return [{ axis: 'y', value: { value: 100, unit: '%' } }];
21
+ }
22
+ return [
23
+ { axis: 'x', value: center },
24
+ { axis: 'y', value: center },
25
+ ];
26
+ };
27
+ const parseLengthPercentage = (token) => {
28
+ const match = cssNumberWithUnit.exec(token);
29
+ if (!match) {
30
+ return null;
31
+ }
32
+ const value = Number(match[1]);
33
+ if (!Number.isFinite(value)) {
34
+ return null;
35
+ }
36
+ return { value, unit: match[2].toLowerCase() };
37
+ };
38
+ const parseToken = (token) => {
39
+ const lower = token.toLowerCase();
40
+ if (keywords.has(lower)) {
41
+ return { type: 'keyword', keyword: lower };
42
+ }
43
+ const value = parseLengthPercentage(token);
44
+ return value === null ? null : { type: 'length-percentage', value };
45
+ };
46
+ const parseTwoKeywords = (first, second) => {
47
+ var _a;
48
+ const candidates = [];
49
+ for (const firstOption of keywordOptions(first)) {
50
+ for (const secondOption of keywordOptions(second)) {
51
+ if (firstOption.axis === secondOption.axis) {
52
+ continue;
53
+ }
54
+ candidates.push(firstOption.axis === 'x'
55
+ ? [firstOption.value, secondOption.value]
56
+ : [secondOption.value, firstOption.value]);
57
+ }
58
+ }
59
+ return (_a = candidates[0]) !== null && _a !== void 0 ? _a : null;
60
+ };
61
+ const parseXY = (parts) => {
62
+ if (parts.length === 1) {
63
+ const token = parseToken(parts[0]);
64
+ if (token === null) {
65
+ return null;
66
+ }
67
+ if (token.type === 'length-percentage') {
68
+ return [token.value, center];
69
+ }
70
+ if (token.keyword === 'top' || token.keyword === 'bottom') {
71
+ return [center, keywordOptions(token.keyword)[0].value];
72
+ }
73
+ return [keywordOptions(token.keyword)[0].value, center];
74
+ }
75
+ const first = parseToken(parts[0]);
76
+ const second = parseToken(parts[1]);
77
+ if (first === null || second === null) {
78
+ return null;
79
+ }
80
+ if (first.type === 'length-percentage' &&
81
+ second.type === 'length-percentage') {
82
+ return [first.value, second.value];
83
+ }
84
+ if (first.type === 'keyword' && second.type === 'keyword') {
85
+ return parseTwoKeywords(first.keyword, second.keyword);
86
+ }
87
+ const keyword = first.type === 'keyword'
88
+ ? first
89
+ : second.type === 'keyword'
90
+ ? second
91
+ : null;
92
+ const length = first.type === 'length-percentage'
93
+ ? first.value
94
+ : second.type === 'length-percentage'
95
+ ? second.value
96
+ : null;
97
+ if (keyword === null || length === null) {
98
+ return null;
99
+ }
100
+ const keywordIsFirst = first.type === 'keyword';
101
+ if (keyword.keyword === 'left' || keyword.keyword === 'right') {
102
+ return keywordIsFirst
103
+ ? [keywordOptions(keyword.keyword)[0].value, length]
104
+ : null;
105
+ }
106
+ if (keyword.keyword === 'top' || keyword.keyword === 'bottom') {
107
+ return [length, keywordOptions(keyword.keyword)[0].value];
108
+ }
109
+ return keywordIsFirst ? [center, length] : [length, center];
110
+ };
111
+ const isSupportedZ = (token) => {
112
+ if (token.includes('%')) {
113
+ return false;
114
+ }
115
+ return cssLength.test(token);
116
+ };
117
+ const parseTransformOrigin = (value) => {
118
+ var _a;
119
+ if (typeof value !== 'string') {
120
+ return null;
121
+ }
122
+ const parts = value.trim().split(/\s+/);
123
+ if (parts.length < 1 || parts.length > 3 || parts[0] === '') {
124
+ return null;
125
+ }
126
+ const xy = parseXY(parts.length === 1 ? [parts[0]] : [parts[0], parts[1]]);
127
+ if (xy === null) {
128
+ return null;
129
+ }
130
+ const z = (_a = parts[2]) !== null && _a !== void 0 ? _a : null;
131
+ if (z !== null && !isSupportedZ(z)) {
132
+ return null;
133
+ }
134
+ return { x: xy[0], y: xy[1], z };
135
+ };
136
+ exports.parseTransformOrigin = parseTransformOrigin;
137
+ const axisValueToUv = (axis, size) => {
138
+ if (!Number.isFinite(size) || size <= 0) {
139
+ return null;
140
+ }
141
+ if (axis.unit === '%') {
142
+ return axis.value / 100;
143
+ }
144
+ return axis.value / size;
145
+ };
146
+ exports.axisValueToUv = axisValueToUv;
147
+ const parsedTransformOriginToUv = ({ parsed, width, height, }) => {
148
+ const x = (0, exports.axisValueToUv)(parsed.x, width);
149
+ const y = (0, exports.axisValueToUv)(parsed.y, height);
150
+ return x === null || y === null ? null : [x, y];
151
+ };
152
+ exports.parsedTransformOriginToUv = parsedTransformOriginToUv;
153
+ const formatPercent = (value, decimalPlaces) => {
154
+ const rounded = (0, timeline_field_utils_1.roundToDecimalPlaces)((0, timeline_field_utils_1.normalizeTimelineNumber)(value * 100), decimalPlaces);
155
+ return String(Object.is(rounded, -0) ? 0 : rounded);
156
+ };
157
+ const serializeTransformOrigin = ({ uv, z, decimalPlaces = 2, }) => {
158
+ const xy = `${formatPercent(uv[0], decimalPlaces)}% ${formatPercent(uv[1], decimalPlaces)}%`;
159
+ return z === null ? xy : `${xy} ${z}`;
160
+ };
161
+ exports.serializeTransformOrigin = serializeTransformOrigin;
162
+ const parsedTransformOriginToPercent = (parsed) => {
163
+ if (parsed.x.unit !== '%' || parsed.y.unit !== '%') {
164
+ return null;
165
+ }
166
+ return [parsed.x.value, parsed.y.value];
167
+ };
168
+ exports.parsedTransformOriginToPercent = parsedTransformOriginToPercent;
169
+ const transformOriginPercentToUv = (percent) => [percent[0] / 100, percent[1] / 100];
170
+ exports.transformOriginPercentToUv = transformOriginPercentToUv;
@@ -0,0 +1,35 @@
1
+ import type { OverrideIdToNodePaths, PropStatuses, TSequence } from 'remotion';
2
+ import type { SetPropStatuses } from './save-sequence-prop';
3
+ import type { TimelineEasingSelection, TimelineSelection } from './TimelineSelection';
4
+ export type EasingSelection = TimelineEasingSelection;
5
+ export type TimelineEasingValue = 'linear' | [number, number, number, number];
6
+ export declare const getEasingSelections: (selections: readonly TimelineSelection[]) => ({
7
+ readonly nodePathInfo: import("../../helpers/get-timeline-sequence-sort-key").SequenceNodePathInfo;
8
+ } & {
9
+ readonly type: "easing";
10
+ readonly fromFrame: number;
11
+ readonly toFrame: number;
12
+ readonly segmentIndex: number;
13
+ })[];
14
+ export declare const getTimelineEasingValueForSelection: ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }: {
15
+ selection: {
16
+ readonly nodePathInfo: import("../../helpers/get-timeline-sequence-sort-key").SequenceNodePathInfo;
17
+ } & {
18
+ readonly type: "easing";
19
+ readonly fromFrame: number;
20
+ readonly toFrame: number;
21
+ readonly segmentIndex: number;
22
+ };
23
+ sequences: TSequence[];
24
+ overrideIdsToNodePaths: OverrideIdToNodePaths;
25
+ propStatuses: PropStatuses;
26
+ }) => TimelineEasingValue | null;
27
+ export declare const updateSelectedTimelineEasings: ({ selections, sequences, overrideIdsToNodePaths, propStatuses, setPropStatuses, clientId, easing, }: {
28
+ selections: readonly TimelineSelection[];
29
+ sequences: TSequence[];
30
+ overrideIdsToNodePaths: OverrideIdToNodePaths;
31
+ propStatuses: PropStatuses;
32
+ setPropStatuses: SetPropStatuses;
33
+ clientId: string;
34
+ easing: TimelineEasingValue;
35
+ }) => Promise<void> | null;
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateSelectedTimelineEasings = exports.getTimelineEasingValueForSelection = exports.getEasingSelections = void 0;
4
+ const remotion_1 = require("remotion");
5
+ const call_update_keyframe_settings_1 = require("./call-update-keyframe-settings");
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 canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
9
+ interpolationFunction === 'interpolateColors';
10
+ const isEasingSelection = (selection) => selection.type === 'easing';
11
+ const getSelectedEasingUpdate = ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }) => {
12
+ var _a;
13
+ var _b, _c, _d;
14
+ const field = (0, parse_keyframe_field_from_node_path_1.parseKeyframeFieldFromNodePath)(selection.nodePathInfo.auxiliaryKeys);
15
+ if (field === null) {
16
+ return null;
17
+ }
18
+ const track = (0, find_track_for_node_path_info_1.findTrackForNodePathInfo)({
19
+ sequences,
20
+ overrideIdsToNodePaths,
21
+ nodePathInfo: selection.nodePathInfo,
22
+ });
23
+ const sequence = (_b = track === null || track === void 0 ? void 0 : track.sequence) !== null && _b !== void 0 ? _b : null;
24
+ if (!sequence) {
25
+ return null;
26
+ }
27
+ const nodePath = selection.nodePathInfo.sequenceSubscriptionKey;
28
+ const fileName = nodePath.absolutePath;
29
+ if (field.type === 'sequence') {
30
+ if (!sequence.controls) {
31
+ return null;
32
+ }
33
+ const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _a === void 0 ? void 0 : _a[field.fieldKey];
34
+ if ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) !== 'keyframed' ||
35
+ !canEditEasingForInterpolationFunction(sequencePropStatus.interpolationFunction)) {
36
+ return null;
37
+ }
38
+ return {
39
+ type: 'sequence',
40
+ fileName,
41
+ nodePath,
42
+ fieldKey: field.fieldKey,
43
+ schema: sequence.controls.schema,
44
+ segmentIndex: selection.segmentIndex,
45
+ currentEasing: (_c = sequencePropStatus.easing[selection.segmentIndex]) !== null && _c !== void 0 ? _c : 'linear',
46
+ };
47
+ }
48
+ const effect = sequence.effects[field.effectIndex];
49
+ if (!effect) {
50
+ return null;
51
+ }
52
+ const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
53
+ propStatuses,
54
+ nodePath,
55
+ effectIndex: field.effectIndex,
56
+ });
57
+ const effectPropStatus = effectStatus.type === 'can-update-effect'
58
+ ? effectStatus.props[field.fieldKey]
59
+ : null;
60
+ if ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) !== 'keyframed' ||
61
+ !canEditEasingForInterpolationFunction(effectPropStatus.interpolationFunction)) {
62
+ return null;
63
+ }
64
+ return {
65
+ type: 'effect',
66
+ fileName,
67
+ nodePath,
68
+ effectIndex: field.effectIndex,
69
+ fieldKey: field.fieldKey,
70
+ schema: effect.schema,
71
+ segmentIndex: selection.segmentIndex,
72
+ currentEasing: (_d = effectPropStatus.easing[selection.segmentIndex]) !== null && _d !== void 0 ? _d : 'linear',
73
+ };
74
+ };
75
+ const getEasingSelections = (selections) => selections.filter(isEasingSelection);
76
+ exports.getEasingSelections = getEasingSelections;
77
+ const getTimelineEasingValueForSelection = ({ selection, sequences, overrideIdsToNodePaths, propStatuses, }) => {
78
+ var _a;
79
+ var _b;
80
+ return ((_b = (_a = getSelectedEasingUpdate({
81
+ selection,
82
+ sequences,
83
+ overrideIdsToNodePaths,
84
+ propStatuses,
85
+ })) === null || _a === void 0 ? void 0 : _a.currentEasing) !== null && _b !== void 0 ? _b : null);
86
+ };
87
+ exports.getTimelineEasingValueForSelection = getTimelineEasingValueForSelection;
88
+ const updateSelectedTimelineEasings = ({ selections, sequences, overrideIdsToNodePaths, propStatuses, setPropStatuses, clientId, easing, }) => {
89
+ const easingSelections = (0, exports.getEasingSelections)(selections);
90
+ if (easingSelections.length === 0) {
91
+ return null;
92
+ }
93
+ const updates = easingSelections
94
+ .map((selection) => getSelectedEasingUpdate({
95
+ selection,
96
+ sequences,
97
+ overrideIdsToNodePaths,
98
+ propStatuses,
99
+ }))
100
+ .filter((update) => update !== null);
101
+ if (updates.length === 0) {
102
+ return null;
103
+ }
104
+ return Promise.all(updates.map((update) => {
105
+ const settings = {
106
+ type: 'easing',
107
+ segmentIndex: update.segmentIndex,
108
+ easing,
109
+ };
110
+ if (update.type === 'sequence') {
111
+ return (0, call_update_keyframe_settings_1.callUpdateSequenceKeyframeSettings)({
112
+ fileName: update.fileName,
113
+ nodePath: update.nodePath,
114
+ fieldKey: update.fieldKey,
115
+ settings,
116
+ schema: update.schema,
117
+ setPropStatuses,
118
+ clientId,
119
+ });
120
+ }
121
+ return (0, call_update_keyframe_settings_1.callUpdateEffectKeyframeSettings)({
122
+ fileName: update.fileName,
123
+ nodePath: update.nodePath,
124
+ effectIndex: update.effectIndex,
125
+ fieldKey: update.fieldKey,
126
+ settings,
127
+ schema: update.schema,
128
+ setPropStatuses,
129
+ clientId,
130
+ });
131
+ })).then(() => undefined);
132
+ };
133
+ exports.updateSelectedTimelineEasings = updateSelectedTimelineEasings;
@@ -4,6 +4,7 @@ import type { getTimelineKeyframes } from './get-timeline-keyframes';
4
4
  export type ExpandedTrackKeyframeRow = {
5
5
  readonly height: number;
6
6
  readonly keyframes: ReturnType<typeof getTimelineKeyframes>;
7
+ readonly canEditEasing: boolean;
7
8
  readonly nodePathInfo: SequenceNodePathInfo;
8
9
  readonly rowKey: string;
9
10
  };
@@ -7,6 +7,29 @@ const timeline_layout_1 = require("../../helpers/timeline-layout");
7
7
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
8
8
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
9
9
  const get_node_keyframes_1 = require("./get-node-keyframes");
10
+ const canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
11
+ interpolationFunction === 'interpolateColors';
12
+ const getNodeCanEditEasing = ({ node, nodePath, propStatuses, }) => {
13
+ var _a;
14
+ if (node.kind !== 'field' || node.field === null) {
15
+ return false;
16
+ }
17
+ if (node.field.kind === 'sequence-field') {
18
+ const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)) === null || _a === void 0 ? void 0 : _a[node.field.key];
19
+ return ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) === 'keyframed' &&
20
+ canEditEasingForInterpolationFunction(sequencePropStatus.interpolationFunction));
21
+ }
22
+ const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
23
+ propStatuses,
24
+ nodePath,
25
+ effectIndex: node.field.effectIndex,
26
+ });
27
+ const effectPropStatus = effectStatus.type === 'can-update-effect'
28
+ ? effectStatus.props[node.field.key]
29
+ : null;
30
+ return ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) === 'keyframed' &&
31
+ canEditEasingForInterpolationFunction(effectPropStatus.interpolationFunction));
32
+ };
10
33
  const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayOffset, }) => {
11
34
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
12
35
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
@@ -43,6 +66,11 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
43
66
  getEffectDragOverrides,
44
67
  timelinePosition,
45
68
  }),
69
+ canEditEasing: getNodeCanEditEasing({
70
+ node,
71
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
72
+ propStatuses,
73
+ }),
46
74
  rowKey: (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(node.nodePathInfo),
47
75
  nodePathInfo: node.nodePathInfo,
48
76
  })), [
@@ -121,21 +121,16 @@ const makeMovedKeyframedDragOverride = ({ group, delta, }) => {
121
121
  if (!first) {
122
122
  throw new Error('Expected a keyframe drag target');
123
123
  }
124
- const moves = new Map(getMovesForGroup({ group, delta }).map((move) => [move.fromFrame, move.toFrame]));
124
+ const movedStatus = (0, studio_shared_1.moveKeyframesInPropStatus)({
125
+ status: first.propStatus,
126
+ moves: getMovesForGroup({ group, delta }),
127
+ });
128
+ if (movedStatus.status !== 'keyframed') {
129
+ throw new Error('Expected keyframed status');
130
+ }
125
131
  return {
126
132
  type: 'keyframed',
127
- status: {
128
- ...first.propStatus,
129
- keyframes: first.propStatus.keyframes
130
- .map((keyframe) => {
131
- var _a;
132
- return ({
133
- ...keyframe,
134
- frame: (_a = moves.get(keyframe.frame)) !== null && _a !== void 0 ? _a : keyframe.frame,
135
- });
136
- })
137
- .sort((a, b) => a.frame - b.frame),
138
- },
133
+ status: movedStatus,
139
134
  };
140
135
  };
141
136
  const applyDragOverrides = ({ delta, setDragOverrides, setEffectDragOverrides, targets, }) => {
@@ -0,0 +1 @@
1
+ export declare const CANVAS_CAPTURE_ENABLED = false;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CANVAS_CAPTURE_ENABLED = void 0;
4
+ exports.CANVAS_CAPTURE_ENABLED = false;
@@ -0,0 +1,11 @@
1
+ import { type EffectDragData } from '@remotion/studio-shared';
2
+ import type { SequencePropsSubscriptionKey } from 'remotion';
3
+ export declare const hasEffectDragType: (dataTransfer: DataTransfer) => boolean;
4
+ export declare const hasExplicitEffectDragType: (dataTransfer: DataTransfer) => boolean;
5
+ export declare const getEffectDragData: (dataTransfer: DataTransfer) => EffectDragData | null;
6
+ export declare const addEffectFromDragData: ({ clientId, dragData, fileName, nodePath, }: {
7
+ readonly clientId: string;
8
+ readonly dragData: EffectDragData;
9
+ readonly fileName: string;
10
+ readonly nodePath: SequencePropsSubscriptionKey;
11
+ }) => Promise<void>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addEffectFromDragData = exports.getEffectDragData = exports.hasExplicitEffectDragType = exports.hasEffectDragType = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
5
+ const install_required_package_1 = require("../helpers/install-required-package");
6
+ const call_api_1 = require("./call-api");
7
+ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
8
+ const hasEffectDragType = (dataTransfer) => {
9
+ const types = Array.from(dataTransfer.types);
10
+ const hasExplicitEffectType = types.includes(studio_shared_1.EFFECT_DRAG_MIME_TYPE);
11
+ if (!hasExplicitEffectType && hasImportableAssetDragType(dataTransfer)) {
12
+ return false;
13
+ }
14
+ return types.some((type) => type === studio_shared_1.EFFECT_DRAG_MIME_TYPE || isGenericDragType(type));
15
+ };
16
+ exports.hasEffectDragType = hasEffectDragType;
17
+ const hasExplicitEffectDragType = (dataTransfer) => {
18
+ return Array.from(dataTransfer.types).includes(studio_shared_1.EFFECT_DRAG_MIME_TYPE);
19
+ };
20
+ exports.hasExplicitEffectDragType = hasExplicitEffectDragType;
21
+ const isGenericDragType = (type) => {
22
+ return type === 'application/json' || type === 'text/plain';
23
+ };
24
+ const hasImportableAssetDragType = (dataTransfer) => {
25
+ return Array.from(dataTransfer.types).some((type) => type === 'Files' ||
26
+ type === studio_shared_1.ASSET_DRAG_MIME_TYPE ||
27
+ type === studio_shared_1.COMPONENT_DRAG_MIME_TYPE ||
28
+ type === studio_shared_1.SFX_DRAG_MIME_TYPE ||
29
+ type === 'text/uri-list' ||
30
+ type === 'text/html');
31
+ };
32
+ const getEffectDragData = (dataTransfer) => {
33
+ for (const type of [
34
+ studio_shared_1.EFFECT_DRAG_MIME_TYPE,
35
+ 'application/json',
36
+ 'text/plain',
37
+ ]) {
38
+ const value = dataTransfer.getData(type);
39
+ if (!value) {
40
+ continue;
41
+ }
42
+ const parsed = (0, studio_shared_1.parseEffectDragData)(value);
43
+ if (parsed) {
44
+ return parsed;
45
+ }
46
+ }
47
+ return null;
48
+ };
49
+ exports.getEffectDragData = getEffectDragData;
50
+ const addEffectFromDragData = async ({ clientId, dragData, fileName, nodePath, }) => {
51
+ try {
52
+ const requiredPackage = (0, studio_shared_1.getRequiredPackageForEffectImportPath)(dragData.effect.importPath);
53
+ await (0, install_required_package_1.installRequiredPackages)(requiredPackage ? [requiredPackage] : []);
54
+ const result = await (0, call_api_1.callApi)('/api/add-effect', {
55
+ fileName,
56
+ sequenceNodePath: nodePath,
57
+ effectName: dragData.effect.name,
58
+ effectImportPath: dragData.effect.importPath,
59
+ effectConfig: dragData.effect.config,
60
+ clientId,
61
+ });
62
+ if (result.success) {
63
+ (0, NotificationCenter_1.showNotification)(`Added ${dragData.effect.name}()`, 2000);
64
+ }
65
+ else {
66
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
67
+ }
68
+ }
69
+ catch (err) {
70
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
71
+ }
72
+ };
73
+ exports.addEffectFromDragData = addEffectFromDragData;
@@ -0,0 +1,20 @@
1
+ export type OutlinePoint = {
2
+ readonly x: number;
3
+ readonly y: number;
4
+ };
5
+ export type SelectedOutline = {
6
+ readonly key: string;
7
+ readonly dimensions: {
8
+ readonly width: number;
9
+ readonly height: number;
10
+ } | null;
11
+ readonly points: readonly [
12
+ OutlinePoint,
13
+ OutlinePoint,
14
+ OutlinePoint,
15
+ OutlinePoint
16
+ ];
17
+ };
18
+ export declare const clamp: (value: number, min: number, max: number) => number;
19
+ export declare const mix: (from: number, to: number, progress: number) => number;
20
+ export declare const mixPoint: (from: OutlinePoint, to: OutlinePoint, progress: number) => OutlinePoint;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mixPoint = exports.mix = exports.clamp = void 0;
4
+ const clamp = (value, min, max) => {
5
+ return Math.min(max, Math.max(min, value));
6
+ };
7
+ exports.clamp = clamp;
8
+ const mix = (from, to, progress) => {
9
+ return from + (to - from) * progress;
10
+ };
11
+ exports.mix = mix;
12
+ const mixPoint = (from, to, progress) => {
13
+ return {
14
+ x: (0, exports.mix)(from.x, to.x, progress),
15
+ y: (0, exports.mix)(from.y, to.y, progress),
16
+ };
17
+ };
18
+ exports.mixPoint = mixPoint;
@@ -0,0 +1,46 @@
1
+ import type { CanUpdateSequencePropStatusKeyframed, CanUpdateSequencePropStatusStatic, GetEffectDragOverrides, PropStatuses, SequenceFieldSchema, SequencePropsSubscriptionKey, SequenceSchema, TSequence } from 'remotion';
2
+ import { type OutlinePoint } from './selected-outline-geometry';
3
+ export type UvCoordinate = readonly [number, number];
4
+ export type UvCoordinateFieldSchema = Extract<SequenceFieldSchema, {
5
+ type: 'uv-coordinate';
6
+ }>;
7
+ export type SelectedOutlineUvHandle = {
8
+ readonly clientId: string;
9
+ readonly propStatus: CanUpdateSequencePropStatusStatic | CanUpdateSequencePropStatusKeyframed;
10
+ readonly effectIndex: number;
11
+ readonly fieldDefault: UvCoordinate | undefined;
12
+ readonly fieldKey: string;
13
+ readonly fieldSchema: UvCoordinateFieldSchema;
14
+ readonly nodePath: SequencePropsSubscriptionKey;
15
+ readonly schema: SequenceSchema;
16
+ readonly sourceFrame: number;
17
+ readonly value: UvCoordinate;
18
+ };
19
+ type UvConnectionHandle = Pick<SelectedOutlineUvHandle, 'effectIndex' | 'fieldKey' | 'fieldSchema' | 'value'>;
20
+ type UvHandleConnectionLine = {
21
+ readonly key: string;
22
+ readonly from: OutlinePoint;
23
+ readonly to: OutlinePoint;
24
+ };
25
+ type SelectedEffectFields = {
26
+ readonly allFields: boolean;
27
+ readonly fieldKeys: ReadonlySet<string>;
28
+ };
29
+ export declare const tuplesEqual: (left: unknown, right: UvCoordinate) => boolean;
30
+ export declare const getUvHandlePosition: (points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint], uv: UvCoordinate) => OutlinePoint;
31
+ export declare const getUvHandleConnectionLines: ({ handles, points, }: {
32
+ readonly handles: readonly UvConnectionHandle[];
33
+ readonly points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint];
34
+ }) => UvHandleConnectionLine[];
35
+ export declare const getUvCoordinateForPoint: (points: readonly [OutlinePoint, OutlinePoint, OutlinePoint, OutlinePoint], point: OutlinePoint) => UvCoordinate;
36
+ export declare function constrainUv(value: UvCoordinate, schema: UvCoordinateFieldSchema): UvCoordinate;
37
+ export declare const getSelectedUvHandles: ({ propStatuses, clientId, getEffectDragOverrides, nodePath, selectedEffects, sequence, sourceFrame, }: {
38
+ readonly propStatuses: PropStatuses;
39
+ readonly clientId: string | null;
40
+ readonly getEffectDragOverrides: GetEffectDragOverrides;
41
+ readonly nodePath: SequencePropsSubscriptionKey;
42
+ readonly selectedEffects: Map<number, SelectedEffectFields> | undefined;
43
+ readonly sequence: TSequence;
44
+ readonly sourceFrame: number;
45
+ }) => SelectedOutlineUvHandle[];
46
+ export {};