FEConf · FEConf 2025 2025
그리드 기반 웹 에디터 / 빌더 구현기
Figma나 Notion처럼 그리드 기반 드래그앤드롭 에디터를 구현하면서 해결한 복잡한 좌표 계산과 상태 관리 문제를 공유합니다.
요약
핵심 토픽
학습 포인트
1. 그리드 스냅과 좌표 변환
에디터의 좌표계는 '화면 픽셀 좌표'와 '그리드 셀 좌표' 두 가지를 관리합니다. 마우스 이벤트는 화면 좌표를 반환하므로 캔버스 오프셋과 줌 배율을 고려해 그리드 좌표로 변환해야 합니다. 스냅 기능은 변환된 그리드 좌표를 `Math.round()`로 반올림해 구현합니다.
핵심 용어
2. Command 패턴으로 Undo/Redo 구현
에디터의 모든 조작(이동, 크기 변경, 삭제)을 Command 객체로 추상화합니다. 각 Command는 `execute()`와 `undo()` 메서드를 가집니다. 실행 스택에 Command를 쌓고, Ctrl+Z 시 스택에서 꺼내 undo()를 호출합니다. 이 패턴으로 임의 깊이의 Undo/Redo가 구현됩니다.
핵심 용어
3. 충돌 감지와 자동 재배치
그리드 에디터에서 요소가 겹치면 자동으로 아래로 밀어내는 알고리즘이 필요합니다. AABB(Axis-Aligned Bounding Box) 충돌 검사로 겹침을 감지하고, 충돌한 요소들을 재귀적으로 아래로 이동시킵니다. 이 과정에서 연쇄 충돌이 발생할 수 있으므로 BFS/DFS로 처리 순서를 결정합니다.
핵심 용어
면접 질문
Q1. 웹에서 Undo/Redo를 구현하는 방법을 설명해주세요.
힌트
[감점 답변] 정의만 반복하거나 "웹에서 Undo/Redo를 구현하는 방법을 설명해주세요."에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] 두 가지 주요 방법: (1) Command 패턴 — 각 조작을 execute/undo 메서드를 가진 객체로 추상화. 세밀한 제어가 가능하지만 구현이 복잡. (2) 상태 스냅샷 — Immer 같은 불변 상태 라이브러리로 각 조작 전 스냅샷 저장. 구현이 간단하지만 메모리 사용량이 큼. 에디터처럼 복잡한 경우 Command 패턴 + 불변 상태를 혼합합니다.
Q2. 드래그앤드롭을 구현할 때 HTML5 DnD API를 사용하지 않는 이유는 무엇인가요?
힌트
[감점 답변] 정의만 반복하거나 "드래그앤드롭을 구현할 때 HTML5 DnD API를 사용하지 않는 이유는 무엇인가요?"에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] HTML5 DnD API의 한계: 드래그 중 요소 위치 커스텀 어려움(고스트 이미지 제한), mousemove로 실시간 좌표 추적 불가, 터치 이벤트 미지원, 크로스 브라우저 불일치. 대안: Pointer Events API(`pointerdown`, `pointermove`, `pointerup`)를 직접 사용하면 마우스/터치/스타일러스를 통합 처리하고 드래그 중 자유로운 DOM 조작이 가능합니다.
Q3. 에디터의 줌/패닝 기능을 구현할 때 좌표 변환은 어떻게 처리하나요?
힌트
[감점 답변] 정의만 반복하거나 "에디터의 줌/패닝 기능을 구현할 때 좌표 변환은 어떻게 처리하나요?"에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] CSS `transform: scale() translate()`를 사용하면 시각적 변환은 간단하지만 이벤트 좌표는 변환 전 좌표를 반환합니다. 마우스 이벤트 좌표를 에디터 내부 좌표로 변환하려면: (화면 좌표 - 캔버스 오프셋) / 줌 배율 + 패닝 오프셋. `DOMMatrix`나 SVG의 `getScreenCTM().inverse()`를 활용하면 행렬 변환을 더 우아하게 처리할 수 있습니다.
선행 학습
- JavaScript 이벤트 처리(mousedown, mousemove)
- CSS Transform과 좌표 시스템
- React 상태 관리 기본
핵심 타임스탬프
학습 방법
1단계: React DnD나 dnd-kit 없이 `pointerdown/pointermove/pointerup`만으로 드래그 가능한 박스를 구현해보세요. 좌표 계산의 기본기를 익히는 가장 좋은 방법입니다. 2단계: Command 패턴으로 간단한 할 일 앱에 Undo/Redo를 구현해보세요. 패턴의 유연성을 직접 체감할 수 있습니다. 3단계: 그리드 스냅 기능을 추가하고 두 박스가 겹칠 때 AABB 충돌을 감지해 색상으로 표시하는 데모를 만들어보세요. 4단계: 동료에게 "좌표 시스템"의 핵심을 5분 안에 설명해보세요. 막히는 부분이 아직 구조적으로 이해되지 않은 지점입니다.