웹 디자인 파이프라인 스킬과 이를 5개 에이전트에 설치하는 CLI 를 담은 모노레포. 스킬 (packages/skill) - SKILL.md 261줄 + 참조 문서 16개 3,349줄. progressive disclosure 로 본문은 절차와 인덱스만, 지식은 references/ 로 분리 - 0~6단계 파이프라인. 규모에 따라 전체·연장·국소 세 경로로 분기 - 하드 게이트 12개는 grep·카운트로 검증 가능한 것만. 취향 판단은 제외 - 미학 프리셋 5종, AI 슬롭 지문 목록, 한글 조판 규칙, SVG 필터·three.js·인터랙티브 모션·HTML-in-Canvas 실전 지침 설치 CLI (packages/cli, packages/core) - npx designpaca 온보딩 TUI. Claude Code · Codex · Cursor · Windsurf · AGENTS.md - 매니페스트에 설치 시점 해시를 기록해 사용자가 고친 파일은 update 가 건너뛴다 - 타깃별로 본문의 references/ 경로를 실제 설치 위치로 재작성 - AGENTS.md 는 항상 로드되므로 본문 대신 303자 포인터만 주입 - Windsurf 는 12,000자 상한 초과 시 설치를 차단 배포 (build/ci, .forgejo/workflows) - 태그 v* → 검사·테스트·빌드 → npmjs 배포 + Forgejo 레지스트리 미러 → draft 릴리스 → Cloudflare Pages. 재실행 멱등 근거 (research/) - 약 250개 웹 소스 조사 결과와 도그푸딩 검증 2건. 스킬의 모든 수치는 여기서 나온다 테스트 22개 통과 (core 16 · cli 6)
7 KiB
노마드코더 「이게 진짜 HTML이라고?」 분석
- URL: https://www.youtube.com/watch?v=8ucoskmA1yg
- 채널: 노마드 코더 Nomad Coders
- 주제: Chrome 신규 HTML in Canvas API
- 원문 자막:
transcript-ko.txt/ 압축본transcript-ko-compact.txt/ 영문nomad-html.en.srt
목차 (영상 챕터)
| 시간 | 내용 |
|---|---|
| 0:00–2:29 | 이게 진짜 HTML이라고? (데모 쇼케이스) |
| 2:30–2:50 | 왜 지금까지 불가능했을까? |
| 2:51–3:51 | HTML in Canvas는 어떻게 작동할까? |
| 3:52–6:02 | 직접 만들어보자 (반사 버튼 구현) |
| 6:03–6:37 | 아직 당장 쓸 수는 없다 |
핵심 주장
"웹사이트와 비디오 게임의 경계를 허무는 새로운 API" "2D 페이지라기보다는 비디오 게임이나 예술 설치 작품처럼 느껴지는 웹사이트"
기존의 딜레마: 캔버스는 다른 HTML 요소를 전혀 알지 못한다. 캔버스 안에 버튼을 그리려면 사각형+글자를 직접 그리고, 클릭 좌표를 히트테스트하고, 호버 시 다시 그려야 한다. 그렇게 해도 접근성·키보드 지원·CSS 스타일링이 전부 없는 "버튼 그림"일 뿐이다. → 픽셀(canvas)이냐 HTML이냐 둘 중 하나만 골라야 했다.
해결: 같은 요소가 DOM(상호작용)과 캔버스(픽셀)에 동시에 존재한다. 셰이더가 그 픽셀을 붙잡아 비틀고, 왜곡하고, 혼합하고, 3D 형태에 매핑한다. 접근성과 폼 동작은 DOM이 그대로 유지한다.
API 구조
⚠️ 영상이 쓰는 API 이름은 전부 구 명칭이다. 조사 결과 확정된 현재 이름으로 아래를 정정했다. 근거와 전체 스펙:
research/canvas/01-api-spec.md
<canvas layoutsubtree>속성 → 캔버스가 직계 자식 요소를 인식 (철자는 전부 소문자, IDL은layoutSubtree)- 그리고 싶은 HTML을 캔버스 자식으로 넣는다 (평범한 HTML/CSS 그대로)
ctx.drawElementImage(el, x, y)— 요소 + 좌표를 주면 실시간 복사본을 그 자리에 그린다- 이름 변천:
drawElement→drawHTMLElement→drawHTML→drawElementImage(2025-09-11 확정). 영상은 첫 이름을 쓴다
- 이름 변천:
- 반환값이 핵심: 그려진 위치를 나타내는
DOMMatrix를 돌려준다 → 그것을 요소의style.transform에 넣으면 실제 DOM 요소가 그려진 위치로 이동한다 → 클릭이 맞아떨어진다- 구 API의
setHitTestRegions()는 2025-11-08 폐기되고 이 방식으로 대체됐다 - 매 프레임 반영하지 않으면 클릭이 전부 어긋난다 — 이 API의 필수 계약이다
- 구 API의
- WebGL
gl.texElementImage2D(...)/ WebGPUdevice.queue.copyElementImageToTexture(...)- 2026-04~06에 두 시그니처 모두 바뀌어 Chrome 공식 블로그 예제조차 구버전이다. WICG 공식 데모도 try/catch 로 신·구 양쪽을 지원한다
- 캔버스 내부 HTML이 바뀔 때(포커스·호버 등)
paint이벤트 발생 → 듣고 다시 그린다 (중첩 시 역트리 순서)
보안 모델 — "read-back-allowed rendering"
캔버스 픽셀은 읽을 수 있으므로, 저자가 원래 볼 수 없던 것은 아예 그리지 않는다: cross-origin 콘텐츠, 시스템 색상, 맞춤법 마커, :visited(히스토리 스니핑 차단), 자동완성 미리보기, 서브픽셀 AA, IME 팝업. same-origin iframe은 그려진다.
데모 구현 흐름 (반사 버튼, JS 약 20줄)
매 프레임(rAF):
캔버스 clear
ctx.save()
translate(아래로) + 상하 반전 + globalAlpha 0.3
drawElement(button) ← 흐릿한 뒤집힌 반사
ctx.restore()
drawElement(button) ← 원본
반환된 변환값 → button.style.transform 에 적용 (히트박스 정렬)
requestAnimationFrame(render)
클릭 이벤트에서 클릭 좌표로 ripple() 호출 — 픽셀을 샘플링해 위치를 조정하는 건 기존 캔버스 연산이라 새로울 게 없다. 요점은 HTML이 일단 캔버스에 올라가면 무엇이든 할 수 있다는 것.
영상에 나온 데모들
- 3D 씬의 천 조각 위에 그려진 포트폴리오 — 찌르면 천이 실제처럼 반응하고 폼이 천에 녹아든다
- HTML
range입력 → 젤리 슬라이더 - 폼 제출 시 셰이더로 HTML이 왜곡되는 효과
- 라이트/다크 모드 전환 시 페이지가 타들어가는 애니메이션
- 웹에서 구현한 Apple Liquid Glass
한계
영상이 밝힌 것:
- Chrome Canary + 플래그 뒤에 있다 (
chrome://flags/#canvas-draw-element) - 아직 제안(proposal) 단계, 전부 초안
- API 시그니처와 기본 형태조차 바뀔 수 있다 — 실제로 조사 기간에만 4번 바뀌었다
- → "당장 내일 프로덕션에 투입할 것은 아니지만, 오늘 실험을 시작할 가치는 충분하다"
조사로 보강한 것 (영상이 말하지 않은 것):
- Origin Trial이 진행 중이다 (M148~M150, M154까지 연장 승인). OT 토큰을 등록하면 Chrome Stable 사용자에게도 동작한다 — 영상은 이 부분을 "플래그뿐"으로 축소해서 말한다. 다만 2026-10 초 만료 예정
- Firefox·Safari 모두 "No signal"(입장 미표명), WHATWG PR #11588은 2025-08 개설 후 여전히 미머지
- 실전 제약 둘: ① cross-origin iframe 미지원 ② 캔버스 안 콘텐츠는 컴포지터 스레드 스크롤/애니메이션을 잃고 JS에 묶인다 — Chrome은 캔버스 안에 스크롤 영역을 넣지 말고 캔버스 전체를 스크롤시키라고 명시
- three.js는 이미 정식 지원한다:
THREE.HTMLTexture(element)+InteractionManager, r184 포함(2026-04-10 머지), WebGL/WebGPU 렌더러 양쪽 - 폴백이 존재한다:
three-html-render폴리필(MIT)이 동일 API 표면을foreignObject로 제공하고 네이티브가 있으면 자동으로 fast path를 탄다. three.js 공식 예제가 이걸 쓴다
designpaca 에의 함의
- 이 API는 스킬의 "실험 레이어"에 넣는다 — 기본 경로가 되어선 안 된다. 프로덕션 기본값은 SVG 필터 + three.js. 단 조사 결과 위상이 조금 올라갔다: three.js
HTMLTexture(r184 정식) +three-html-render폴리필 조합이면 점진적 향상으로 오늘 쓸 수 있다. "쓰지 마라"가 아니라 **"폴백을 먼저 만들고, 그 위에 얹어라"**로 규칙을 정한다 - 폴백 필수: 미지원 브라우저에서 같은 인상을 주는 대안 경로를 항상 같이 설계한다 (
foreignObject폴리필, SVG displacement, backdrop-filter, CSS3DRenderer 등 — 비교표는research/canvas/04-fallbacks.md) - "DOM은 살려두고 픽셀만 왜곡한다"는 원칙은 이 API 없이도 유효하다 — 접근성을 포기하지 않고 화려함을 얻는 designpaca의 기본 철학으로 삼는다
- 영상의 문제의식("웹이 다시 재밌어질 수 있다", "플래시 시절처럼")이 곧 스킬의 방향성 — 안전하고 지루한 템플릿의 반대편