contentEditable 버리고 2D canvas에 직접 글자를 그리는 오픈소스 편집기 Tasfer
- contentEditable을 버리고 글자, 커서, 선택 영역, 줄바꿈, 아랍어 RTL 배치를 모두 HTML5 2D canvas에 직접 그리는 편집기 Tasfer를 공개함
- 키보드 입력과 자동 교정, 아랍어와 중국어 IME는 브라우저가 실제 입력 필드로 인식해야 동작해서 숨은 input 요소로 받고 화면 그리기만 canvas가 맡음
- 처음에는 WebGL과 WebGPU로 TrueType 폰트를 직접 파싱해 GPU에 텍스트를 그리려다 접었고, 2025년 크리스마스 연휴에 Claude 등 LLM을 집중적으로 쓰면서 개발 속도가 크게 붙음
- 서버와 계정 없이 문서를 기기에 두고 CRDT를 직접 구현해 WebRTC로 피어끼리 암호화 전송하며, 피어 탐색용 시그널링 서버와 직접 연결이 막힐 때의 암호화 릴레이만 예외로 둠
- 앱은 AGPL, 편집 엔진은 MIT로 이중 라이선스해 SDK로 분리 공개했고 LaTeX 렌더러와 코드 블록, 표, 캘린더를 얹어 웹과 macOS, Windows, Linux, iOS, Android에서 실행됨
Hacker News 의견들
프라이버시 설계는 좋은데 iOS에서 자동 교정이 아예 깨져 있더라. 실제로 테스트는 안 해본 것 같고, 웹사이트도 통째로 LLM이 쓴 티가 나서 신뢰가 안 간다.
Show HN에 올리면 테스터는 금방 모인다. 나도 iOS에서 줄바꿈이랑 자동 교정 커서 버그 확인했음. LLM 도움을 받은 사이트라도 사람이 과정을 검토했다는 티가 나면 괜찮다고 본다.
피드백 고맙다. iOS는 숨은 contenteditable을 canvas가 제어하는 걸 유독 싫어해서 힘들었고, 그래서 App Store에 iOS 앱도 따로 냈다. LLM은 혼자 개발하는 내게 구현 속도를 준 도구일 뿐, 생각을 대신하게 두면 안 된다고 본다.
커스텀 리치 텍스트 LaTeX 편집기는 진짜 멋지다. 다만 태블릿에서 텍스트 선택할 때 자동 스크롤이 네이티브만큼 정밀하지 않아서 좀 불편하더라.
10년 가까이 글쓰기 도구를 만들어 왔는데 bidi 처리 쪽으로 얘기 나눌 만하다. 내 프로젝트 Enso도 한번 봐달라.
UI는 뭘로 만들었나? 깔끔하다. radix UI에 스타일은 직접 입혔다고 하더라.
예전에 contentEditable로 JATS 문서 모델 편집기를 만들다가 중첩 문맥을 합치고 나누는 데서 죽을 뻔했는데 이건 잘 풀었네. 커서가 굵게 영역인지 일반 모드인지 방향으로 알려주는 건 처음 보는 발명 같다.
그 발명은 나도 좋다고 본다. 근데 굵게 표시를 지우려면 Ctrl+B 말고는 방법이 없고, 첫 번째 불릿을 지우고 undo 하면 복구가 안 되고 두 번째를 지우면 커서가 첫 불릿으로 튄다. 복사할 땐 마크다운 원문이 나왔으면 좋겠다.
canvas가 성능 때문에 당연한 선택이라니 그건 좀 틀린 얘기다. DOM을 과하게 복잡하게 만들지만 않으면 브라우저에 맡기는 쪽이 더 빠르고, Monaco도 canvas가 아니다.
Monaco는 canvas를 안 쓴다. Google Docs가 canvas를 쓴다는 걸 보고 시작했고, WebGL이나 WebGPU였으면 더 빨랐겠지만 폰트 파싱이 너무 어려웠다. 지금 결과로 만족한다.
온라인 Word가 데스크톱이랑 다르게 렌더링되는 게 늘 답답하다. 보조금 신청서처럼 분량 제한이 걸린 문서를 쓸 때는 결국 윈도우 VM을 띄우게 된다.
CodeMirror로 아웃라이너 블록, 산문, 임베드를 한 편집기에 넣는 걸 9개월째 쓰고 있는데 타이핑 감이 가볍고 빠르다. canvas 없이도 충분히 된다는 쪽이다.
IME랑 스크린 리더는 canvas에서 어떻게 처리하나? 레이아웃은 줄 단위로 다시 계산하나, 블록 단위인가?
편집 중인 줄 전체를 담은 숨은 contenteditable div가 있어서 IME는 그걸로 동작한다.
편집기가 악센트 문자(á, ã, ö, è)를 전부 삼켜버린다.
난 안 그런데 브라우저랑 OS를 적어줘야 알 수 있겠다.