mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(studio): stop horizontal drag from cancelling a vertical restack
Lane/overlap resolution now uses the clip's authored time span instead of the live dragged start. A diagonal drag that drifts the clip out of overlap no longer flips the placement from restack to lane-join, so the two axes never fight.
This commit is contained in:
@@ -107,18 +107,16 @@ export function resolveTimelineMove(
|
||||
Math.max(0, input.maxStart),
|
||||
);
|
||||
|
||||
// Stacking mode: vertical movement writes z-index only. The authored
|
||||
// data-track-index is preserved even when the pointer crosses rows.
|
||||
// Stacking mode: the two axes never fight. Horizontal movement writes time
|
||||
// (nextStart); vertical movement writes z-index. Lane/overlap resolution
|
||||
// uses the clip's authored time span, NOT the dragged start — otherwise a
|
||||
// diagonal drag that drifts the clip out of overlap silently flips the
|
||||
// placement from "restack" to "join lane" and cancels the reorder.
|
||||
if (input.stackingElement) {
|
||||
const stackingElement = {
|
||||
...input.stackingElement,
|
||||
start: nextStart,
|
||||
duration: input.duration,
|
||||
};
|
||||
const layerMove =
|
||||
input.timelineLayers && input.layerOrder
|
||||
? resolveTimelineLayerStackingMove({
|
||||
element: stackingElement,
|
||||
element: { ...input.stackingElement, duration: input.duration },
|
||||
layers: input.timelineLayers,
|
||||
layerOrder: input.layerOrder,
|
||||
trackDeltaRaw,
|
||||
|
||||
@@ -202,13 +202,17 @@ describe("useTimelineClipDrag", () => {
|
||||
harness.unmount();
|
||||
});
|
||||
|
||||
it("uses the preview start when resolving whether a dragged clip can join a lane", async () => {
|
||||
it("resolves lane stacking from the authored time span, independent of horizontal drag", async () => {
|
||||
const front = timelineElement({ id: "front", track: 0, zIndex: 3 });
|
||||
const back = timelineElement({ id: "back", track: 1, zIndex: 1 });
|
||||
back.start = 0;
|
||||
front.start = 0;
|
||||
const harness = renderDragHarness([front, back]);
|
||||
|
||||
// Drag up one row AND rightward in time. The horizontal drift moves the
|
||||
// clip out of overlap, but the two axes never fight: the vertical restack
|
||||
// is resolved from the authored (overlapping) span, so it still inserts
|
||||
// above the target lane rather than silently joining it.
|
||||
harness.startDrag(back, 1);
|
||||
harness.movePointer(200, -TRACK_H);
|
||||
await harness.dropPointer();
|
||||
@@ -219,8 +223,8 @@ describe("useTimelineClipDrag", () => {
|
||||
track: 1,
|
||||
stackingReorder: {
|
||||
contextKey: "root",
|
||||
placement: { type: "onto", layerId: harness.layers[0]!.id },
|
||||
zIndexChanges: [{ key: "back", zIndex: 3 }],
|
||||
placement: { type: "above", layerId: harness.layers[0]!.id },
|
||||
zIndexChanges: [{ key: "back", zIndex: 4 }],
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user