HTML을 2D 캔버스로 렌더링

HTML-in-Canvas API를 사용하면 상호작용이 가능하고 접근성이 우수한 DOM 하위 트리를 2D 캔버스 컨텍스트에 직접 렌더링할 수 있습니다. HTML-in-Canvas 개요를 읽고 API와 API의 이점에 대해 자세히 알아보세요.

이 가이드에서는 HTML을 2D 캔버스로 렌더링하는 방법을 보여줍니다. 2D 캔버스에서 HTML을 렌더링하려면 다음 단계를 따르세요.

  1. 캔버스를 준비합니다. 브라우저가 HTML을 캔버스에 렌더링해야 한다는 것을 알 수 있도록 올바른 속성을 선언적으로 설정합니다. 이 설정은 2D, WebGL, WebGPU 컨텍스트에서 동일합니다. 캔버스를 설정하는 방법과 독립적으로 그려질 HTML 요소를 선언하는 방법을 알아보세요.
  2. 요소 이미지를 캔버스에 그립니다.
  3. [선택사항] DOM과 픽셀을 동기화합니다.

2D 캔버스에 HTML 요소 그리기

캔버스가 준비되고 요소가 drawable로 표시되면 drawElementImage() 메서드를 사용하여 2D 컨텍스트로 렌더링합니다.

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const childElement1 = document.getElementById("childElement1");
const childElement2 = document.getElementById("childElement2");

canvas.onpaint = () => {
  ctx.reset();
  // 1. Draw the primary element at coordinate (20, 20)
  ctx.drawElementImage(childElement1, 20, 20);
  // 2. Draw the secondary nested button at a custom offset
  ctx.drawElementImage(childElement2, 40, 90);
}

drawElementImage()는 인수 3개, 인수 5개, 인수 7개, 인수 9개 형식을 지원하며 선택적 options 매개변수를 허용합니다.

// 1. Basic position: (element, dx, dy, options?)
ctx.drawElementImage(targetElement, 100, 150);

// 2. Scaled / resized: (element, dx, dy, dWidth, dHeight, options?)
ctx.drawElementImage(targetElement, 100, 150, 180, 60);

// 3. Cropped, default size: (element, sx, sy, swidth, sheight, dx, dy, options?)
ctx.drawElementImage(targetElement, 0, 0, 90, 30, 100, 150);

// 4. Cropped and resized: (element, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, options?)
ctx.drawElementImage(targetElement, 0, 0, 90, 30, 100, 150, 180, 60);
과부하 양식 매개변수 레이아웃 효과
기본 크기 (element, dx, dy) 기본 크기의 전체 요소로, 왼쪽 상단이 (dx, dy)에 있습니다.
맞춤 대상 유형 상자 (element, dx, dy, dwidth, dheight) 전체 요소 이미지를 캔버스의 dw × dh 표시 영역으로 조정합니다.
잘림, 기본 크기 (element, sx, sy, swidth, sheight, dx, dy) (sx, sy)에서 시작하는 swidth × sheight 영역만 해당 영역의 기본 크기 (기본 크기 양식과 동일한 배율)로 그려집니다.
소스 슬라이스에서 대상으로 (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) (sx, sy)에서 시작하는 소스 요소를 swidth × sheight 크기로 자른 다음 대상 (dx, dy, dwidth, dheight)에 매핑합니다.

DOM 및 픽셀 동기화

DOM 레이아웃과 CSS 스타일 지정은 반응형이지만 <canvas> 렌더링은 필수이므로 브라우저에는 렌더링된 캔버스 픽셀, 대화형 Hit Test 영역, 접근성 트리를 동기화된 상태로 유지하는 메커니즘이 필요합니다. DOM과 픽셀을 동기화하는 방법을 알아보기 전에 DOM 요소가 업데이트되고 다시 그려야 할 때 트리거되는 paint 이벤트를 이해해야 합니다.

2D 캔버스 컨텍스트에서 브라우저는 요소의 레이아웃 좌표, 접근성 경계, 포인터 Hit Test를 그려진 캔버스 좌표와 자동으로 동기화합니다.

요소 도형 수동 업데이트

고급 시나리오에서는 자동 도형 동기화를 선택 해제하고 공간 변환을 수동으로 제어할 수 있습니다. { preserveElementGeometry: true }를 drawElementImage()에 전달하여 브라우저가 요소의 기존 Hit Test 좌표를 자동으로 재정의하지 않도록 합니다.

// 1. Draw the element without altering its existing hit-test bounds
ctx.drawElementImage(targetElement, elementX, 200, { preserveElementGeometry: true });

// 2. Construct a custom transform matrix as needed,
// assuming scaleX/scaleY = canvas grid pixels per CSS pixel,
// from your resize observer (see "Units and sizing").
const currentTransform = new DOMMatrix();
currentTransform.a = 1.5;          // scale X
currentTransform.e = x / scaleX;   // translate X: grid px → CSS px
currentTransform.f = y / scaleY;   // translate Y: grid px → CSS px

// 3. Explicitly apply the custom transform
canvas.updateElementGeometry(targetElement, { canvasTransform: currentTransform });
2D에서 drawElementImage()는 이 도형을 자동으로 업데이트합니다. 이 데모에서는 { preserveElementGeometry: true }가 설정될 때 도형이 동기화되지 않는 방식을 보여줍니다.

다음 단계