00:00:00지금의 인터넷에는 기발함이 더 필요하다고 생각해요. 특히 AI가
00:00:03웹사이트를 한 번에 뚝딱 만들어내는 요즘엔 더더욱 그렇죠.
00:00:05그럼 웹을 더 재미있게 만드는 게 더 쉬워진다면 어떨까요? 이렇게 말이죠. 걱정 마세요.
00:00:09여러분을 붙잡아두려는 건 아니에요. 그냥 이 웹사이트에서 장난을 좀 치는 것뿐이죠. 지금 보시면
00:00:13화면 아래쪽에 제 눈들이 잔뜩 보일 거예요. 그리고 그나저나,
00:00:17제가 구독 버튼을 누를 수 있다면, 여러분도 할 수 있어요.
00:00:18그 대신, 더 기능적이면서도 아름다운 상호작용을 사이트에 넣고 싶거나,
00:00:22구독 취소를 하려면 핀볼 게임을 해야 하는 새로운 다크 패턴을 만들고 싶을지도 모르죠. 아니면
00:00:27긴 하루 일과를 마치고 맥주 한 잔과 함께 컴퓨터 앞에 앉아,
00:00:30가상 컴퓨터 앞에 맥주를 들고 앉아 트위터를 둘러보고 싶을지도요. 이 모든 게
00:00:34HTML in Canvas 덕분에 가능합니다. 한번 알아볼까요?
00:00:43저는 최근 트위터에서 맷 로텐버그(Matt Rothenberg)님 덕분에 이걸 처음 알게 됐어요.
00:00:46그 게시물을 본 이후로 트위터에서 일주일 동안 아주 멋진
00:00:50데모들이 쏟아져 나오더라고요. 웨스 보스(Wes Boss)님도 이걸 시도하며 아주
00:00:54즐거워하는 모습을 봤고요. AA님이 올린 손가락 총 데모도 봤죠. 저희 두 사람의 데모가
00:00:58사실 제가 인트로에서 보여드린 유튜브 데모에 영감을 주기도 했어요. 그래서 제가 참고한 모든
00:01:02데모 출처는 더 보기란에 링크해 둘 테니 더 보고 싶으시면 확인해 보세요.
00:01:05자, 그럼 HTML in Canvas란 무엇일까요? 간단히 말해서, 실제 대화형
00:01:10DOM 요소를 WebGL이나 2D 캔버스에 바로 삽입할 수 있게 해주는 기술입니다. 현재는 제안 단계에 있고요.
00:01:15실제로 크롬 카나리(Chrome Canary)에 실험 기능으로 추가되었고, 최근에 데모들이
00:01:19많이 올라온 이유도 이 플래그를 활성화하면 크롬 카나리에서 직접 테스트해 볼 수 있기 때문입니다.
00:01:24그런데 왜 이걸 써야 하냐고요? 캔버스는 우리가 이미 본 것처럼 아주 멋진
00:01:28UI와 커스터마이징을 가능하게 해주기 때문입니다. CSS로는 하기 어렵거나 불가능한 일들이죠.
00:01:32하지만 캔버스는 복잡한 텍스트 레이아웃이나 HTML 콘텐츠를 쉽게 렌더링하지 못합니다.
00:01:38내부에서 처음부터 다시 구현해야 하는 경우가 많죠. 그래서 그동안 캔버스
00:01:42기반 콘텐츠는 접근성, 국제화, 성능, 품질 문제로 어려움을 겪어왔습니다.
00:01:47그런데 이런 문제는 HTML이 대부분 해결한 부분이죠. 그래서 HTML in Canvas는 두 가지의 장점을
00:01:51모두 취할 수 있는 최선의 방법입니다.
00:01:52작동 방식을 보여드리기 위해 직접 사용하는 데모를 보여드릴게요. 지금 제 앞에 있는 건
00:01:56AI가 이런 걸 단번에 만들기 전, 제가 몇 년 전에 만든 런던 지하철 시간표 사이트예요.
00:02:00항상 이 정보를 3JS 장면 안에 넣으면 멋지겠다고 생각했었거든요.
00:02:02물론 3JS로도 가능합니다. 3JS는 당연히 텍스트를 지원하니까요.
00:02:08하지만 HTML in Canvas를 사용해서 시간표 요소를 그대로 캔버스 내의
00:02:12장면에 넣는 편이 훨씬 쉽겠죠. 그래서 지금 보이는 토마스 기차 그림 대신,
00:02:16제 HTML을 보고 싶습니다. 그러려면 첫 번째 단계로
00:02:20장면에 실제로 렌더링하고 싶은 HTML을 가져와서
00:02:24캔버스 내부에 넣는 것입니다. 이게 방금 보신 게시판을 만든 HTML 코드예요.
00:02:28이걸 캔버스 자체의 자식 요소로 넣었습니다. 현재 이
00:02:32요소는 캔버스 폴백(fallback) 역할을 하고 있어요. 그래서 캔버스가 브라우저에서
00:02:36어떤 이유로든 로드되지 않으면, 사용자는 이 요소를 보게 될 겁니다. 하지만 이건
00:02:39우리가 원하는 게 아니죠. 해결 방법은 캔버스 요소에
00:02:44layout subtree 속성을 추가하는 것입니다. 이렇게 하면 브라우저는 캔버스의 자식 요소를
00:02:48실제 레이아웃 참여자로 처리합니다. 그래서 접근성 트리에도 포함되고, 포커스도
00:02:52받을 수 있지만, 화면에는 그려지지 않죠. 제 데모에서 보시는 것처럼
00:02:56아직 아무것도 표시되지 않아요. 요소가 화면 어디에도 보이지 않지만,
00:03:00요소 검사를 해보면 마우스를 올렸을 때 기술적으로
00:03:04렌더링되고 있다는 걸 알 수 있습니다. 단지 보이지 않을 뿐이죠. 캔버스에 실제로 렌더링하려면
00:03:08이걸 텍스처로 변환해서 토마스 기차 그림 대신 사용해야 합니다. 그리고
00:03:12그게 바로 이 함수로 하는 일입니다. 대부분은 3JS 코드라
00:03:15신경 쓰지 않으셔도 돼요. 첫 번째는 GL 텍스처를 가져오는 건데,
00:03:19현재는 그게 토마스 기차 그림이죠. 하지만 그 다음
00:03:22이 줄에서 HTML in Canvas의 textElementImage2D 함수를 사용하고 있습니다.
00:03:27복잡해 보이지만, 그냥 우리가 적용하려는 3JS 텍스처를 가져와서
00:03:30어떻게 렌더링할지 GPU를 위한 색 공간 같은 정보들을 제공할 뿐입니다.
00:03:34이런 세부 사항은 너무 걱정하지 않으셔도 됩니다.
00:03:38그리고 렌더링하고 싶은 HTML 요소도 제공하죠. 여기서는
00:03:42보드(board)입니다. 그건 document.getElementById를 사용해
00:03:45캔버스 안에 넣었던 요소를 가져오는 이 줄에서 간단히 처리됩니다. 이제 다시
00:03:49데모로 돌아오면, 보셨듯이 그림 대신 시간표가 들어갔고
00:03:53실시간으로 업데이트되고 있습니다. 시계도 움직이고 시간도 바뀌고 있네요. 이렇게
00:03:57HTML 요소를 사용하되 캔버스에는 텍스처로 제공되는 방식입니다. 이제
00:04:02요소 검사를 해보면, 보드에 해당하는 요소를 확인할 수 있는데
00:04:06여전히 보이지 않는 방식으로 렌더링되고 있죠. 이 방식은 근본적으로
00:04:09해당 요소가 무엇인지 확인하고, 스크린샷을 찍어서
00:04:14텍스처 자리에 배치하는 것과 같습니다. 그래서 요소가 다시 렌더링될 때마다 업데이트되죠.
00:04:19이 작업은 HTML 캔버스에서 페인트 이벤트가 발생할 때 처리되며
00:04:22캔버스의 자식 요소가 다시 렌더링되는 걸 감지해서 업데이트합니다. 물론
00:04:26requestAnimationFrame처럼 직접 다시 그리기를 요청할 수도 있습니다.
00:04:30여전히 좀 헷갈리신다면 GitHub에 있는 제안서를 꼭 확인해 보세요.
00:04:34정보와 데모가 아주 많거든요. 솔직히 말씀드리면 저는 3JS와 WebGL을 선택해서
00:04:38조금 더 복잡한 경로를 택했습니다. 하지만 가장
00:04:42기본적인 예를 보자면, 캔버스 안에 폼 요소 같은 걸 넣고
00:04:46그걸 캔버스에 렌더링하고 싶다면 context.drawElementImage라고 하고
00:04:49폼 요소와 위치를 지정해주기만 하면 됩니다. 그게
00:04:54HTML in Canvas의 가장 간단한 형태입니다. 그리고 이 데모도
00:04:58정말 재미있어서 빨리 보여드리고 싶네요. 이 데모는 WebGPU와 copyElementImage
00:05:02함수를 사용해서 젤리 슬라이더 아래에 div를 그리는 모습인데, 정말 재미있죠.
00:05:07더 멋진 점은 이 뒤에 여전히 입력 창이 있다는 겁니다.
00:05:11아주 멋진 커스텀 입력 창일 뿐이죠. 이런 게 바로 HTML in Canvas가 가능하게 만드는 것들입니다.
00:05:16물론 제안서에서 해결해야 할 단점들도 있습니다. 주요한 문제 중 하나는
00:05:19당연히 성능입니다. 아직은 좀 불안정하죠. 그리고 drawElementImage가
00:05:24DOM 상태보다 한 프레임 늦는 등의 버그도 있습니다. 이런 건 약간의
00:05:28시각적 동기화 어긋남을 초래하죠. 또 캔버스 자식 요소 안에 스크롤 바를 넣으면
00:05:32그냥 앱이 튕겨버린다고 합니다. 하지만 이런 문제들이 바로 실험적인 기능을 운영하는 이유이기도 하죠.
00:05:36제작자들도 정확히 이런 피드백을 기대하고 있습니다. 또한 개인정보 보호 문제도 있어서,
00:05:40이게 HTML 요소를 렌더링할 수 있다면, 평소 자바스크립트로 얻을 수 있는 것 이상의
00:05:44정보가 유출되는 건 막아야 합니다. 그래서 시스템 색상, 테마, 설정,
00:05:48맞춤법 및 문법 검사기 마커, 방문한 링크 정보 같은 민감한 정보는 제외하는
00:05:52개인정보 보호 페인팅 리스크를 두고 있습니다. 제 생각에 핵심적인 우려는
00:05:56핑거프린팅을 위한 또 다른 데이터 수집 경로가 추가되는 것을 피하려는 것 같습니다. 어쨌든,
00:06:00지금까지 본 모습은 아주 마음에 듭니다. 부디 이 기능이 실험 단계에서 벗어나 발전했으면 좋겠네요.
00:06:04여러분 생각은 어떠신가요? 댓글로 알려주시고, 구독도 잊지 마세요.
00:06:07그럼 늘 그렇듯, 다음 영상에서 뵙겠습니다.