URL: https://www.youtube.com/watch?v=8ucoskmA1yg
날짜: 2026-08-20
채널: 노마드 코더 Nomad Coders
📌 핵심 질문 / HTML과 픽셀 캔버스는 한 화면에서 공존할 수 있는가
==HTML-in-Canvas API는 실제 DOM 요소의 상호작용성과 Canvas의 자유로운 픽셀 조작을 한 화면에 결합한다.==
- 버튼·입력·폼·웹페이지 전체를 Canvas 안에 실시간으로 그릴 수 있다.
- DOM에는 클릭·키보드 입력·접근성을 담당하는 실제 요소가 남고, Canvas에는 셰이더(shader)가 가공할 픽셀 복사본이 놓인다.
- 3D 천, 젤리 슬라이더, 페이지가 타는 전환, Apple Liquid Glass 같은 효과를 실제 HTML 요소에 적용할 수 있다.
2D 문서와 게임·아트 설치물 사이의 경계가 사라지지만, HTML-in-Canvas는 아직 Chrome Canary 플래그 뒤에서 동작하는 제안(proposal) 단계다. 즉시 프로덕션에 배포할 API는 아니며, 미래의 인터랙티브 웹을 실험하기 위한 기반으로 받아들여야 한다.
1. HTML-in-Canvas가 열어젖힌 인터랙티브 웹
HTML의 의미론적 요소가 Canvas의 시각 효과 속에서 살아 움직이면 웹페이지가 문서보다 게임이나 설치 미술에 가까운 경험이 된다.
1.1. 실제 HTML 요소를 3D 장면에 배치하기
-
포트폴리오 폼의 실재성
- 진짜 DOM 상호작용: 포트폴리오 페이지의 제목을 마우스로 선택할 수 있고, 일반 웹페이지의 텍스트처럼 드래그할 수 있다.
- 기능 보존: 버튼과 슬라이더가 작동하며, Canvas 안에서 클릭하고 그림을 그리고 텍스트 입력란에 글자를 쓸 수 있다.
-
천과 HTML의 결합
- 3D 천 위의 폼: 폼은 3D 장면 속 천 조각에 칠해지지만, 그 위에 보이는 UI는 실제 HTML이다.
- 물리적 반응: 천을 클릭하거나 찌르거나 쓰다듬으면 실제 천처럼 반응하고, 폼의 표면도 천의 변형을 따라 휘어진다.
- 충돌 처리: 캐릭터가 폼이 놓인 천으로 걸어 들어가면 평면 이미지처럼 통과하지 않고 바로 부딪힌다.
-
젤리 슬라이더
- 기존 입력의 재해석: HTML
range입력을 젤리처럼 휘고 늘어나는 슬라이더로 바꿀 수 있다. - 3D의 비필수성: API를 쓰기 위해 전체 웹사이트를 3D로 만들 필요는 없으며, 기존 2D 페이지에 시각 효과만 추가해도 된다.
- 기존 입력의 재해석: HTML
1.2. 기존 웹사이트에 셰이더 효과 입히기
-
입력과 제출 동작의 시각화
- 입력 보존: 화면에 보이는 입력란은 진짜 HTML 입력란이므로 사용자가 직접 타이핑할 수 있다.
- 제출 효과: 입력란이 Canvas 안에 있으므로 폼을 제출하는 순간 HTML 표면에 셰이더 효과를 적용할 수 있다.
-
일상적인 폼을 그래픽 장면으로 만들기
- 포커스 효과: 입력란이 포커스를 받을 때 생기는 효과, 움직이는 테두리, 빛나는 테두리는 Canvas에서 실행되는 셰이더가 만든다.
- HTML 왜곡: 폼을 제출하면 셰이더가 HTML 이미지를 왜곡해 평범한 폼을 시각적 이벤트로 바꾼다.
-
페이지 전환과 소재 표현
- 불타는 모드 전환: 라이트 모드와 다크 모드 사이를 전환할 때 페이지가 타서 사라지는 애니메이션을 만들 수 있다.
- Liquid Glass: 누군가 Apple의 Liquid Glass 스타일을 웹에서 재현했으며, 유리처럼 굴절·반사되는 표면을 HTML UI에 적용할 수 있다.
- 웹의 감각 변화: 결과물은 2D 문서보다 비디오 게임이나 아트 설치물처럼 느껴지는 웹이 된다.
2. 기존 Canvas와 HTML의 분리
Canvas는 픽셀을 완전히 통제하지만 HTML 요소의 의미와 동작을 알지 못한다. 이 분리가 지금까지 인터랙티브 그래픽과 접근 가능한 UI를 동시에 만들기 어렵게 했다.
2.1. Canvas가 제공하는 시각적 통제
-
픽셀 단위 조작
- Canvas의 역할:
<canvas>는 내부 픽셀을 직접 조작하는 HTML 요소다. - 사용 분야: 게임, 이미지 편집, 3D 장면처럼 순수한 시각적 통제가 필요한 작업에 사용한다.
- Canvas의 역할:
-
빠져 있던 연결고리
- HTML 인식 부재: 일반 Canvas는 다른 HTML 요소의 구조나 의미를 이해하지 못한다.
- 직접 삽입 불가: 버튼 요소를 Canvas 안으로 끌어다 놓는 방식으로 넣을 수 없으며, Canvas는 그 버튼이 존재한다는 사실 자체를 알지 못한다.
2.2. 버튼 하나를 가짜로 그릴 때 발생하는 비용
-
수동 렌더링
- 모양 그리기: 버튼의 사각형과 텍스트를 픽셀로 직접 칠해야 한다.
- 좌표 기반 클릭 판정: Canvas 전체에 클릭 리스너를 붙이고, 클릭 좌표가 버튼 영역 안에 들어왔는지 직접 검사해야 한다.
-
호버와 상태 관리의 중복
- 두 번째 히트 테스트: 마우스가 버튼 위에 올라왔는지 알아내기 위해 같은 좌표 판정을 다시 수행해야 한다.
- 수동 재렌더링: 호버 상태가 바뀌면 버튼을 다른 색으로 다시 그려야 한다.
-
의미론적 기능의 상실
- 접근성 부재: 화면에 버튼처럼 보이는 그림이 있을 뿐, 실제 버튼의 접근성(Accessibility) 의미가 없다.
- 키보드 지원 부재: 키보드 포커스와 입력을 자동으로 받을 수 없다.
- CSS 부재: CSS 스타일링, 브라우저가 제공하는 폼 동작, 실제 DOM 요소의 기능을 모두 잃는다.
-
페이지 규모에서의 붕괴
- 요소 수의 증가: 버튼 하나가 아니라 모든 버튼, 입력란, 폼, 전체 인터페이스를 같은 방식으로 구현해야 한다.
- 양자택일의 역사: 개발자는 오랫동안 픽셀로 가득한 Canvas와 HTML로 가득한 웹페이지 중 하나를 선택해야 했으며, 둘을 동시에 사용할 수 없었다.
3. HTML-in-Canvas API의 핵심 구조
HTML-in-Canvas는 한 요소를 DOM과 Canvas라는 두 위치에 동시에 존재하게 해 상호작용과 픽셀 가공을 분리한다.
3.1. 하나의 HTML, 두 개의 표현
-
DOM에 남는 실제 요소
- 상호작용 담당: DOM에는 사용자가 클릭할 수 있는 실제 버튼과 타이핑할 수 있는 실제 입력란이 남는다.
- 브라우저 기능 유지: 포커스·호버·키보드·접근성처럼 브라우저가 DOM에 제공하는 기능을 계속 사용할 수 있다.
-
Canvas에 놓이는 픽셀 복사본
- 그래픽 담당: 같은 요소의 렌더링 결과가 Canvas에 픽셀로 그려진다.
- 셰이더 가공: 셰이더는 그 픽셀을 집어 비틀고(distort), 뒤섞고(blend), 변형하고, 3D 형태 위에 매핑할 수 있다.
-
두 복사본의 의미
- 접촉 가능한 복사본: DOM 복사본은 사용자가 만지고 입력하는 대상이다.
- 칠할 수 있는 복사본: Canvas 복사본은 셰이더와 그래픽 코드가 마음대로 가공하는 대상이다.
- 동일 요소의 동기화: 두 복사본은 서로 다른 UI를 만드는 것이 아니라 같은 HTML 요소의 상호작용 상태와 시각 표현을 연결한다.
3.2. 최소 API와 렌더링 경로
-
Canvas 옵트인
layoutsubtree속성: Canvas에layoutsubtree속성을 추가해 자식 HTML을 레이아웃 트리의 일부로 받아들이도록 한다.- 자식 배치: 그린 뒤 싶은 HTML을 Canvas 안에 자식 요소로 넣는다.
-
2D Canvas 경로
drawElementImage()호출: Canvas의 2D 컨텍스트에서drawElementImage(element, x, y)를 호출해 요소와 좌표를 전달한다.- 라이브 복사본: Canvas는 해당 위치에 HTML 요소의 살아 있는 렌더링 복사본을 그린다.
-
GPU 경로
- WebGL: WebGL에서는
texElementImage2D()가 DOM 요소를 텍스처 소스로 받아texImage2D()와 비슷한 방식으로 GPU 텍스처에 올린다. - WebGPU: WebGPU에서는
copyElementImageToTexture()가 HTML 렌더링을 GPU 텍스처로 복사한다. - 공통 원리: 2D Canvas에 직접 그리는 대신 HTML을 GPU 텍스처로 공급한다는 차이만 있으며, HTML을 픽셀 파이프라인에 넣는다는 원리는 같다.
- WebGL: WebGL에서는
-
상태 변경 통지
paint이벤트: Canvas 안의 HTML이 바뀌면 Canvas가paint이벤트를 발생시킨다.- 변경 사례: 입력란이 포커스를 받거나 버튼에 마우스가 올라가는 상태 변화가 이벤트를 발생시킨다.
- 이벤트 처리: 개발자는 이벤트 핸들러에서 HTML을 다시 칠하거나, 셰이더로 왜곡하거나, 3D 형상에 감싸는 작업을 수행한다.
4. 실제 구현: 반사 효과가 있는 클릭 가능한 버튼
DOM 버튼은 상호작용을 유지하고, Canvas는 같은 버튼의 반사 이미지를 그린다. 이 구조는 HTML-in-Canvas의 동기화 문제와 해결책을 짧은 예제로 보여준다.
4.1. HTML과 CSS 구성
-
Canvas 내부의 버튼
- 구조: Canvas 안에 버튼을 자식으로 넣고 Canvas에
layoutsubtree속성을 지정한다. - 버튼의 정체성: 버튼은 Canvas 전용 객체가 아니라 평범한 HTML 버튼이다.
- 구조: Canvas 안에 버튼을 자식으로 넣고 Canvas에
-
기본 스타일과 상태
- 기본 모습: CSS로 분홍색(pink) 둥근 버튼을 만든다.
- 호버 상태: 마우스를 올리면 보라색(purple)으로 바뀌고 조금 커진다.
- 클릭 상태: 클릭하면 살짝 작아진다.
4.2. 초당 60회 렌더 루프
-
렌더링에 필요한 값
- 객체 참조: JavaScript가 Canvas, 그릴 때 사용하는 브러시인
context, 버튼을 가져온다. - 좌표와 크기: 버튼을 Canvas에 배치할
X,Y와 버튼 높이H를 저장한다.
- 객체 참조: JavaScript가 Canvas, 그릴 때 사용하는 브러시인
-
프레임 초기화
- 초당 60회 호출:
render함수는 초당 60번 호출된다. - Canvas 지우기: 매 프레임 Canvas 전체를 지운다. 지우지 않으면 이전 프레임의 그림이 계속 쌓인다.
- 초당 60회 호출:
-
반사본 그리기
- 컨텍스트 저장: 브러시의 현재 상태를 저장한다.
- 변환 적용: 그릴 내용을 아래로 이동하고, 위아래를 뒤집고, 불투명도를 30%로 낮춘다.
- 버튼 스탬프: 변환된 브러시로 버튼을 Canvas에 찍어 흐리고 거꾸로 된 반사본을 만든다.
-
원본 그리기
- 상태 복원: 저장한 브러시 상태로 돌아가 이동·반전·투명도 변경을 모두 해제한다.
- 두 번째 스탬프: 정상 브러시로 버튼을 다시 찍는다. 사용자가 눈으로 보고 클릭하는 버튼은 이 정상 복사본이다.
4.3. 보이는 버튼과 실제 버튼의 위치 동기화
-
이중 존재로 생기는 문제
- Canvas 위치: 버튼은 방금 픽셀로 그려진 Canvas 안에 있다.
- DOM 위치: 브라우저는 실제 클릭 가능한 버튼을 DOM 안에 보이지 않는 상태로 유지한다.
- 좌표 불일치: 브라우저는 Canvas에 버튼을 어느 위치에 그렸는지 자동으로 알지 못하므로, 사용자가 보이는 버튼을 클릭해도 다른 곳에 있는 실제 버튼을 놓칠 수 있다.
-
drawElementImage()의 반환값 활용- 배치 수학:
drawElementImage()는 요소를 그린 위치를 나타내는 변환 수학값을 돌려준다. - DOM 변환 적용: 그 값을 버튼의
style.transform에 전달해 보이지 않는 DOM 버튼을 Canvas에 칠한 버튼과 같은 위치로 이동한다. - 클릭 일치: 두 위치가 맞아지면 사용자가 보는 픽셀 버튼의 클릭이 실제 DOM 버튼에 정확히 도달한다.
- 배치 수학:
-
다음 프레임 예약
- 반복 호출: 브라우저에 다음 프레임에서
render를 다시 호출하도록 요청한다. - 재생 비유: 이 동작은 영상의 재생 버튼을 누르는 것처럼 매 프레임 최신 상태를 다시 그리는 과정이다.
- 반복 호출: 브라우저에 다음 프레임에서
-
구현 규모
- 동일 요소의 두 렌더링: 같은 HTML 요소를 Canvas에 두 번 칠한다. 한 번은 30% 투명도의 반사본, 한 번은 사용자가 클릭할 정상본이다.
- 짧은 코드: 두 복사본이 모두 살아 있는 상태를 약 20줄의 JavaScript로 구현할 수 있다.
5. Canvas 픽셀을 소유한다는 것
HTML이 Canvas 위에 올라온 순간부터 그 HTML의 픽셀은 일반 DOM 이미지와 달리 그래픽 코드가 직접 가공할 수 있는 재료가 된다.
5.1. 클릭 리플 효과
-
이벤트 연결
- 클릭 감지: 버튼의 클릭 이벤트를 듣는다.
- 좌표 전달: 클릭 이벤트가 발생하면 클릭 좌표와 함께
ripple함수를 호출한다.
-
고전적인 Canvas 수학
- 픽셀 샘플링: 리플 함수는 픽셀을 샘플링한다.
- 픽셀 이동: 샘플링한 픽셀을 주변으로 이동해 물결이 번지는 것처럼 보이게 한다.
- 새 API와의 구분: 픽셀 샘플링과 이동 자체는 새로운 API가 아니라 고전적인 Canvas 수학이다.
-
AI의 역할
- 구현 보조: 리플 함수처럼 픽셀을 샘플링하고 옮기는 그래픽 수학은 AI가 코드 작성을 도울 수 있는 부분이다.
- 핵심 변화: 새로 생긴 가능성은 리플 알고리즘이 아니라, 원래 HTML이었던 버튼의 픽셀을 Canvas가 가공할 수 있게 된 사실이다.
6. 현재 상태와 웹의 향방
HTML-in-Canvas는 강력한 시각 실험을 가능하게 하지만 아직 사양과 구현이 확정되지 않았다.
6.1. 프로덕션 도입 전의 제약
-
브라우저 플래그 의존
- Chrome Canary 전용 실험: API는 아직 프로덕션 준비가 끝나지 않았으며 Chrome Canary의 플래그 뒤에 있다.
- 사용자 설정 필요: API를 시험하려면 브라우저에서 해당 플래그를 직접 활성화해야 한다.
-
제안 단계의 변동성
- 아직 초안: 현재 보이는 기능 전체가 draft다.
- 시그니처 변경 가능성: 메서드 시그니처뿐 아니라 API의 기본 형태 자체가 바뀔 수 있다.
- 배포 판단: 내일 바로 프로덕션에 배포할 기능은 아니지만, 오늘부터 실험해볼 가치는 충분하다.
6.2. Flash 이후의 웹에 대한 기대
-
실험에서 제품으로
- 표준화 기대: API가 실제 브라우저 기능으로 출시되면 의미론적 HTML과 GPU 기반 시각 효과를 함께 사용하는 웹앱이 쉬워진다.
- 경험의 확장: 폼·입력란·버튼이 문서의 고정된 UI를 넘어 물리적 소재, 3D 오브젝트, 셰이더 표면이 될 수 있다.
-
웹의 재미 회복
- Flash 시대의 비유: 웹이 예전 Flash 시절처럼 다시 재미있어질 수 있다는 기대가 제시된다.
- 새로운 기본 단위: 웹페이지의 기본 단위가 정적인 2D 페이지에서 반응하는 장면(scene)과 설치물로 확장될 수 있다.
- 남은 과제: 브라우저 간 지원, API 사양 안정화, 성능·접근성·입력 동기화를 해결해야 이 비전이 실제 서비스로 이어진다.
주요 발언 모음
“웹사이트는 곧 미쳐버릴 것이다.”
“HTML은 이제 DOM과 Canvas에 동시에 존재한다. 하나는 만질 수 있고, 하나는 칠할 수 있다.”
“HTML이 Canvas 위에 올라가면 그 픽셀로 무엇이든 할 수 있다.”
“프로덕션에 내일 바로 배포할 것은 아니지만, 오늘부터 실험해볼 것은 분명하다.”
“이 기능이 실제로 출시되어 Flash 시절처럼 웹을 다시 재미있게 만들면 좋겠다.”
핵심 데이터 & 수치
- 398초: 처리 대상 영상의 길이다.
- 초당 60회: 버튼 반사 데모의
render호출 빈도다. - 30% 불투명도: 반사본을 흐리게 보이게 하는 Canvas 상태값이다.
- 약 20줄: 클릭 가능한 HTML 버튼을 두 번 렌더링하고 위치를 동기화하는 JavaScript 구현 규모다.
- 세 가지 렌더링 경로: 2D Canvas의
drawElementImage(), WebGL의texElementImage2D(), WebGPU의copyElementImageToTexture()가 HTML을 픽셀·텍스처 파이프라인으로 전달한다. - Chrome Canary 플래그: 현재 API를 시험하기 위해 필요한 실험적 브라우저 설정이다.
결론 및 시사점
- HTML-in-Canvas는 의미론적 DOM과 자유로운 픽셀 조작이라는 기존의 양자택일을 하나의 렌더링 구조로 합친다.
- 접근성·키보드 입력·CSS·폼 동작은 DOM의 실제 요소에 맡기고, 왜곡·반사·물리 시뮬레이션·3D 매핑은 Canvas와 셰이더에 맡기는 분업이 핵심이다.
layoutsubtree로 Canvas 자식을 옵트인하고drawElementImage()또는 GPU 대응 메서드로 그리면 HTML을 그래픽 파이프라인에 넣을 수 있다.paint이벤트와 DOM 변환 동기화를 함께 처리해야 포커스·호버·클릭 상태가 보이는 픽셀과 실제 요소에서 어긋나지 않는다.- 현재는 Chrome Canary의 플래그와 변경 가능한 제안 사양에 의존하므로 실서비스 도입보다 작은 프로토타입과 인터랙션 실험에 적합하다.
- 표준화가 진행되면 웹은 문서를 넘어 게임·아트 설치물·물리적 장면처럼 반응하는 인터랙티브 매체로 확장될 수 있다.
핵심 요약 (20줄)
HTML-in-Canvas API는 실제 HTML 요소를 Canvas 안에 실시간으로 그리게 한다. DOM의 버튼과 입력란은 상호작용을 유지하고 Canvas의 픽셀 복사본은 시각 효과를 담당한다. 포트폴리오 폼의 제목은 마우스로 선택할 수 있고 버튼·슬라이더·텍스트 입력도 그대로 작동한다. 실제 폼은 3D 천 위에서 천의 변형을 따라 휘어지고 캐릭터의 충돌 대상이 될 수 있다. HTML range 입력은 젤리처럼 휘고 늘어나는 슬라이더로 표현할 수 있다. 전체 화면을 3D로 만들지 않아도 기존 웹사이트의 입력과 폼에 셰이더 효과를 입힐 수 있다. 포커스 테두리·빛나는 효과와 라이트 모드·다크 모드 전환 때 페이지가 타서 사라지는 애니메이션은 Canvas 셰이더로 실제 HTML에 적용할 수 있다. Apple Liquid Glass 같은 굴절형 표면을 웹 UI에 구현하면 페이지가 게임이나 설치물처럼 느껴진다. 기존 Canvas는 픽셀은 조작하지만 다른 HTML 요소의 의미와 동작은 이해하지 못한다. 가짜 Canvas 버튼은 클릭 좌표와 호버 판정을 직접 관리해야 하며 접근성·키보드·CSS를 잃는다. HTML-in-Canvas는 같은 요소를 DOM의 실제 객체와 Canvas의 픽셀 복사본으로 함께 유지한다. Canvas는 layoutsubtree 속성으로 자식 HTML을 레이아웃 대상으로 받아들인다. 2D 컨텍스트의 drawElementImage는 HTML 요소를 지정한 좌표에 라이브 복사본으로 그린다. WebGL은 texElementImage2D를 사용하고 WebGPU는 copyElementImageToTexture로 HTML을 GPU 텍스처에 넣는다. HTML의 포커스나 호버가 바뀌면 paint 이벤트가 발생해 다시 그리거나 셰이더를 적용할 수 있다. 반사 버튼 예제는 Canvas를 매 프레임 지우고 30% 불투명도로 뒤집은 버튼을 먼저 그린다. drawElementImage가 반환한 변환값을 DOM 버튼의 style.transform에 적용하면 보이는 클릭 영역과 실제 버튼이 맞는다. 같은 요소를 반사본과 정상본으로 두 번 그리는 전체 JavaScript 구현은 약 20줄이다. 클릭 좌표에 픽셀을 샘플링하고 이동하는 고전적인 Canvas 수학으로 버튼에 리플 효과를 추가할 수 있다. API는 아직 Chrome Canary 플래그 뒤의 초안이지만 Flash 시대처럼 재미있는 웹을 만들기 위해 지금 실험할 가치가 있다.
