frame과 clipping
frame은 단순한 group이 아닙니다. frame은 child를 담고, 좌표계를 제공하고, 필요하면 child를 자신의 bounds 안으로 clip합니다.
Figma-like 에디터에서 frame은 핵심 node type입니다.
frame은 local coordinate system이다
frame 안의 child는 frame의 local 좌표계를 기준으로 배치됩니다.
Frame local (0,0)
child x=24, y=32
frame을 움직여도 child local position은 그대로 남습니다. world matrix만 달라집니다.
clipping은 렌더링 정책이다
frame이 clipsContent를 갖는다면 child는 frame bounds 밖으로 보이면 안 됩니다.
const frame = {
type: "frame",
width: 640,
height: 480,
clipsContent: true
};
Canvas 2D에서는 clip path를 쓰고, WebGL에서는 scissor나 stencil, 또는 shader clipping 전략을 사용할 수 있습니다.
hit testing도 clipping을 고려한다
보이지 않는 child가 클릭되면 이상합니다. frame이 clipping한다면 hit testing에서도 frame bounds 밖 child는 제외해야 합니다.
if point is outside clipped frame:
skip children
렌더링과 입력이 같은 clipping 정책을 써야 합니다.
function collectVisibleChildren(frame, scene, worldPoint) {
if (frame.clipsContent && !pointInNode(worldPoint, frame)) {
return [];
}
return frame.children.map((id) => scene.nodesById.get(id));
}
renderer도 같은 조건으로 clip stack을 구성합니다.
function renderFrame(pass, frame, snapshot) {
if (frame.clipsContent) pass.pushClip(nodeWorldBounds(frame));
for (const childId of frame.children) renderNode(pass, snapshot.scene.nodesById.get(childId));
if (frame.clipsContent) pass.popClip();
}
오늘의 핵심
frame은 container, coordinate system, clipping boundary입니다.
frame local coordinates
child transforms
render clipping
hit test clipping
이 네 가지가 같은 frame model에서 나와야 합니다.