Hacker News

The HTML-in-Canvas API origin trial

HTML-in-Canvas API 오리진 트라이얼

Chrome의 실험 기능 HTML-in-Canvas API가 오리진 트라이얼로 공개됐습니다. DOM 요소를 2D 캔버스나 WebGL·WebGPU 텍스처에 그리면서 선택, 입력, 접근성 같은 브라우저 기능을 유지합니다. 다만 렌더링과 스크롤은 JavaScript 실행에 의존합니다.

에디터 노트

DOM의 입력과 텍스트 기능을 GPU 장면에 가져오는 필요성은 게임 개발자의 경험담에서도 확인됩니다. 기존 Canvas 구현은 패널마다 텍스트와 상호작용을 직접 처리해야 했고, 라이브러리로 해결하려면 브라우저의 텍스트 배치 기능을 다시 만들어야 한다는 반론도 설득력 있습니다. 다만 API가 보장하는 기능은 요소를 텍스처로 그리는 일과 DOM 위치를 화면에 맞추는 일입니다. 3D 장면에서 가림이나 곡면 변형이 어떻게 처리되는지는 글의 일반적인 MVP 예시만으로 판단하기 어렵고, 댓글에서도 이를 의문으로 제기합니다. 또한 스크롤과 애니메이션은 JavaScript 실행에 묶입니다. 방문 링크 정보 유출 문제는 댓글에서 제안서의 `read-back-allowed` 설계를 근거로 답했지만, 블로그 본문은 세부 보안 조건을 설명하지 않습니다.

AI 요약

DOM의 텍스트 배치와 접근성 기능은 편리하지만 복잡한 2D·3D 화면을 직접 다루기 어렵습니다. 반대로 Canvas와 WebGL·WebGPU는 픽셀 단위의 렌더링을 지원하지만, 텍스트 선택과 폼 입력, 브라우저 접근성 기능을 구현하려면 별도 작업이 필요합니다. HTML-in-Canvas API는 DOM 요소를 캔버스 안에 그려 두 방식을 결합합니다. 요소는 화면에 그린 뒤에도 실제 DOM으로 남아 상호작용을 처리합니다.

API 사용 절차

Chrome 148~150 오리진 트라이얼 기능이며, 테스트하려면 Chrome Canary 149 이상에서 chrome://flags/#canvas-draw-element 플래그를 켜거나 사이트를 오리진 트라이얼에 등록해야 합니다. 먼저 <canvas>에 layoutsubtree 속성을 지정해 브라우저가 자식 요소를 캔버스 안에서 배치하고 접근성 트리에 노출하도록 합니다. 캔버스의 픽셀 크기는 ResizeObserver의 devicePixelContentBoxSize를 이용해 기기 픽셀 비율에 맞춥니다. 지원하지 않는 환경에서는 CSS 크기에 devicePixelRatio를 곱해 설정합니다.

2D Canvas에서는 drawElementImage(element, x, y)로 요소를 그립니다. 이 호출은 paint 이벤트에서 수행하며, 텍스트 선택이나 입력 등 요소가 다시 그려질 때 갱신합니다. 반환된 변환 행렬을 요소의 style.transform에 지정해야 브라우저가 실제 화면의 위치와 이벤트 영역을 맞출 수 있습니다. WebGL에서는 texElementImage2D로 DOM 요소를 텍스처 소스로 사용하고, WebGPU에서는 큐의 copyElementImageToTexture를 씁니다.

WebGL·WebGPU는 셰이더에서 텍스처를 배치하므로 캔버스 렌더링 문맥만으로 요소의 화면 좌표를 알 수 없습니다. 글에서는 일반적인 모델·뷰·투영(Model-View-Projection, MVP) 행렬을 사용하는 경우의 계산 방법을 제시합니다. HTML 요소의 픽셀 크기를 단위 정사각형으로 정규화하고, 캔버스 뷰포트 크기에 맞춰 변환한 뒤 MVP 행렬과 결합합니다. getElementTransform()에 이 변환을 전달해 얻은 결과를 요소의 CSS 변환에 적용합니다. Three.js는 실험적인 THREE.HTMLTexture를, PlayCanvas는 텍스처 API를 통한 지원을 제공합니다.

활용 사례와 제약

예시로는 HTML 텍스트를 페이지에 쓰는 3D 책, 입력 컨트롤을 포함한 WebGPU 장면, 애니메이션 SVG를 사용하는 WebGL 텍스처가 소개됩니다. DOM 기반 콘텐츠라 텍스트 선택과 복사, 브라우저 번역, 화면 내 검색, 접근성 도구, 확장 프로그램, 개발자 도구 검사 기능을 활용할 수 있습니다. 글은 검색 엔진과 AI 에이전트가 장면 안의 텍스트를 읽을 수 있다는 점도 장점으로 듭니다.

교차 출처 iframe 콘텐츠는 보안과 개인정보 보호 이유로 지원하지 않습니다. HTML-in-Canvas의 렌더링은 JavaScript가 담당하므로 스크롤과 애니메이션이 JavaScript 실행과 독립적으로 갱신되지 않습니다. 따라서 스크롤 콘텐츠를 캔버스 안에 넣을지, 캔버스 전체를 스크롤할지 성능 특성을 고려해야 합니다.

Hacker News 반응

  • @avaer — WebVR 시절에는 보안 문제 때문에 불가능하다는 분위기였는데, Chrome이 왜 입장을 바꿨는지 궁금합니다. 이 기능에 의존하는 Google의 제품이 있나요?
    • @thomasikzelf — 렌더링한 <a>의 픽셀을 읽어 방문한 링크 정보를 유출할 수 있는 문제와 관련이 있었습니다. read-back-allowed rendering이라는 개념으로 해결했습니다.
    • @bawolff — 보안은 대개 된다, 안 된다의 문제가 아니라 안전한 방법을 찾는 데 얼마나 투자하느냐의 문제입니다. 사업적 이유가 있는 기능에 Chrome이 더 많은 자원을 쓰는 건 놀랍지 않습니다.
  • @dvh — HTML 요소에 Canvas를 추가하는 편이 더 논리적이지 않나요? 예를 들어 checkbox.getContext("2d").fillRect(...)처럼요.
    • @aroman — 그런 용도도 있겠지만 웹 게임 개발자에게는 큰 도움이 되지 않을 것 같습니다. 진짜 장점은 입력과 텍스트 렌더링입니다.
    • @azangru — 3D 객체의 모양에 HTML을 맞춰야 한다면 그렇지 않습니다. 말씀한 방식은 CSS Painting API와 관련이 있습니다.
  • @artpar — HTML만으로 패널 50개 정도를 구현했을 때 반응성이 떨어져 Canvas로 다시 만들었습니다. 1,000개가 넘는 패널도 60fps 이상으로 처리했지만 각 패널을 직접 구현해야 해 복잡도가 커졌습니다. HTML-in-Canvas로 다시 시도하고 싶지만 API가 유지될지 걱정됩니다.
  • @hackyhacky — 브라우저 기능을 계속 늘리는 건 잘못된 방향이라고 봅니다. 이 문제는 라이브러리로 풀어야 하며, Chrome이 Firefox와의 기능 격차를 키우려고 웹 API를 확장하는 것처럼 보입니다.
    • @hollowturtle — 라이브러리로 해결하려면 언어별 텍스트 배치와 입력을 포함해 별도의 브라우저 엔진을 구현해야 합니다. JavaScript에서 Skia 텍스트 배치 API를 제공하는 편이 낫다고 봅니다.
    • @paavohtl — JavaScript나 WASM으로 브라우저 엔진을 사실상 새로 만들지 않고서는 라이브러리로 해결하기 어렵습니다. 브라우저 엔진에서 처리하는 편이 훨씬 단순합니다.
  • @unconed — 이 API가 제공하는 기능은 장식 목적의 사용 사례에 치우쳐 있습니다. 곡면 요소는 평면 투영으로 근사하라는 답을 들었고, 텍스트 선택 표시가 마스크에 들어가면 텍스트가 읽기 어려워지는 문제도 있습니다.
    • @TazeTSchnitzel — 캔버스 위에 position:absolute 요소를 띄우는 방식으로 할 수 없는 일이 무엇인지 잘 모르겠습니다. 입력 처리를 제어하지 못하고 가림도 제대로 되는지 의문입니다.
  • @mrec — DOM 링크를 캔버스에 그린 뒤 픽셀에서 방문 여부에 따른 색을 읽는 개인정보 유출을 어떻게 막나요?
    • @adzm — 제안서에 read-back-allowed 관련 내용이 있습니다.
  • @Ian_Macharia — AI 모션 그래픽·영상 생성기를 만들고 있는데 HTML과 Canvas가 잘 맞지 않는 점이 큰 제약입니다. 이 API가 웹에서 After Effects 수준의 기능을 구현하는 데 필요한 마지막 요소라고 생각합니다.
  • @vollbrecht — HTML-in-Canvas 안에 HTML-in-Canvas를 다시 넣는 재귀 사용도 가능한가요?

원문: Chrome for Developers / 번역·요약: Trawling