@hyperframes/studio 0.6.36 → 0.6.38
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.
- package/dist/assets/{index-CMBmEncK.js → index-C55KfVpx.js} +40 -40
- package/dist/index.html +1 -1
- package/package.json +4 -4
- package/src/components/editor/manualEditsDom.ts +38 -359
- package/src/components/editor/manualEditsDomPatches.ts +237 -0
- package/src/player/components/PlayerControls.tsx +356 -721
- package/src/player/components/ShortcutsPanel.tsx +277 -0
- package/src/player/components/SpeedMenu.tsx +83 -0
- package/src/player/components/useSeekBarDrag.ts +168 -0
- package/src/utils/timelineAssetDrop.test.ts +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { PatchOperation } from "../../utils/sourcePatcher";
|
|
2
|
+
import {
|
|
3
|
+
STUDIO_OFFSET_X_PROP,
|
|
4
|
+
STUDIO_OFFSET_Y_PROP,
|
|
5
|
+
STUDIO_WIDTH_PROP,
|
|
6
|
+
STUDIO_HEIGHT_PROP,
|
|
7
|
+
STUDIO_ROTATION_PROP,
|
|
8
|
+
STUDIO_PATH_OFFSET_ATTR,
|
|
9
|
+
STUDIO_BOX_SIZE_ATTR,
|
|
10
|
+
STUDIO_ROTATION_ATTR,
|
|
11
|
+
STUDIO_ROTATION_DRAFT_ATTR,
|
|
12
|
+
STUDIO_ORIGINAL_TRANSLATE_ATTR,
|
|
13
|
+
STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR,
|
|
14
|
+
STUDIO_ORIGINAL_WIDTH_ATTR,
|
|
15
|
+
STUDIO_ORIGINAL_HEIGHT_ATTR,
|
|
16
|
+
STUDIO_ORIGINAL_MIN_WIDTH_ATTR,
|
|
17
|
+
STUDIO_ORIGINAL_MIN_HEIGHT_ATTR,
|
|
18
|
+
STUDIO_ORIGINAL_MAX_WIDTH_ATTR,
|
|
19
|
+
STUDIO_ORIGINAL_MAX_HEIGHT_ATTR,
|
|
20
|
+
STUDIO_ORIGINAL_FLEX_BASIS_ATTR,
|
|
21
|
+
STUDIO_ORIGINAL_FLEX_GROW_ATTR,
|
|
22
|
+
STUDIO_ORIGINAL_FLEX_SHRINK_ATTR,
|
|
23
|
+
STUDIO_ORIGINAL_BOX_SIZING_ATTR,
|
|
24
|
+
STUDIO_ORIGINAL_SCALE_ATTR,
|
|
25
|
+
STUDIO_ORIGINAL_TRANSFORM_ORIGIN_ATTR,
|
|
26
|
+
STUDIO_ORIGINAL_DISPLAY_ATTR,
|
|
27
|
+
STUDIO_ORIGINAL_ROTATE_ATTR,
|
|
28
|
+
STUDIO_ORIGINAL_INLINE_ROTATE_ATTR,
|
|
29
|
+
STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR,
|
|
30
|
+
STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR,
|
|
31
|
+
} from "./manualEditsTypes";
|
|
32
|
+
import {
|
|
33
|
+
STUDIO_MOTION_ATTR,
|
|
34
|
+
STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR,
|
|
35
|
+
STUDIO_MOTION_ORIGINAL_OPACITY_ATTR,
|
|
36
|
+
STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR,
|
|
37
|
+
} from "./studioMotionTypes";
|
|
38
|
+
|
|
39
|
+
/* ── Shared helpers ──────────────────────────────────────────────── */
|
|
40
|
+
|
|
41
|
+
function collectInlineStyleOps(
|
|
42
|
+
element: HTMLElement,
|
|
43
|
+
properties: readonly string[],
|
|
44
|
+
ops: PatchOperation[],
|
|
45
|
+
): void {
|
|
46
|
+
for (const prop of properties) {
|
|
47
|
+
const val = element.style.getPropertyValue(prop);
|
|
48
|
+
if (val) ops.push({ type: "inline-style", property: prop, value: val });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function collectAttributeOps(
|
|
53
|
+
element: HTMLElement,
|
|
54
|
+
attrNames: readonly string[],
|
|
55
|
+
ops: PatchOperation[],
|
|
56
|
+
): void {
|
|
57
|
+
for (const attr of attrNames) {
|
|
58
|
+
const val = element.getAttribute(attr);
|
|
59
|
+
if (val !== null) ops.push({ type: "attribute", property: attr, value: val });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function appendTransformDisplayOps(element: HTMLElement, ops: PatchOperation[]): void {
|
|
64
|
+
const val = element.getAttribute(STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR);
|
|
65
|
+
if (val !== null) {
|
|
66
|
+
ops.push({ type: "inline-style", property: "display", value: val || null });
|
|
67
|
+
ops.push({ type: "attribute", property: STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, value: null });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ── Path offset patches ─────────────────────────────────────────── */
|
|
72
|
+
|
|
73
|
+
export function buildPathOffsetPatches(element: HTMLElement): PatchOperation[] {
|
|
74
|
+
const ops: PatchOperation[] = [];
|
|
75
|
+
collectInlineStyleOps(element, [STUDIO_OFFSET_X_PROP, STUDIO_OFFSET_Y_PROP, "translate"], ops);
|
|
76
|
+
ops.push({ type: "attribute", property: STUDIO_PATH_OFFSET_ATTR, value: "true" });
|
|
77
|
+
collectAttributeOps(
|
|
78
|
+
element,
|
|
79
|
+
[STUDIO_ORIGINAL_TRANSLATE_ATTR, STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR],
|
|
80
|
+
ops,
|
|
81
|
+
);
|
|
82
|
+
collectInlineStyleOps(element, ["display"], ops);
|
|
83
|
+
collectAttributeOps(element, [STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR], ops);
|
|
84
|
+
return ops;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function buildClearPathOffsetPatches(element: HTMLElement): PatchOperation[] {
|
|
88
|
+
const originalInlineTranslate = element.getAttribute(STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR);
|
|
89
|
+
const ops: PatchOperation[] = [
|
|
90
|
+
{ type: "inline-style", property: STUDIO_OFFSET_X_PROP, value: null },
|
|
91
|
+
{ type: "inline-style", property: STUDIO_OFFSET_Y_PROP, value: null },
|
|
92
|
+
{ type: "inline-style", property: "translate", value: originalInlineTranslate || null },
|
|
93
|
+
{ type: "attribute", property: STUDIO_PATH_OFFSET_ATTR, value: null },
|
|
94
|
+
{ type: "attribute", property: STUDIO_ORIGINAL_TRANSLATE_ATTR, value: null },
|
|
95
|
+
{ type: "attribute", property: STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR, value: null },
|
|
96
|
+
];
|
|
97
|
+
appendTransformDisplayOps(element, ops);
|
|
98
|
+
return ops;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* ── Box size patches ────────────────────────────────────────────── */
|
|
102
|
+
|
|
103
|
+
const BOX_SIZE_STYLE_PROPS = [
|
|
104
|
+
"width",
|
|
105
|
+
"height",
|
|
106
|
+
"min-width",
|
|
107
|
+
"min-height",
|
|
108
|
+
"max-width",
|
|
109
|
+
"max-height",
|
|
110
|
+
"flex-basis",
|
|
111
|
+
"flex-grow",
|
|
112
|
+
"flex-shrink",
|
|
113
|
+
"box-sizing",
|
|
114
|
+
"scale",
|
|
115
|
+
"transform-origin",
|
|
116
|
+
"display",
|
|
117
|
+
] as const;
|
|
118
|
+
|
|
119
|
+
const BOX_SIZE_ORIG_ATTRS: ReadonlyArray<[string, string]> = [
|
|
120
|
+
[STUDIO_ORIGINAL_WIDTH_ATTR, "width"],
|
|
121
|
+
[STUDIO_ORIGINAL_HEIGHT_ATTR, "height"],
|
|
122
|
+
[STUDIO_ORIGINAL_MIN_WIDTH_ATTR, "min-width"],
|
|
123
|
+
[STUDIO_ORIGINAL_MIN_HEIGHT_ATTR, "min-height"],
|
|
124
|
+
[STUDIO_ORIGINAL_MAX_WIDTH_ATTR, "max-width"],
|
|
125
|
+
[STUDIO_ORIGINAL_MAX_HEIGHT_ATTR, "max-height"],
|
|
126
|
+
[STUDIO_ORIGINAL_FLEX_BASIS_ATTR, "flex-basis"],
|
|
127
|
+
[STUDIO_ORIGINAL_FLEX_GROW_ATTR, "flex-grow"],
|
|
128
|
+
[STUDIO_ORIGINAL_FLEX_SHRINK_ATTR, "flex-shrink"],
|
|
129
|
+
[STUDIO_ORIGINAL_BOX_SIZING_ATTR, "box-sizing"],
|
|
130
|
+
[STUDIO_ORIGINAL_SCALE_ATTR, "scale"],
|
|
131
|
+
[STUDIO_ORIGINAL_TRANSFORM_ORIGIN_ATTR, "transform-origin"],
|
|
132
|
+
[STUDIO_ORIGINAL_DISPLAY_ATTR, "display"],
|
|
133
|
+
[STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, ""],
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
export function buildBoxSizePatches(element: HTMLElement): PatchOperation[] {
|
|
137
|
+
const ops: PatchOperation[] = [];
|
|
138
|
+
collectInlineStyleOps(element, [STUDIO_WIDTH_PROP, STUDIO_HEIGHT_PROP], ops);
|
|
139
|
+
collectInlineStyleOps(element, BOX_SIZE_STYLE_PROPS, ops);
|
|
140
|
+
ops.push({ type: "attribute", property: STUDIO_BOX_SIZE_ATTR, value: "true" });
|
|
141
|
+
collectAttributeOps(
|
|
142
|
+
element,
|
|
143
|
+
BOX_SIZE_ORIG_ATTRS.map(([attr]) => attr),
|
|
144
|
+
ops,
|
|
145
|
+
);
|
|
146
|
+
return ops;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function buildClearBoxSizePatches(element: HTMLElement): PatchOperation[] {
|
|
150
|
+
const ops: PatchOperation[] = [
|
|
151
|
+
{ type: "inline-style", property: STUDIO_WIDTH_PROP, value: null },
|
|
152
|
+
{ type: "inline-style", property: STUDIO_HEIGHT_PROP, value: null },
|
|
153
|
+
{ type: "attribute", property: STUDIO_BOX_SIZE_ATTR, value: null },
|
|
154
|
+
];
|
|
155
|
+
for (const [attrName, styleProp] of BOX_SIZE_ORIG_ATTRS) {
|
|
156
|
+
const origVal = element.getAttribute(attrName);
|
|
157
|
+
if (origVal !== null && styleProp) {
|
|
158
|
+
ops.push({ type: "inline-style", property: styleProp, value: origVal || null });
|
|
159
|
+
}
|
|
160
|
+
ops.push({ type: "attribute", property: attrName, value: null });
|
|
161
|
+
}
|
|
162
|
+
return ops;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* ── Rotation patches ────────────────────────────────────────────── */
|
|
166
|
+
|
|
167
|
+
const ROTATION_STYLE_PROPS = [
|
|
168
|
+
STUDIO_ROTATION_PROP,
|
|
169
|
+
"rotate",
|
|
170
|
+
"transform-origin",
|
|
171
|
+
"display",
|
|
172
|
+
] as const;
|
|
173
|
+
|
|
174
|
+
const ROTATION_ORIG_ATTRS = [
|
|
175
|
+
STUDIO_ORIGINAL_ROTATE_ATTR,
|
|
176
|
+
STUDIO_ORIGINAL_INLINE_ROTATE_ATTR,
|
|
177
|
+
STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR,
|
|
178
|
+
STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR,
|
|
179
|
+
] as const;
|
|
180
|
+
|
|
181
|
+
export function buildRotationPatches(element: HTMLElement): PatchOperation[] {
|
|
182
|
+
const ops: PatchOperation[] = [];
|
|
183
|
+
collectInlineStyleOps(element, ROTATION_STYLE_PROPS, ops);
|
|
184
|
+
ops.push({ type: "attribute", property: STUDIO_ROTATION_ATTR, value: "true" });
|
|
185
|
+
collectAttributeOps(element, ROTATION_ORIG_ATTRS, ops);
|
|
186
|
+
return ops;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function buildClearRotationPatches(element: HTMLElement): PatchOperation[] {
|
|
190
|
+
const origInlineRotate = element.getAttribute(STUDIO_ORIGINAL_INLINE_ROTATE_ATTR);
|
|
191
|
+
const origRotationTransformOrigin = element.getAttribute(
|
|
192
|
+
STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR,
|
|
193
|
+
);
|
|
194
|
+
const ops: PatchOperation[] = [
|
|
195
|
+
{ type: "inline-style", property: STUDIO_ROTATION_PROP, value: null },
|
|
196
|
+
{ type: "inline-style", property: "rotate", value: origInlineRotate || null },
|
|
197
|
+
{
|
|
198
|
+
type: "inline-style",
|
|
199
|
+
property: "transform-origin",
|
|
200
|
+
value: origRotationTransformOrigin !== null ? origRotationTransformOrigin || null : null,
|
|
201
|
+
},
|
|
202
|
+
{ type: "attribute", property: STUDIO_ROTATION_ATTR, value: null },
|
|
203
|
+
{ type: "attribute", property: STUDIO_ROTATION_DRAFT_ATTR, value: null },
|
|
204
|
+
{ type: "attribute", property: STUDIO_ORIGINAL_ROTATE_ATTR, value: null },
|
|
205
|
+
{ type: "attribute", property: STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, value: null },
|
|
206
|
+
{ type: "attribute", property: STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR, value: null },
|
|
207
|
+
];
|
|
208
|
+
appendTransformDisplayOps(element, ops);
|
|
209
|
+
return ops;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* ── Motion patches ──────────────────────────────────────────────── */
|
|
213
|
+
|
|
214
|
+
const MOTION_ORIG_ATTRS = [
|
|
215
|
+
STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR,
|
|
216
|
+
STUDIO_MOTION_ORIGINAL_OPACITY_ATTR,
|
|
217
|
+
STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR,
|
|
218
|
+
] as const;
|
|
219
|
+
|
|
220
|
+
export function buildMotionPatches(element: HTMLElement): PatchOperation[] {
|
|
221
|
+
const motionJson = element.getAttribute(STUDIO_MOTION_ATTR);
|
|
222
|
+
if (!motionJson) return [];
|
|
223
|
+
const ops: PatchOperation[] = [
|
|
224
|
+
{ type: "attribute", property: STUDIO_MOTION_ATTR, value: motionJson },
|
|
225
|
+
];
|
|
226
|
+
collectAttributeOps(element, MOTION_ORIG_ATTRS, ops);
|
|
227
|
+
return ops;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function buildClearMotionPatches(_element: HTMLElement): PatchOperation[] {
|
|
231
|
+
return [
|
|
232
|
+
{ type: "attribute", property: STUDIO_MOTION_ATTR, value: null },
|
|
233
|
+
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_TRANSFORM_ATTR, value: null },
|
|
234
|
+
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_OPACITY_ATTR, value: null },
|
|
235
|
+
{ type: "attribute", property: STUDIO_MOTION_ORIGINAL_VISIBILITY_ATTR, value: null },
|
|
236
|
+
];
|
|
237
|
+
}
|