mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix(studio): bake the group transform into members on ungroup (#1764)
Ungroup only baked the wrapper's layout (left/top), not its GSAP transform — so a moved group's members snapped back to their creation-time positions. Distribute the group's static transform onto each member before stripping it: translation is an exact per-axis add; rotation/scale are composed about the group center so off-center members don't drift. Animated group transforms are left to be stripped, not baked.
This commit is contained in:
@@ -404,6 +404,15 @@ export interface WrapElementsResult {
|
||||
export interface UnwrapElementsResult {
|
||||
html: string;
|
||||
unwrapped: boolean;
|
||||
/** The unwrapped wrapper's id, so callers can strip GSAP that targeted it
|
||||
* (the wrapper is gone; a leftover `gsap.set("#id")` would throw at runtime). */
|
||||
unwrappedGroupId?: string;
|
||||
/** Members (id'd children) with their absolute layout centres (post un-rebase),
|
||||
* so the caller can BAKE the group's GSAP transform into each member before
|
||||
* stripping it — otherwise the group's moves are lost on ungroup. */
|
||||
members?: Array<{ id: string; cx: number; cy: number }>;
|
||||
/** The wrapper's layout centre — the pivot for baking the group's rotation/scale. */
|
||||
groupCenter?: { cx: number; cy: number };
|
||||
}
|
||||
|
||||
export interface ElementRebase {
|
||||
@@ -554,22 +563,36 @@ export function unwrapElementsFromHtml(
|
||||
// Undo the rebase: child absolute position = child (rebased) + wrapper origin.
|
||||
const wLeft = getInlineStylePx(group, "left");
|
||||
const wTop = getInlineStylePx(group, "top");
|
||||
const groupCenter = {
|
||||
cx: wLeft + getInlineStylePx(group, "width") / 2,
|
||||
cy: wTop + getInlineStylePx(group, "height") / 2,
|
||||
};
|
||||
|
||||
// Move children back to the wrapper's slot, preserving order.
|
||||
const members: Array<{ id: string; cx: number; cy: number }> = [];
|
||||
for (const child of Array.from(group.children)) {
|
||||
if (isHTMLElement(child)) {
|
||||
setInlineLeftTop(
|
||||
child,
|
||||
getInlineStylePx(child, "left") + wLeft,
|
||||
getInlineStylePx(child, "top") + wTop,
|
||||
);
|
||||
const newLeft = getInlineStylePx(child, "left") + wLeft;
|
||||
const newTop = getInlineStylePx(child, "top") + wTop;
|
||||
setInlineLeftTop(child, newLeft, newTop);
|
||||
if (child.id) {
|
||||
members.push({
|
||||
id: child.id,
|
||||
cx: newLeft + getInlineStylePx(child, "width") / 2,
|
||||
cy: newTop + getInlineStylePx(child, "height") / 2,
|
||||
});
|
||||
}
|
||||
}
|
||||
parent.insertBefore(child, group);
|
||||
}
|
||||
const groupId = group.id || undefined;
|
||||
group.remove();
|
||||
|
||||
return {
|
||||
html: wrappedFragment ? document.body.innerHTML || "" : document.toString(),
|
||||
unwrapped: true,
|
||||
unwrappedGroupId: groupId,
|
||||
members,
|
||||
groupCenter,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user