group transform
여러 도형을 함께 움직이거나 회전하거나 resize하면 사실상 임시 group을 다루는 것입니다. group transform은 편집기 수학의 중요한 경계입니다.
reparenting에서 world transform을 보존하는 코드
node를 다른 parent 아래로 옮길 때 화면 위치를 유지하려면 새 local matrix를 다시 계산해야 합니다.
function reparentKeepingWorld(node, newParent) {
const oldWorld = node.worldMatrix;
const newParentWorld = newParent ? newParent.worldMatrix : identity3();
const newLocal = multiply3(invert3(newParentWorld), oldWorld);
return {
...node,
parentId: newParent ? newParent.id : null,
localMatrix: newLocal
};
}
selection group도 같은 사고방식으로 다룹니다. 임시 group matrix를 만들고, 각 child의 local/world 관계를 유지하면서 최종 transform으로 풀어냅니다.
function applyGroupTransform(children, groupDeltaMatrix) {
return children.map((child) => ({
...child,
worldMatrix: multiply3(groupDeltaMatrix, child.worldMatrix)
}));
}
실제 문서에 저장할 때는 worldMatrix를 그대로 source of truth로 두기보다 parent 기준 local matrix로 다시 풀어야 합니다.
function applyGroupTransformToDocument(document, childIds, groupDeltaMatrix) {
return childIds.reduce((nextDocument, id) => {
const node = nextDocument.nodesById.get(id);
const parent = node.parentId ? nextDocument.nodesById.get(node.parentId) : null;
const parentWorld = parent ? parent.worldMatrix : identity3();
const nextWorld = multiply3(groupDeltaMatrix, node.worldMatrix);
const nextLocal = multiply3(invert3(parentWorld), nextWorld);
return updateNode(nextDocument, id, { localMatrix: nextLocal });
}, document);
}
부모 matrix가 자식에게 누적된다
scene graph에서 child의 world matrix는 parent world matrix와 child local matrix의 곱입니다.
childWorld = parentWorld * childLocal
group을 움직이면 parent matrix가 바뀌고, child local 값은 그대로 둘 수 있습니다.
selection group은 임시 parent처럼 생각할 수 있다
여러 node를 선택하고 resize/rotate할 때 실제 group node를 만들지 않아도, selection bounds를 임시 parent처럼 보고 계산할 수 있습니다.
selection bounds = temporary group box
child transforms = relative to selection box
작업이 끝나면 각 child의 transform에 결과를 반영합니다.
reparenting은 world transform을 보존해야 한다
node를 다른 group으로 옮길 때 화면 위치가 튀면 안 됩니다. 이때는 기존 world matrix를 유지하도록 새 local matrix를 계산합니다.
newLocal = inverse(newParentWorld) * oldWorld
이 식은 group, frame, component 내부 편집에서 계속 나옵니다.
오늘의 핵심
group transform은 parent/child matrix 관계를 다루는 문제입니다.
local
parent world
child world
reparent while preserving world
이 감각이 있으면 Figma-like scene graph의 편집 동작을 안정적으로 만들 수 있습니다.