mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(studio): make a timeline lane a z-band so a vertical restack moves the row
Clips share a lane only when they carry the same z-index and don't overlap in time. Previously a non-overlapping clip packed into the first time-compatible row regardless of z, so restacking changed the z-index but the clip's row never followed.
This commit is contained in:
@@ -34,16 +34,29 @@ function rowIds(rows: readonly { elements: readonly TimelineElement[] }[]): stri
|
||||
}
|
||||
|
||||
describe("buildStackingTimelineLayers", () => {
|
||||
it("packs non-overlapping clips into the same lane even when their z-index differs", () => {
|
||||
it("splits non-overlapping clips into separate lanes when their z-index differs", () => {
|
||||
// A lane is a z-band: differing z must land on different rows even when the
|
||||
// clips don't overlap in time, so a vertical (z) restack actually moves the
|
||||
// clip's row. Rows are ordered by descending z.
|
||||
const result = buildStackingTimelineLayers([
|
||||
rowElement({ id: "back", zIndex: 1, start: 0, duration: 1 }),
|
||||
rowElement({ id: "front", zIndex: 10, start: 1, duration: 1 }),
|
||||
]);
|
||||
|
||||
expect(rowIds(result.visualLayers)).toEqual([["back", "front"]]);
|
||||
expect(rowIds(result.visualLayers)).toEqual([["front"], ["back"]]);
|
||||
expect(result.visualLayers[0]?.zIndex).toBe(10);
|
||||
});
|
||||
|
||||
it("packs non-overlapping clips into one lane when they share a z-index", () => {
|
||||
const result = buildStackingTimelineLayers([
|
||||
rowElement({ id: "back", zIndex: 5, start: 0, duration: 1 }),
|
||||
rowElement({ id: "front", zIndex: 5, start: 1, duration: 1 }),
|
||||
]);
|
||||
|
||||
expect(rowIds(result.visualLayers)).toEqual([["back", "front"]]);
|
||||
expect(result.visualLayers[0]?.zIndex).toBe(5);
|
||||
});
|
||||
|
||||
it("splits clips into separate lanes when they overlap in time", () => {
|
||||
const result = buildStackingTimelineLayers([
|
||||
rowElement({ id: "front", zIndex: 10, start: 0, duration: 2 }),
|
||||
|
||||
@@ -78,8 +78,13 @@ function getOrderedContextKeys(items: readonly TimelineLayerOrderItem[]): string
|
||||
}
|
||||
|
||||
function canJoinLayer(layer: BuildLayer, item: TimelineLayerOrderItem): boolean {
|
||||
// A row IS a z-band: clips only share a lane when they carry the same z-index
|
||||
// (and don't overlap in time). Without the z-index gate a non-overlapping clip
|
||||
// greedily packs into the first time-compatible row — the topmost one — so a
|
||||
// vertical restack changes z but the row never follows it.
|
||||
return (
|
||||
layer.contextKey === resolveStackingContextKey(item) &&
|
||||
layer.zIndex === item.zIndex &&
|
||||
layer.elements.every((element) => !timelineElementsOverlap(element, item.element))
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user