접근성과 남용에 대한 많은 걱정이 있지만, 이 논의의 또 다른 면을 볼 필요가 있음
최근 트위터에서 흥미로운 스레드를 봤는데, 웹의 발전에 있어 폰트 렌더링과 메트릭스를 JS에서 사용할 수 없어서 90%의 좋은 일들이 일어나지 못한다고 함
웹이 텍스트를 표현하기 위해 설계된 플랫폼인데, 텍스트를 디테일하게 다룰 기능이 없다는 지적, tldraw에서 텍스트 측정을 억지로 구현해야 하는 게 안타깝다는 반응 등 다양한 답변이 있었음 (트위터 스레드: https://x.com/_chenglou/status/1951481453046538493)
웹은 애플리케이션 개발 플랫폼이기 때문에 쉽고 강력하게 만드는 일이 모두에게 좋음
내 생각엔 웹 API는 좀 더 로우 레벨로 내려가야 한다고 보는데, 캔버스용 폰트/텍스트 메트릭스 API가 있다면 매우 좋을 것임
하지만 동시에 웹엔진의 텍스트 레이아웃은 엄청나게 성능이 뛰어나니, 이런 기능이 캔버스 내부에서도 쓰일 수 있다면 멋진 기능이 생겨날 것임
내가 수년간 계속 되짚어온 사례는 ‘페이지네이션이 된 리치텍스트 에디팅’인데, contenteditable만으로는 제품 수준의 구현이 불가능하기 때문에 Google Docs가 자체 레이아웃 엔진을 만든 것임
이 제안이 적용된다면 contenteditable의 강력함과, 페이지/프린트 레이아웃 제어 가능성을 모두 가져갈 수 있음
이 기능이 브라우저에 적용되길 바람
“웹에서 일어날 수 있는 대다수 좋은 일들이 폰트 렌더링 및 메트릭스 접근이 안돼서 불가능하다”는 주장에 좀 의문이 있음
실제 대표적인 혁신적인 사례가 뭔지 보고 싶음
지금도 JS에서 폰트와 메트릭스 정보가 꽤 제공되고 있고, 필요한 기능은 대부분 성능에 심각한 장애 없이 우회할 수 있음
또, HTML-in-Canvas에서 제공되는 기능이 이런 부분에서 근본적인 변화를 주는 것도 아님
나도 Google Docs처럼 Nutrient에서 Harfbuzz와 자체 레이아웃 엔진을 WASM 기반으로 사용하고 있음
데모: https://document-authoring-demo.nutrient.io/
이런 API가 플랫폼에 공식 제공된다면 훨씬 개발이 쉬워질 것임
WASM 덕분에 정말 막다른 길은 아님
ElectricSQL에서 동기화 작업 중이라는 소식을 들었으니 Oleksii에게도 안부 전함
“이 기능이 브라우저에 적용되길 바란다”는 말에, 세상에서 가장 비효율적인 레이아웃/UI 엔진을 캔버스에까지 확장시키길 바라는 이유를 모르겠음
이렇게 되면 오히려 좋은 API 접근권이 없는 현재의 문제만 고착화시킬 뿐임
Figma는 DOM의 한계를 극복하려고 브라우저 안에 또 다른 브라우저를 만드는 방식으로 동작함 (참고: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/)
contenteditable만으로는 제품 수준 구현이 되지 않아 Google Docs가 자체 엔진을 만들었다면, 새 제안이 리치텍스트 레이아웃에 실질적으로 도움이 되기는 어려움
이 기능은 유용성이 크다고 생각하지만, HTML 안에서 Canvas 안에 HTML을 넣는 구조 자체가 뭔가 기묘하고 어울리지 않는 느낌이 듦
내가 생각하기에, 캔버스가 브라우저에서 독립적인 1급 포맷이 되어야 붙임성 있게 다뤄질 수 있다고 봄
그러면 HTML 중심의 페이지에 Canvas를 넣거나, 반대로 Canvas 중심에 HTML 요소가 들어가는 구조도 자연스러울 것임
물론 이건 내 생각일 뿐임
네 얘기에 전혀 이상함이 없음
참고로, 이미 HTML을 SVG 안, 다시 HTML 안 등으로 넣을 수 있음
만약 캔버스가 페이지의 최상위 요소라면, 페이지의 제목은 어디 저장하냐?
결국 <title> 태그를 써야 하니, 예시로
실제로 텍스트를 찾아봤는데, 해당 내용은 정말로 문서에 아직 추가되어야 하는 상태임 ("TODO: Don't be evil"과 교차 참조될 수도 있을 것임)
SVG의 foreignObject 태그를 활용하면 이미 HTML-in-Canvas와 비슷한 결과를 얻을 수 있다는 생각임
예를 들어 https://github.com/zumerlab/snapdom 처럼, DOM을 inlined style로 복사해서 SVG의 foreignObject 안에 넣고, 이를 캔버스로 렌더하는 프로젝트가 있음
이번 제안은 foreignObject를 더 쉽게 캔버스에 그릴 수 있도록 한 것과 비슷함
게다가, 콘텐츠가 바뀔 때 캔버스를 자동으로 업데이트하거나, 상호작용성 등 새로운 기능도 지원함
혹시 내가 틀렸는지 모르겠지만, 순정 JS만으로도 캔버스 위에 HTML을 렌더링하는 건 충분히 가능하다고 느낌
캔버스는 HTML로 할 수 없는 걸 그릴 때 쓰는 것이고, DOM을 대체할 목적이 아닌 구조임
현재로서는 예를 들면
박물관 동상 3D 모델을 보여주는 경우
모델 위에 주목해야 할 특징에 주석(annotations)을 달아야 하는데, 이때 그 주석이 단순한 단어나 숫자 이상이라면
주석이 3D 모델 뒤에 가려져야 하는데, HTML만으로는 이 처리가 무척 힘들고, 복잡한 위치 계산과 프레임 지연 등 이슈가 있음
HTML 캔버스 위에 덧씌우면 전체 주석 요소를 한 번에 보여주거나 숨기는 정도 밖에 불가능했음
3D 텍스트나 SDF 방식 등 별도 렌더링 시스템을 만들면, 접근성도 빠지고 모든 것을 직접 다시 구현해야 했음
복잡한 UI(동영상, 리스트, 셀렉트박스 등)는 HTML로 다시 돌아가야 했음
HTML 요소가 캔버스 위 모든 것보다 앞에 있다면 괜찮지만, 그렇지 않은 경우엔 html 위에 또 캔버스를 깔아야 하고, z-레이어마다 반복작업임
이번 변화로 마침내 브라우저의 “역전된 렌더링 레이어 스택”을 고칠 수 있다고 봄
모든 브라우저 렌더링이 유니버설 캔버스 API 위에 쌓여야 한다고 생각함
곧 우리는 HTML-in-Canvas 안에서도 다시 Canvas 렌더링을 하는 일이 필요하지 않을까 싶은 생각이 듦
만약 중첩된 canvas가 같은 방식을 사용한다면 이미 동작 가능함
다만 순환 참조는 아니고, 진짜 순환되는 canvas를 원하면 부모 canvas 내용을 수동으로 자식 canvas에 그릴 필요가 있음
Pimp My Ride 밈이 떠오를 정도임
“형, 네가 HTML 좋아한다길래, 캔버스 안에 HTML을 넣어서 HTML 안에 또 캔버스를 넣어줬어”라는 느낌임
다음과 같이 body 엘리먼트에 플래그를 하나 주는 건 어떨까 생각이 듦
<body canvas="true"></body>
이러면 페이지 전체가 캔버스와 같은 드로잉 서피스가 되고, 평소처럼 DOM 요소를 렌더할 수 있음
내부적으로 DOM까지 래스터라이즈하는 과정을 오픈해주면 더 나을 것도 같음
아키텍처 상 DOM 렌더링과 캔버스 렌더링이 완전히 대등한 레이어가 됨
예를 들어 페이지에 선을 긋는 액션이 DOM 요소의 리플로우를 유도하거나 무시하도록 제어할 수도 있음
스크린리더가 모두 동시에 비명을 지를 상황이 떠오름
이 방식이면 캔버스가 자동으로 크기 조정도 가능해질 수 있는데, 만약 그렇다면 HTML 조합의 새로운 시대를 여는 것임
iframe을 뛰어넘을 수 있음
어색하긴 하지만 이번 제안에 찬성하는 편임
어떤 걸 그려야 할 때, 기존의 HTML 엘리먼트를 재활용할 일이 종종 있음
예전에는 그걸 오프스크린에서 비트맵으로 렌더링해서 캔버스에 복사하거나, z-index와 position absolute로 조정하려 해도 캔버스가 무조건 시각적으로 덮어버리는 문제가 있었음(최근엔 꽤 개선됨)
이 방식이 완벽한 해결은 아닐 수 있지만, 이전의 꼼수들보다는 한결 낫다고 생각함
딱 html2canvas처럼, 꼭 그렇게 해야 할 상황이면 쓸 만한 해법임
Hacker News 의견
접근성과 남용에 대한 많은 걱정이 있지만, 이 논의의 또 다른 면을 볼 필요가 있음
최근 트위터에서 흥미로운 스레드를 봤는데, 웹의 발전에 있어 폰트 렌더링과 메트릭스를 JS에서 사용할 수 없어서 90%의 좋은 일들이 일어나지 못한다고 함
웹이 텍스트를 표현하기 위해 설계된 플랫폼인데, 텍스트를 디테일하게 다룰 기능이 없다는 지적, tldraw에서 텍스트 측정을 억지로 구현해야 하는 게 안타깝다는 반응 등 다양한 답변이 있었음 (트위터 스레드: https://x.com/_chenglou/status/1951481453046538493)
웹은 애플리케이션 개발 플랫폼이기 때문에 쉽고 강력하게 만드는 일이 모두에게 좋음
내 생각엔 웹 API는 좀 더 로우 레벨로 내려가야 한다고 보는데, 캔버스용 폰트/텍스트 메트릭스 API가 있다면 매우 좋을 것임
하지만 동시에 웹엔진의 텍스트 레이아웃은 엄청나게 성능이 뛰어나니, 이런 기능이 캔버스 내부에서도 쓰일 수 있다면 멋진 기능이 생겨날 것임
내가 수년간 계속 되짚어온 사례는 ‘페이지네이션이 된 리치텍스트 에디팅’인데, contenteditable만으로는 제품 수준의 구현이 불가능하기 때문에 Google Docs가 자체 레이아웃 엔진을 만든 것임
이 제안이 적용된다면 contenteditable의 강력함과, 페이지/프린트 레이아웃 제어 가능성을 모두 가져갈 수 있음
이 기능이 브라우저에 적용되길 바람
“웹에서 일어날 수 있는 대다수 좋은 일들이 폰트 렌더링 및 메트릭스 접근이 안돼서 불가능하다”는 주장에 좀 의문이 있음
실제 대표적인 혁신적인 사례가 뭔지 보고 싶음
지금도 JS에서 폰트와 메트릭스 정보가 꽤 제공되고 있고, 필요한 기능은 대부분 성능에 심각한 장애 없이 우회할 수 있음
또, HTML-in-Canvas에서 제공되는 기능이 이런 부분에서 근본적인 변화를 주는 것도 아님
나도 Google Docs처럼 Nutrient에서 Harfbuzz와 자체 레이아웃 엔진을 WASM 기반으로 사용하고 있음
데모: https://document-authoring-demo.nutrient.io/
이런 API가 플랫폼에 공식 제공된다면 훨씬 개발이 쉬워질 것임
WASM 덕분에 정말 막다른 길은 아님
ElectricSQL에서 동기화 작업 중이라는 소식을 들었으니 Oleksii에게도 안부 전함
“이 기능이 브라우저에 적용되길 바란다”는 말에, 세상에서 가장 비효율적인 레이아웃/UI 엔진을 캔버스에까지 확장시키길 바라는 이유를 모르겠음
이렇게 되면 오히려 좋은 API 접근권이 없는 현재의 문제만 고착화시킬 뿐임
Figma는 DOM의 한계를 극복하려고 브라우저 안에 또 다른 브라우저를 만드는 방식으로 동작함 (참고: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/)
contenteditable만으로는 제품 수준 구현이 되지 않아 Google Docs가 자체 엔진을 만들었다면, 새 제안이 리치텍스트 레이아웃에 실질적으로 도움이 되기는 어려움
이 기능은 유용성이 크다고 생각하지만, HTML 안에서 Canvas 안에 HTML을 넣는 구조 자체가 뭔가 기묘하고 어울리지 않는 느낌이 듦
내가 생각하기에, 캔버스가 브라우저에서 독립적인 1급 포맷이 되어야 붙임성 있게 다뤄질 수 있다고 봄
그러면 HTML 중심의 페이지에 Canvas를 넣거나, 반대로 Canvas 중심에 HTML 요소가 들어가는 구조도 자연스러울 것임
물론 이건 내 생각일 뿐임
네 얘기에 전혀 이상함이 없음
참고로, 이미 HTML을 SVG 안, 다시 HTML 안 등으로 넣을 수 있음
만약 캔버스가 페이지의 최상위 요소라면, 페이지의 제목은 어디 저장하냐?
결국 <title> 태그를 써야 하니, 예시로
실질적으로 캐번스 태그 안에 콘텐츠가 들어갈 수 있게 만들면 심플하게 해결될 수 있음
캔버스 중심 웹사이트는 불편함이 많음
시스템 서비스(자동완성, 접근성 등) 전체를 사용할 수 없고, 개인정보 문제도 있음
예를 들어 시스템의 맞춤법 사전 교정 기능을 쓰기 어렵고, 시스템의 접근성도 제공하지 못해서 각 앱마다 전혀 다른 UI 접근성을 직접 구현해야 함
네가 말한 구조라면 플래시를 발명한 셈임
다만, 플래시를 웹에 넣는 것도 엄청난 고생이었음
HTML 페이지에 Canvas를 두고, 그 안의 텍스트에 레이아웃이나 스타일링을 추가하고 싶을 때가 있음
그렇다고 해서 전체 페이지 레이아웃 방식까지 바꾸는 건 불필요하게 복잡한 일임
이전에 사람들이 WASM의 DOM 접근에 반대한 적이 있었음
그래서 이런 방향성의 발전이 필연적이라고 봄
이제 우리는 브라우저 전체를 WASM으로 컴파일해서, 이 브라우저를 메인 브라우저의 캔버스 요소 안에서 돌리는 시점까지 온 것임
아예 OS 자체와 함께 IE까지 웹에서 실행하는 것도 가능함 (예시: https://copy.sh/v86/?profile=windows2000)
The Birth & Death of JavaScript라는 유명한 발표의 전제와 비슷함
참고: https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript
https://www.chromium.org/blink/blink-in-js/ 이런 시도도 있음
‘샌드박싱과 보안’ 이슈 때문에 이런 식 구조가 필수가 될 미래도 올 수 있음
참고로 https://trevorlinton.github.io에서 직접 비슷한 환경을 볼 수 있음
https://github.com/WICG/html-in-canvas/blob/main/security-privacy-questionnaire.md 에 보면
‘지문 수집(fingerprinting) 위험성’에 대해 더 추가해야 한다는 TODO가 있음
SVG의
foreignObject태그를 활용하면 이미 HTML-in-Canvas와 비슷한 결과를 얻을 수 있다는 생각임예를 들어 https://github.com/zumerlab/snapdom 처럼, DOM을 inlined style로 복사해서 SVG의 foreignObject 안에 넣고, 이를 캔버스로 렌더하는 프로젝트가 있음
게다가, 콘텐츠가 바뀔 때 캔버스를 자동으로 업데이트하거나, 상호작용성 등 새로운 기능도 지원함
혹시 내가 틀렸는지 모르겠지만, 순정 JS만으로도 캔버스 위에 HTML을 렌더링하는 건 충분히 가능하다고 느낌
캔버스는 HTML로 할 수 없는 걸 그릴 때 쓰는 것이고, DOM을 대체할 목적이 아닌 구조임
현재로서는 예를 들면
주석이 3D 모델 뒤에 가려져야 하는데, HTML만으로는 이 처리가 무척 힘들고, 복잡한 위치 계산과 프레임 지연 등 이슈가 있음
HTML 캔버스 위에 덧씌우면 전체 주석 요소를 한 번에 보여주거나 숨기는 정도 밖에 불가능했음
3D 텍스트나 SDF 방식 등 별도 렌더링 시스템을 만들면, 접근성도 빠지고 모든 것을 직접 다시 구현해야 했음
복잡한 UI(동영상, 리스트, 셀렉트박스 등)는 HTML로 다시 돌아가야 했음
HTML 요소가 캔버스 위 모든 것보다 앞에 있다면 괜찮지만, 그렇지 않은 경우엔 html 위에 또 캔버스를 깔아야 하고, z-레이어마다 반복작업임
이번 변화로 마침내 브라우저의 “역전된 렌더링 레이어 스택”을 고칠 수 있다고 봄
모든 브라우저 렌더링이 유니버설 캔버스 API 위에 쌓여야 한다고 생각함
곧 우리는 HTML-in-Canvas 안에서도 다시 Canvas 렌더링을 하는 일이 필요하지 않을까 싶은 생각이 듦
다만 순환 참조는 아니고, 진짜 순환되는 canvas를 원하면 부모 canvas 내용을 수동으로 자식 canvas에 그릴 필요가 있음
Pimp My Ride 밈이 떠오를 정도임
“형, 네가 HTML 좋아한다길래, 캔버스 안에 HTML을 넣어서 HTML 안에 또 캔버스를 넣어줬어”라는 느낌임
다음과 같이 body 엘리먼트에 플래그를 하나 주는 건 어떨까 생각이 듦
이러면 페이지 전체가 캔버스와 같은 드로잉 서피스가 되고, 평소처럼 DOM 요소를 렌더할 수 있음
내부적으로 DOM까지 래스터라이즈하는 과정을 오픈해주면 더 나을 것도 같음
아키텍처 상 DOM 렌더링과 캔버스 렌더링이 완전히 대등한 레이어가 됨
예를 들어 페이지에 선을 긋는 액션이 DOM 요소의 리플로우를 유도하거나 무시하도록 제어할 수도 있음
스크린리더가 모두 동시에 비명을 지를 상황이 떠오름
이 방식이면 캔버스가 자동으로 크기 조정도 가능해질 수 있는데, 만약 그렇다면 HTML 조합의 새로운 시대를 여는 것임
iframe을 뛰어넘을 수 있음
어색하긴 하지만 이번 제안에 찬성하는 편임
어떤 걸 그려야 할 때, 기존의 HTML 엘리먼트를 재활용할 일이 종종 있음
예전에는 그걸 오프스크린에서 비트맵으로 렌더링해서 캔버스에 복사하거나, z-index와 position absolute로 조정하려 해도 캔버스가 무조건 시각적으로 덮어버리는 문제가 있었음(최근엔 꽤 개선됨)
이 방식이 완벽한 해결은 아닐 수 있지만, 이전의 꼼수들보다는 한결 낫다고 생각함
딱 html2canvas처럼, 꼭 그렇게 해야 할 상황이면 쓸 만한 해법임