@hyperframes/studio 0.8.138 → 0.8.140
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/{hyperframes-player-B30apksz.js → hyperframes-player-BLuyxnK7.js} +1 -1
- package/dist/assets/{index-DXVvWfQG.js → index-CWfuDCoA.js} +1 -1
- package/dist/assets/{index-DIJuIBwI.js → index-Dr3Bo9uH.js} +1 -1
- package/dist/assets/{index-BdjA0CLD.js → index-VAHDM_zL.js} +210 -210
- package/dist/{chunk-4S3AYCOG.js → chunk-H2DUOXTF.js} +3 -2
- package/dist/{chunk-TDWGXBUT.js → chunk-TFLU2MGI.js} +1 -6
- package/dist/chunk-TFLU2MGI.js.map +1 -0
- package/dist/{chunk-7UQWVN52.js → chunk-UYWON5AX.js} +2 -2
- package/dist/{domEditingLayers-IEVLO54Z.js → domEditingLayers-KBTPQKGA.js} +3 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.html +1 -1
- package/dist/index.js +7327 -6265
- package/dist/index.js.map +1 -1
- package/dist/player.js +2 -2
- package/package.json +8 -8
- package/src/App.tsx +9 -4
- package/src/components/TimelineToolbar.test.tsx +79 -1
- package/src/components/TimelineToolbar.tsx +14 -29
- package/src/components/editor/DomEditOverlay.tsx +11 -7
- package/src/components/editor/PropertyPanel.test.tsx +600 -748
- package/src/components/editor/PropertyPanel.tsx +1 -0
- package/src/components/editor/PropertyPanelFlat.tsx +1 -0
- package/src/components/editor/anchoredResizeCommitFeedsOffset.test.ts +2 -0
- package/src/components/editor/domEditOverlayGeometry.ts +7 -7
- package/src/components/editor/domEditOverlayGestures.ts +18 -0
- package/src/components/editor/domEditOverlayStartGesture.blocked.test.ts +1 -0
- package/src/components/editor/domEditOverlayStartGesture.test.ts +3 -0
- package/src/components/editor/domEditOverlayStartGesture.ts +9 -1
- package/src/components/editor/dragUndoPaint.test.ts +2 -0
- package/src/components/editor/gestureHoldsPreviewReload.test.tsx +432 -15
- package/src/components/editor/groupDropKeepsSelection.test.ts +1 -0
- package/src/components/editor/manualEdits.ts +1 -1
- package/src/components/editor/manualEditsDom.ts +7 -7
- package/src/components/editor/manualEditsParsing.ts +14 -2
- package/src/components/editor/manualEditsTypes.ts +5 -0
- package/src/components/editor/manualOffsetDrag.test.ts +23 -0
- package/src/components/editor/manualOffsetDrag.ts +5 -0
- package/src/components/editor/previewGestureStarts.ts +284 -0
- package/src/components/editor/previewReadOnly.overlay.test.tsx +3 -2
- package/src/components/editor/propertyPanelFill.tsx +36 -13
- package/src/components/editor/propertyPanelFlatStyleSections.test.tsx +4 -0
- package/src/components/editor/propertyPanelFlatStyleSections.tsx +13 -7
- package/src/components/editor/propertyPanelImageFill.test.tsx +164 -0
- package/src/components/editor/propertyPanelStyleSections.tsx +10 -7
- package/src/components/editor/rotateInlineSave.test.ts +1 -0
- package/src/components/editor/shiftDragAxisLock.test.tsx +1 -0
- package/src/components/editor/useDomEditOverlayGestures.ts +67 -71
- package/src/components/nle/NLEContext.test.ts +26 -0
- package/src/components/nle/NLEContext.tsx +8 -3
- package/src/components/nle/NLEPreview.test.ts +44 -1
- package/src/components/nle/NLEPreview.tsx +7 -2
- package/src/hooks/draggedGsapPosition.ts +8 -0
- package/src/hooks/editMoment.ts +13 -0
- package/src/hooks/externalFileChangeOwnership.test.ts +25 -4
- package/src/hooks/gsapDragCommit.ts +2 -1
- package/src/hooks/gsapDragPositionCommit.ts +19 -7
- package/src/hooks/gsapPositionDetection.ts +5 -3
- package/src/hooks/gsapResizeIntercept.ts +11 -4
- package/src/hooks/gsapRuntimeBridge.ts +31 -11
- package/src/hooks/gsapValueAtPlayhead.browser.test.ts +3 -22
- package/src/hooks/gsapValueAtPlayhead.test.ts +15 -0
- package/src/hooks/gsapValueAtPlayhead.ts +12 -5
- package/src/hooks/timelineEditingHelpers.test.ts +22 -0
- package/src/hooks/timelineEditingHelpers.ts +18 -2
- package/src/hooks/useDomSelection.test.ts +21 -2
- package/src/hooks/useEditHistoryActions.test.tsx +20 -0
- package/src/hooks/useEditHistoryActions.ts +2 -0
- package/src/hooks/useExternalFileChangeCoordinator.test.tsx +536 -10
- package/src/hooks/useExternalFileChangeCoordinator.ts +72 -45
- package/src/hooks/useGsapAwareEditing.test.tsx +38 -0
- package/src/hooks/useGsapAwareEditing.ts +148 -136
- package/src/hooks/useGsapAwareGroupMove.ts +126 -113
- package/src/hooks/useGsapScriptCommits.ts +5 -4
- package/src/hooks/useMusicBeatAnalysis.ts +2 -1
- package/src/hooks/usePreviewPersistence.history.test.tsx +7 -2
- package/src/hooks/usePreviewPersistence.ts +1 -4
- package/src/hooks/useSdkSession.lifecycle.test.tsx +20 -0
- package/src/hooks/useSdkSession.ts +4 -1
- package/src/hooks/useThumbnailStripSize.test.tsx +65 -0
- package/src/hooks/useThumbnailStripSize.ts +23 -1
- package/src/hooks/useTimelineDeleteOps.test.tsx +10 -0
- package/src/hooks/useTimelineDeleteOps.ts +9 -10
- package/src/index.ts +2 -0
- package/src/player/components/AudioWaveform.test.tsx +153 -1
- package/src/player/components/AudioWaveform.tsx +93 -37
- package/src/player/components/Timeline.scrollRest.test.tsx +22 -0
- package/src/player/components/Timeline.test.ts +3 -1
- package/src/player/components/TimelineCanvas.tsx +4 -0
- package/src/player/components/TimelineClip.tsx +20 -6
- package/src/player/components/TimelineClipFades.test.tsx +11 -0
- package/src/player/components/TimelineClipFades.tsx +4 -4
- package/src/player/components/TimelineClipJoins.tsx +23 -18
- package/src/player/components/TimelineGestureOverlay.tsx +30 -27
- package/src/player/components/TimelineGroupRow.tsx +1 -0
- package/src/player/components/TimelineLaneClip.tsx +127 -0
- package/src/player/components/TimelineLanes.test.tsx +51 -6
- package/src/player/components/TimelineLanes.tsx +166 -178
- package/src/player/components/TimelineRuler.tsx +2 -0
- package/src/player/components/TimelineTimeLayer.tsx +25 -0
- package/src/player/components/VideoThumbnail.test.tsx +204 -12
- package/src/player/components/VideoThumbnail.tsx +37 -9
- package/src/player/components/thumbnailUtils.test.ts +17 -3
- package/src/player/components/thumbnailUtils.ts +17 -1
- package/src/player/components/timelineLayout.test.ts +3 -3
- package/src/player/components/timelineMotion.test.ts +27 -0
- package/src/player/components/timelineMotion.ts +62 -0
- package/src/player/components/timelineZoomInput.test.ts +438 -0
- package/src/player/components/timelineZoomInput.ts +456 -0
- package/src/player/components/useTimelineGeometry.ts +0 -3
- package/src/player/components/useTimelinePlayhead.test.tsx +97 -30
- package/src/player/components/useTimelinePlayhead.ts +53 -59
- package/src/player/components/useTimelineProviderState.tsx +16 -21
- package/src/player/components/useTimelineZoom.ts +7 -12
- package/src/player/hooks/useShadowPreviewReload.ts +6 -6
- package/src/player/hooks/useTimelinePlayer.shadowReload.test.ts +14 -0
- package/src/player/hooks/useTimelinePlayer.ts +8 -5
- package/src/player/lib/thumbnailScheduler.test.ts +20 -1
- package/src/player/lib/thumbnailScheduler.ts +1 -1
- package/src/player/lib/thumbnailVideoDecoder.test.ts +230 -30
- package/src/player/lib/thumbnailVideoDecoder.ts +197 -54
- package/src/player/lib/timelineElementHelpers.ts +0 -11
- package/src/player/lib/timelineViewportBudgets.test.ts +1 -1
- package/src/player/lib/timelineViewportBudgets.ts +1 -1
- package/src/player/previewReloading.test.ts +48 -0
- package/src/player/previewReloading.ts +48 -0
- package/src/utils/gsapUndoRestore.browser.test.ts +4 -17
- package/src/utils/rootDuration.ts +5 -4
- package/src/utils/studioPendingEdits.test.ts +27 -0
- package/src/utils/studioPendingEdits.ts +9 -0
- package/src/utils/timelineAssetDrop.test.ts +13 -4
- package/src/utils/timelineAssetDrop.ts +6 -2
- package/dist/chunk-TDWGXBUT.js.map +0 -1
- /package/dist/{chunk-4S3AYCOG.js.map → chunk-H2DUOXTF.js.map} +0 -0
- /package/dist/{chunk-7UQWVN52.js.map → chunk-UYWON5AX.js.map} +0 -0
- /package/dist/{domEditingLayers-IEVLO54Z.js.map → domEditingLayers-KBTPQKGA.js.map} +0 -0
|
@@ -565,6 +565,7 @@ export const PropertyPanel = memo(function PropertyPanel(props: PropertyPanelPro
|
|
|
565
565
|
styles={styles}
|
|
566
566
|
assets={assets}
|
|
567
567
|
onSetStyle={onSetStyle}
|
|
568
|
+
onSetHtmlAttribute={props.onSetHtmlAttribute}
|
|
568
569
|
onImportAssets={onImportAssets}
|
|
569
570
|
gsapBorderRadius={gsapBorderRadius}
|
|
570
571
|
/>
|
|
@@ -351,6 +351,7 @@ export function PropertyPanelFlat({
|
|
|
351
351
|
styles={styles}
|
|
352
352
|
assets={assets}
|
|
353
353
|
onSetStyle={onSetStyle}
|
|
354
|
+
onSetHtmlAttribute={forwardedProps.onSetHtmlAttribute}
|
|
354
355
|
onPreviewStyle={onPreviewStyle}
|
|
355
356
|
onImportAssets={onImportAssets}
|
|
356
357
|
gsapBorderRadius={gsapBorderRadius}
|
|
@@ -142,6 +142,7 @@ function buildHarness(
|
|
|
142
142
|
const iframe = document.createElement("iframe");
|
|
143
143
|
|
|
144
144
|
const opts: UseDomEditOverlayGesturesOptions = {
|
|
145
|
+
activeCompositionPathRef: { current: null },
|
|
145
146
|
overlayRef: ref<HTMLDivElement | null>(overlayEl),
|
|
146
147
|
iframeRef: ref<HTMLIFrameElement | null>(iframe),
|
|
147
148
|
boxRef: ref<HTMLDivElement | null>(document.createElement("div")),
|
|
@@ -159,6 +160,7 @@ function buildHarness(
|
|
|
159
160
|
gestureRef: ref<GestureState | null>(null),
|
|
160
161
|
groupGestureRef: ref(null),
|
|
161
162
|
blockedMoveRef: ref(null),
|
|
163
|
+
waitingPressRef: ref(null),
|
|
162
164
|
rafPausedRef: ref(false),
|
|
163
165
|
suppressNextBoxClickRef: ref(false),
|
|
164
166
|
setOverlayRect: () => {},
|
|
@@ -18,16 +18,16 @@ export interface OverlayRect {
|
|
|
18
18
|
height: number;
|
|
19
19
|
editScaleX: number;
|
|
20
20
|
editScaleY: number;
|
|
21
|
-
/**
|
|
22
|
-
* The element's live transform rotation in DEGREES (screen/CSS convention, CW
|
|
23
|
-
* positive), decomposed from its computed transform matrix. Present so the
|
|
24
|
-
* selection chrome can render as an oriented bounding box (OBB) that co-rotates
|
|
25
|
-
* with the element. Omitted (treated as 0) for group/union rects and when the
|
|
26
|
-
* transform is unmeasurable — those render axis-aligned exactly as before.
|
|
27
|
-
*/
|
|
21
|
+
/** Live screen-space rotation; omitted for axis-aligned group bounds. */
|
|
28
22
|
angle?: number;
|
|
29
23
|
}
|
|
30
24
|
|
|
25
|
+
export const shiftedOverlayRect = (rect: OverlayRect, dx: number, dy: number): OverlayRect => ({
|
|
26
|
+
...rect,
|
|
27
|
+
left: rect.left + dx,
|
|
28
|
+
top: rect.top + dy,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
31
|
export interface GroupOverlayItem {
|
|
32
32
|
key: string;
|
|
33
33
|
selection: DomEditSelection;
|
|
@@ -121,6 +121,22 @@ export interface BlockedMoveState {
|
|
|
121
121
|
startY: number;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/** Marks the selection box while its press waits for a reload: it is drawn at the pointer, not at the element. */
|
|
125
|
+
export const PRESS_WAITING_ATTR = "data-dom-edit-press-waiting";
|
|
126
|
+
|
|
127
|
+
/** A press that landed while the preview reloads: it starts once the new preview shows what it pressed. */
|
|
128
|
+
export interface WaitingPressState {
|
|
129
|
+
pointerId: number;
|
|
130
|
+
startX: number;
|
|
131
|
+
startY: number;
|
|
132
|
+
draw: ((dx: number, dy: number) => void) | null;
|
|
133
|
+
frame: number;
|
|
134
|
+
moved: React.PointerEvent<HTMLDivElement> | null;
|
|
135
|
+
released: React.PointerEvent<HTMLDivElement> | null;
|
|
136
|
+
after: WaitingPressState | null;
|
|
137
|
+
ended: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
export type FocusableDomEditOverlay = {
|
|
125
141
|
focus(options?: FocusOptions): void;
|
|
126
142
|
};
|
|
@@ -245,6 +261,7 @@ export interface DomEditGroupPathOffsetCommit {
|
|
|
245
261
|
|
|
246
262
|
// Refs are stable across renders; values are read via .current.
|
|
247
263
|
export type UseDomEditOverlayGesturesOptions = {
|
|
264
|
+
activeCompositionPathRef: RefObject<string | null>;
|
|
248
265
|
overlayRef: RefObject<HTMLDivElement | null>;
|
|
249
266
|
iframeRef: RefObject<HTMLIFrameElement | null>;
|
|
250
267
|
boxRef: RefObject<HTMLDivElement | null>;
|
|
@@ -255,6 +272,7 @@ export type UseDomEditOverlayGesturesOptions = {
|
|
|
255
272
|
gestureRef: RefObject<GestureState | null>;
|
|
256
273
|
groupGestureRef: RefObject<GroupGestureState | null>;
|
|
257
274
|
blockedMoveRef: RefObject<BlockedMoveState | null>;
|
|
275
|
+
waitingPressRef: RefObject<WaitingPressState | null>;
|
|
258
276
|
rafPausedRef: RefObject<boolean>;
|
|
259
277
|
suppressNextBoxClickRef: RefObject<boolean>;
|
|
260
278
|
setOverlayRect: (next: OverlayRect | null) => void;
|
|
@@ -30,6 +30,7 @@ it("a drag press the layer cannot take gets the notice, counts as handled, and l
|
|
|
30
30
|
snapGuidesRef: ref(null),
|
|
31
31
|
groupGestureRef: ref(null),
|
|
32
32
|
blockedMoveRef: ref(null),
|
|
33
|
+
waitingPressRef: ref(null),
|
|
33
34
|
setOverlayRect: vi.fn(),
|
|
34
35
|
suppressNextBoxClickRef: ref(false),
|
|
35
36
|
hoverSelectionRef: ref(null),
|
|
@@ -47,6 +47,7 @@ function pressOptions(element: HTMLElement) {
|
|
|
47
47
|
snapGuidesRef: ref(null),
|
|
48
48
|
groupGestureRef: ref(null),
|
|
49
49
|
blockedMoveRef: ref(null),
|
|
50
|
+
waitingPressRef: ref(null),
|
|
50
51
|
setOverlayRect: vi.fn(),
|
|
51
52
|
suppressNextBoxClickRef: ref(false),
|
|
52
53
|
hoverSelectionRef: ref(null),
|
|
@@ -169,6 +170,7 @@ describe("a rotate on a page that loads GSAP", () => {
|
|
|
169
170
|
gestureRef: ref<GestureState | null>(null),
|
|
170
171
|
groupGestureRef: ref(null),
|
|
171
172
|
blockedMoveRef: ref(null),
|
|
173
|
+
waitingPressRef: ref(null),
|
|
172
174
|
rafPausedRef: ref(false),
|
|
173
175
|
onCanvasPointerMoveRef: ref(vi.fn()),
|
|
174
176
|
};
|
|
@@ -222,6 +224,7 @@ describe("a rotate press on an element a GSAP tween turns", () => {
|
|
|
222
224
|
iframeRef: ref(null),
|
|
223
225
|
gestureRef: ref<GestureState | null>(null),
|
|
224
226
|
rafPausedRef: ref(false),
|
|
227
|
+
waitingPressRef: ref(null),
|
|
225
228
|
};
|
|
226
229
|
const press = {
|
|
227
230
|
clientX: 25,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* These are pure "start a new gesture" operations — no draft rect updates.
|
|
4
4
|
*/
|
|
5
5
|
import { type DomEditSelection } from "./domEditing";
|
|
6
|
+
import type { EditMoment } from "./manualEditsTypes";
|
|
6
7
|
import {
|
|
7
8
|
applyManualOffsetDragDraft,
|
|
8
9
|
createManualOffsetDragMember,
|
|
@@ -49,6 +50,7 @@ export function notifyBlockedPress(
|
|
|
49
50
|
export function startGroupDrag(
|
|
50
51
|
e: React.PointerEvent<HTMLElement>,
|
|
51
52
|
opts: UseDomEditOverlayGesturesOptions,
|
|
53
|
+
at?: EditMoment,
|
|
52
54
|
): boolean {
|
|
53
55
|
const items = opts.groupOverlayItemsRef.current;
|
|
54
56
|
if (items.length <= 1) return false;
|
|
@@ -73,6 +75,7 @@ export function startGroupDrag(
|
|
|
73
75
|
element: item.element,
|
|
74
76
|
rect: item.rect,
|
|
75
77
|
gesture: "drag",
|
|
78
|
+
at,
|
|
76
79
|
});
|
|
77
80
|
if (!result.ok) {
|
|
78
81
|
restoreManualOffsetDragMembers(members);
|
|
@@ -144,8 +147,10 @@ export function startGesture(
|
|
|
144
147
|
selection?: DomEditSelection;
|
|
145
148
|
rect?: OverlayRect | null;
|
|
146
149
|
resizeHandle?: ResizeHandle;
|
|
150
|
+
at?: EditMoment;
|
|
147
151
|
},
|
|
148
152
|
): boolean {
|
|
153
|
+
const at = options?.at;
|
|
149
154
|
const sel = options?.selection ?? opts.selectionRef.current;
|
|
150
155
|
const rect = options?.rect ?? opts.overlayRectRef.current;
|
|
151
156
|
const box = opts.boxRef.current;
|
|
@@ -196,6 +201,7 @@ export function startGesture(
|
|
|
196
201
|
element: sel.element,
|
|
197
202
|
rect,
|
|
198
203
|
gesture: "drag",
|
|
204
|
+
at,
|
|
199
205
|
});
|
|
200
206
|
if (!result.ok) {
|
|
201
207
|
opts.onBlockedMoveRef.current(result.selection, result.reason);
|
|
@@ -217,6 +223,7 @@ export function startGesture(
|
|
|
217
223
|
element: sel.element,
|
|
218
224
|
rect,
|
|
219
225
|
gesture: "resize",
|
|
226
|
+
at,
|
|
220
227
|
});
|
|
221
228
|
if (result.ok) {
|
|
222
229
|
pathOffsetMember = result.member;
|
|
@@ -225,12 +232,13 @@ export function startGesture(
|
|
|
225
232
|
// Hold a % translate as the same px now, so a growing box can't drag it along mid-frame.
|
|
226
233
|
if (result.member.plainTranslate) applyManualOffsetDragDraft(result.member, 0, 0);
|
|
227
234
|
} else {
|
|
228
|
-
manualEditDragToken = beginStudioManualEditGesture(sel.element, "resize");
|
|
235
|
+
manualEditDragToken = beginStudioManualEditGesture(sel.element, "resize", at);
|
|
229
236
|
}
|
|
230
237
|
} else {
|
|
231
238
|
manualEditDragToken = beginStudioManualEditGesture(
|
|
232
239
|
sel.element,
|
|
233
240
|
kind === "rotate" ? "rotate" : "resize",
|
|
241
|
+
at,
|
|
234
242
|
);
|
|
235
243
|
}
|
|
236
244
|
}
|
|
@@ -68,6 +68,7 @@ function dragWithSaveRunning(save: Promise<void> | (() => Promise<void>)) {
|
|
|
68
68
|
snapGuidesRef: ref(null),
|
|
69
69
|
groupGestureRef: ref(null),
|
|
70
70
|
blockedMoveRef: ref(null),
|
|
71
|
+
waitingPressRef: ref(null),
|
|
71
72
|
setOverlayRect: vi.fn(),
|
|
72
73
|
suppressNextBoxClickRef: ref(false),
|
|
73
74
|
hoverSelectionRef: ref(null),
|
|
@@ -127,6 +128,7 @@ function gestureWithSaveRunning(kind: "resize" | "rotate", save: Promise<void>)
|
|
|
127
128
|
snapGuidesRef: ref(null),
|
|
128
129
|
groupGestureRef: ref(null),
|
|
129
130
|
blockedMoveRef: ref(null),
|
|
131
|
+
waitingPressRef: ref(null),
|
|
130
132
|
setOverlayRect: vi.fn(),
|
|
131
133
|
suppressNextBoxClickRef: ref(false),
|
|
132
134
|
hoverSelectionRef: ref(null),
|