개발2026-02-18

WebCreator-X: 레이아웃 시스템 분석 보고서

사이드바 조작과 캔버스 드래그 인터랙션의 불일치 문제 분석

1. 현상 요약: “데이터는 존재하나 화면은 움직이지 않는 상태”

현재 WebCreator-X 에디터에서는 우측 사이드바에서 top, left 등 위치 값을 직접 입력해도 캔버스의 노드가 움직이지 않거나, 드래그 작업 후 값이 꼬이는 현상이 발생합니다. 이는 노드의 위치를 결정하는 **두 가지 데이터 선로(Track)**가 동기화되지 않고 각자 작동하기 때문입니다.

2. 코드 흐름 기반 문제 분석

2.1 사이드바 명령의 전달 (style 선로)

사용자가 PositionSection.tsx에서 값을 입력하면 node.style 객체가 업데이트됩니다.

  • 경로: PositionSection -> useUpdateNode -> EditorStore
  • 결과: node.style.top = 100 등의 표준 CSS 값이 저장됨.

2.2 스타일 필터링의 역설 (processNodeStyles)

노드가 렌더링될 때, processNodeStyles.ts는 노드의 스타일 중 레이아웃에 영향을 주는 속성들을 강제로 필터링합니다.

  • 이유: "레이아웃은 래퍼(EditorNodeWrapper)가 관리한다"는 규칙 때문.
  • 결과: 사이드바에서 입력한 top, left, position 값이 실제 컴포넌트에는 도달하지 못하고 사라짐.

2.3 래퍼의 독점적 통제 (layout 선로)

실제 화면에서 위치를 잡는 것은 EditorNodeWrapper 내부의 react-rnd 라이브러리입니다.

  • 경로: EditorNodeWrapper.tsx -> <Rnd position={{ x, y }} />
  • 동작 방식: Rnd는 오직 node.layout.x, node.layout.y만 바라보며, 내부적으로 transform: translate()를 사용하여 노드를 배치합니다.
  • 충돌: 사이드바가 수정하는 style.topRnd가 수정하는 layout.y는 서로 다른 변수이므로, 한쪽을 바꿔도 다른 쪽은 꿈쩍도 하지 않습니다.

3. 핵심 문제점 (Pain Points)

  1. 데이터의 이원화 (Split Brain): 표준 CSS(style) 방식과 디자인 툴 좌표(layout) 방식이 공존하지만 서로 대화하지 않음.
  2. Relative 모드에서의 ‘Rnd’ 잔류: Relative 노드도 여전히 Rnd 래퍼에 감싸져 있어, 부모 컨테이너(Stack 등)의 자연스러운 흐름을 타지 못하고 유령 좌표(translate)에 갇힘.
  3. 관리 주체 모호: 어떤 상황에서 드래그를 허용하고, 어떤 상황에서 사이드바 입력을 우선할지에 대한 전략적 분기가 부족함.

4. 향후 해결 방향 제안

✅ 해결책 1: 데이터 동기화 (Bridge 구현)

사이드바에서 style.top을 수정할 때, 내부적으로 layout.y 값도 함께 업데이트하는 로직을 추가합니다. 반대로 드래그가 끝났을 때(onResizeStop, onDragStop) style 값도 갱신해줍니다.

✅ 해결책 2: 포지션에 따른 Rnd 활성화 제어

  • Absolute/Fixed: Rnd를 활성화하여 자유로운 드래그와 좌표 기반 배치를 허용합니다.
  • Relative/Sticky: Rnd의 드래그 기능을 비활성화(disableDragging)하고, 노드가 부모의 Layout 엔진(Stack 등)의 흐름을 따르도록 layout.x/y를 제어합니다.

✅ 해결책 3: 데이터 구조 통합

기존의 style.top/left를 아예 제거하고, 에디터의 모든 위치 정보는 layout 객체로만 관리하도록 UI와 로직을 통일합니다. (Figma/Framer와 유사한 방식)


이 문제는 **웹의 전통적인 문서 흐름(Flow)**과 **디자인 툴의 자유 좌표(Absolute)**를 하나의 시스템에 녹여내는 과정에서 발생하는 구조적 단계입니다.