캔버스 대규모 개선 — 아트보드·슬라이드쇼부터 그룹 연결·다크모드 색 보정까지
무한 캔버스 보드를 거듭 손봤다. 16:9 아트보드와 슬라이드쇼(Shift+F), 노드 잠금·라인 다중선택에 이어, 그룹 선 연결·색 동기화·Alt 중심 리사이즈, 그리고 다크모드 색 자동 보정·스포이드·글자 서식(볼드/밑줄/취소선)까지. 무빌드 바닐라 JS.
캔버스를 만들기 시작할 때 목표는 소박했다. 옵시디언의 캔버스처럼, 카드를 무한한 판 위에 펼치고 선으로 잇는 메모판. 그런데 한 번 손을 댈 때마다 도구가 조금씩 더 자라더니, 이번 라운드에서는 메모판을 넘어 발표 도구가 됐다. 16:9 아트보드를 깔고, Shift + F 한 번으로 PPT처럼 전체화면 슬라이드쇼를 돌린다. 거기에 노드 잠금, Alt 복제, 라인 다중선택을 더하고, 오래 거슬리던 화살표 마무리와 정렬 버그를 정리했다. 사용방법 창도 한 줄짜리 목록에서 카테고리 메뉴가 있는 2단 도움말로 새로 짰다.
여전히 빌드 도구는 없다. 코어·벡터·프레젠테이션·크롭 — 바닐라 JS 네 파일이 전부다. 그리고 실제 사이트에 올리기 전, 헤드리스 DOM에 모듈을 통째로 띄워 손으로 누를 동작을 코드로 눌러보며 회귀를 막았다.

아트보드와 슬라이드쇼 — 캔버스가 슬라이드 덱이 되다
가장 공들인 부분이다. 도구상자의 아트보드 버튼을 누르면 캔버스 위에 16:9(1600×900) 프레임이 생긴다. 그 위에 카드·이미지·도형을 올려 한 장(슬라이드)을 구성한다. 프레임은 그룹처럼 동작해서, 옮기면 안의 내용이 통째로 따라온다. 슬라이드를 연달아 만들면 매번 화면 중앙에 겹쳐 쌓이던 걸 고쳐, 직전 슬라이드 오른쪽 옆에 나란히 붙도록 했다. 그러면 자연스럽게 왼쪽에서 오른쪽으로 덱이 쌓인다.
그리고 Shift + F. 아트보드를 번호 순서대로 전체화면 슬라이드쇼로 넘긴다. 방향키·PageUp/PageDown·마우스 휠·클릭으로 앞뒤로 가고, ESC로 빠져나온다.
구현에서 택한 길이 마음에 든다. 슬라이드를 따로 이미지로 굽지 않는다. 대신 실제 캔버스를 각 아트보드에 맞춰 확대·이동할 뿐이다. 캔버스 전체는 하나의 transform(이동+확대)으로 그려지니, 슬라이드 A에서 B로 가는 건 그 transform 값을 B의 프레임에 맞게 바꾸는 일이다. 여기에 CSS 트랜지션을 얹으면 화면이 옆으로 미끄러지는 "밀기"가 공짜로 나온다. 16:9 프레임과 화면 비율이 안 맞아 생기는 여백은 검은 레터박스 바로 덮어 옆 슬라이드가 비치지 않게 했다. 전환 효과는 슬라이드마다 없음·페이드·밀기 중 고른다(처음엔 줌도 넣었다가, 어정쩡하게 동작해서 덜어냈다). 배경색도 슬라이드별로 지정할 수 있고, 그 색이 편집 화면과 쇼에서 똑같이 적용된다(기본 흰색).

휠 처리에서 작은 함정이 있었다. 평소 캔버스에서 휠은 스크롤(팬)인데, 슬라이드쇼에서 휠을 굴리면 화면이 아래로 밀려버렸다. 쇼 중에는 휠을 가로채 슬라이드 넘김으로 돌리고, 한 번 넘긴 뒤 잠깐 잠가 한 번의 휠 제스처에 여러 장이 우르르 넘어가지 않게 했다.
화살표를 라인 위에 제대로
연결선 화살표는 오래 거슬렸다. 처음엔 화살표가 늘 가로·세로 한 방향으로만 향했다. 노드의 어느 변에서 선이 나가는지로 각도가 정해졌기 때문이다. 비스듬히 이어진 선에서도 화살표는 곧게 서 있어 어색했다.
고치는 길은 의외로 한 번에 안 났다. 화살표를 "라인 방향"으로 돌렸더니, 이번엔 곡선의 실제 끝과 어긋나 화살표가 선 위에 따로 얹혀 보였다. 결국 두 가지를 같이 손봤다. 먼저 곡선을 더 둥글게(핸들을 길게) 만들고, 화살촉은 곡선의 실제 끝 접선에 정확히 맞춰 회전시켰다 — 베지어의 끝 제어점에서 끝점으로 향하는 방향이 곧 그 지점의 접선이다. 그리고 라인을 끝점까지 다 그리지 않고 화살촉의 V자 노치(뒤 패임)에서 끊었다. 선이 화살표 안으로 사라지며 끝이 깔끔하게 한 점으로 모인다. 사소해 보여도, 다이어그램은 이런 마무리에서 인상이 갈린다.
잠금·복제·라인 다중선택
손이 가는 빈틈을 메웠다.
- 노드 잠금:
Shift + 2로 잠그고, 한 번 더 누르면 풀린다(별도 해제 키 없이 토글). 잠긴 노드는 이동·리사이즈·연결·편집·삭제가 막히고 자물쇠 배지가 붙는다. 배경 틀처럼 고정해두고 싶은 카드에 좋다. 도구상자에도 자물쇠 버튼을 넣었다. - Alt + 드래그 복제: 일러스트레이터의 그 손맛. 선택한 노드를 그 자리에 복제하고 사본을 바로 끌고 간다. 그룹이면 안의 자식과 둘 사이 화살표까지 함께 복제된다.
- 라인 다중선택: 직접선택 도구로 라인(엣지)을 클릭하거나, 드래그로 여러 개를 한 번에 묶어 선택한다(
Shift로 추가,Shift+클릭으로 제외). 예전엔 화살표를 한 번에 하나씩만 골랐는데, 잘못 이어진 선 뭉치를 드래그 한 번으로 쓸어Delete.
그룹을 더 자유롭게
그룹은 단순한 테두리가 아니라 다루는 단위가 됐다.
- 그룹 이름 정렬: 라벨을 좌·중·우로 정렬한다(위 전경 그림의 "정렬된 카드"는 가운데).
- 직접선택으로 프레임 조정: 직접선택 도구로 그룹 모서리를 잡아, 노드처럼 프레임 크기를 바꾼다.
- 그룹과 그 안 노드 정렬: 그룹 하나만 선택하면 안의 카드 전체를 프레임 기준으로 정렬한다. 그리고 그룹과 그 안의 특정 카드들을 함께 선택하면, 그 카드들만 프레임에 맞춘다. 이 두 번째 경우가 "단위가 하나뿐"이라며 아무 동작도 안 하던 버그를 잡았다.
작은 손맛 — 여백
카드 안쪽 패딩을 인스펙터에서 직접 줄이고 늘린다. 빽빽하게 모아 라벨처럼 쓰거나, 넉넉히 띄워 본문 카드로 쓰거나. 별것 아닌데, 보드의 밀도를 잡는 데 의외로 자주 쓴다.
사용방법을 다시 — 한 줄 목록에서 2단 메뉴로
기능이 마흔 줄을 넘기자 사용방법 창이 무너졌다. 끝없이 이어지는 한 줄짜리 목록은 아무도 끝까지 안 읽는다. 왼쪽 카테고리 메뉴 + 오른쪽 내용 패널의 2단으로 다시 짰다. 기본 조작·추가·도구·선택/정렬·노드 편집·그룹/잠금·아트보드/슬라이드쇼·펜/패스·파일로 나누고, 각 항목을 단축키 + 설명의 표로 보여준다. 팝업도 넓혔고, 다크모드와 좁은 화면도 대응한다.

이미지를 붙이거나, 항목을 누르면 캔버스에서 실제로 시연해주는 인터랙티브 튜토리얼까지 갈 수도 있다. 일단 뼈대를 이렇게 잡아두고, 다음에 살을 붙일 생각이다.
잡은 버그 셋
쓰다 보면 드러나는 것들이 있다.
- 그룹 위에 카드가 안 생기던 문제: 연결점을 빈 곳에 떨어뜨리면 새 카드가 생기는데, 하필 그룹 영역에 놓으면 아무 일도 없었다. 코드가 그룹 프레임을 "연결할 대상 노드"로 착각한 탓. 이제 그 자리에 새 카드가 생기고, 위치상 자동으로 그 그룹에 포함된다.
- 그룹 + 내부 노드 정렬: 위에 적은 대로, 그룹과 그 안 노드를 함께 선택하면 정렬이 안 되던 것.
- 이중 스크롤: 긴 카드를 편집하면 스크롤바가 두 개 겹쳐 나왔다. 본문 영역과 그 안의 입력칸이 각각 스크롤한 탓 — 편집 중에는 본문 스크롤을 끄고 입력칸만 스크롤하게 했다.
무빌드, 그리고 검증
이번에도 번들러도 프레임워크도 없다. 바닐라 JS 네 파일이 window.__CANVAS_CORE__라는 작은 API로 느슨하게 맞물린다 — 코어가 노드/엣지/선택/렌더를 쥐고, 벡터(펜·도형·직접선택)와 프레젠테이션과 크롭이 그 위에 얹힌다. 새 기능을 더해도 코어는 거의 안 건드린다.
검증은 헤드리스 DOM(jsdom)으로 했다. 실제 브라우저에 올리기 전, 모듈을 통째로 메모리에 띄우고 아트보드 생성·슬라이드쇼 진입·휠 넘김·잠금 토글·라인 다중선택·정렬·도움말 전환까지 코드로 눌러보며 깨진 곳이 없는지 확인한다. 손으로 매번 클릭해 확인하던 걸 기계에 맡기니, 큰 변경을 마음 편히 친다.
메모판으로 시작한 도구가 슬라이드 덱까지 그리게 됐다. 욕심을 부리자면, 다음엔 슬라이드 안 요소가 장 사이에서 부드럽게 이어지는 전환(피그마의 스마트 애니메이트 같은)과, 도움말 속 인터랙티브 튜토리얼이다. 도구 하나로 어디까지 가나 — 그게 요즘 가장 재밌는 실험이다.
그 후 — 연결·색·서식
보드를 더 쓰면서 손이 가는 곳을 계속 메웠다.
- 그룹에도 선을 잇는다 — 그룹끼리, 그룹과 노드를 화살표로 연결한다. 덩어리 단위로 흐름도를 그리기 좋아졌다.
- 도구상자 색 동기화 — 노드를 고르면 면·선색 스와치가 그 노드의 실제 색을 보여준다. 클릭해서 바로 손본다.
- 색 드래그 버벅임 해소 — 색 피커를 끌 때 매번 캔버스 전체를 다시 그리던 걸, 드래그 중엔 해당 노드의 화면 색만 바꾸고 놓을 때만 커밋하게 했다.
- Alt 중심 리사이즈 — 핸들을 끌 때
Alt를 누르면 중심을 고정한 채 양쪽으로(대각이면 전방향) 늘어난다. - 다크모드 색 자동 보정 — 모드를 바꾸면 직접 칠한 면·선·글자색의 명도를 자동으로 뒤집어 대비를 맞춘다(색조 보존, 저장값은 그대로). 라이트로 돌아오면 원래 색이다.
- 스포이드(
i) — 노드를 고르고i를 누른 뒤 원본 노드를 클릭하면 외형 속성(면·선·글자색·크기·서식…)을 통째로 복제한다. - 글자 서식 — 볼드·밑줄·취소선. 편집 중 드래그한 글자에
Ctrl+B/Ctrl+U/Ctrl+Shift+S, 노드 전체엔 인스펙터 B/U/S 버튼.


손에 더 붙게 — 서식 단축키와 스포이드 손질
며칠 써 보니 자잘하게 거슬리는 여섯 군데가 나와 한 번에 정리했다.

- 단축키가 노드에도 듣는다. 전엔 글자를 편집 중일 때만 듣던
Ctrl+B/Ctrl+U/Ctrl+Shift+S가, 이제 노드만 골라도 볼드·밑줄·취소선을 토글한다. - 브라우저 단축키를 가로챈다.
Ctrl+U(소스 보기)·Ctrl+S(페이지 저장)가 끼어들지 않도록 서식 대상이 있을 땐 기본 동작을 막는다. - 일부만 골라도 그 부분에만. 드래그로 일부 글자를 고른 뒤 인스펙터 아이콘을 눌러 입력칸이 닫혀도, 그 선택 범위를 기억해 정확히 거기에만 적용한다.
- 스포이드 + Space = 핸드툴. 스포이드 상태에서 노드 위에 있어도
Space를 누르는 동안은 화면을 끌어 옮긴다. 원본을 찾아 움직이다 엉뚱한 노드를 복제하던 일이 없어졌다. - 스포이드를 도구상자에. 왼쪽 도구막대에 스포이드 버튼을 더했다(단축키
i와 같다). - 도구마다 커서가 바뀐다. 펜·스포이드·직접선택이 저마다 다른 커서를 쓴다.
이 캔버스는 데스크톱 앱(ICE Canvas)으로도 똑같이 굴러간다. 둘이 같은 코드를 공유하니, 한쪽을 손보면 다른 쪽으로 옮기는 일이 점점 수월해진다.