Communitygithub.com

Washing Line Hero

브랜드 포스터가 나무 빨래집게로 빨랫줄에 고정된 면 천에 인쇄되고, 구름이 떠다니는 열린 하늘 아래에서 방문자가 포인터로 천을 살짝 누르고, 잡아당기고, 놓으면 천이 흔들리다가 멈추는 실제 천 시뮬레이션을 제공하는 대화형 웹사이트 히어로를 만듭니다.

Washing Line Hero란 무엇인가요?

Washing Line Hero는 사용자가 포인터나 손가락으로 천을 실제처럼 조작할 수 있는 물리 기반의 대화형 웹사이트 히어로를 생성하는 AI 에이전트 스킬입니다. 이 스킬은 빨랫줄에 걸린 천이 바람에 흔들리고, 사용자가 누르면 움푹 들어가고, 잡아당기면 따라오며, 놓으면 흔들리다가 멈추는 현실적인 패브릭 시뮬레이션을 구현합니다. Claude Code, Cursor, Codex와 같은 AI 코딩 어시스턴트와 함께 사용하도록 설계되었습니다. 이 스킬은 `hero.json` 설정 파일을 통해 브랜드 이름, 로고, 색상, 폰트, 본문 텍스트, 천에 인쇄될 내용 등을 정의합니다. 빌드 스크립트가 이 설정을 바탕으로 완전한 단일 HTML 페이지(`index.html`)와 기존 사이트에 삽입 가능한 임베드 코드(`embed.html`)를 생성합니다. 또한 체크 스크립트가 다양한 화면 너비에서 레이아웃과 대비를 검증하고, 레코딩 스크립트가 WebGL 또는 네트워크 장애 시 표시될 정지 이미지와 함께, 포인터가 천을 조작하는 모습을 담은 MP4 비디오를 생성합니다. 주요 특징으로 Three.js 기반의 120Hz 고정 스텝 시뮬레이션, WebGL/네트워크 장애 및 Reduced Motion 모드를 위한 정지 이미지 폴백, 휴대폰에서 천 조작 시 페이지 스크롤 방지, 다양한 화면 너비(390, 768, 1024, 1440px)에 대한 자동 레이아웃 및 대비 검사 등이 있습니다. 이 스킬은 섬유, 세탁, 야외, 또는 '가볍고 심플한' 제품을 위한 웹사이트나, 방문자가 직접 조작하며 즐길 수 있는 플레이풀한 히어로, 드래그 가능한 플래그/배너, 포스터가 걸린 빨랫줄, 런칭 헤더 등을 만들고자 할 때 특히 유용합니다.

지원 대상✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/lookbkdev/lookbk-skills/tree/HEAD/skills/washing-line-hero

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Washing Line Hero은(는) 무엇을 하나요?

웹사이트의 첫 화면: 상단에 브랜드 바와 네비게이션, 하나의 컬러 문구가 들어간 큰 헤드라인, 소개 문장, 하나 또는 두 개의 버튼과 작은 노트, 그리고 그 옆에 하늘을 가로지르는 빨랫줄이 있습니다. 빨랫줄에는 나무 빨래집게로 고정된 면 천이 걸려 있고, 천에는 브랜드 자체 포스터(이름, 작은 한 줄, 두 개의 큰 단어, 스펙 열, 작은 막대 차트)가 인쇄되어 있습니다. 산들바람이 때때로 천을 살짝 들어 올리고 구름은 뒤에서 흘러갑니다.

만질 수 있도록 설계되었습니다. 포인터를 천 위로 움직이면 손가락 끝이 천을 움푹 누릅니다. 누르고 드래그하면 천이 손을 따라옵니다: 모서리를 위로 당기고, 줄 위로 접고, 앞으로 늘입니다. 놓으면 천이 떨어지고, 흔들리다가 멈춥니다. 휴대폰에서도 손가락으로 동일하게 조작할 수 있으며, 천을 잡고 있는 동안 페이지는 스크롤되지 않습니다. 천은 시뮬레이션됩니다(늘어짐, 전단, 굽힘 제약 조건으로 결합된 입자 그리드가 120Hz 고정 스텝으로 움직임). 따라서 미리 녹화된 애니메이션을 재생하는 것이 아니라, 잡힌 위치에 따라 천처럼 실제로 움직입니다.

히어로와 인쇄 내용을 hero.json에 설명합니다. 빌드가 모든 것을 확인하고, 하나의 파일로 된 전체 페이지 out/index.html과 이미 있는 사이트에 붙여넣을 수 있는 동일한 섹션 out/embed.html을 생성합니다. 시뮬레이션이 정지된 상태에서 고정 스텝으로 실행되기 때문에 record.mjs가 프레임별로 스텝을 진행할 수 있습니다: 비디오에서 그려진 포인터가 모서리를 잡아당기고, 놓고, 천 위로 손가락 끝을 움직여 방문자가 할 수 있는 동작을 모든 기기에서 동일하게 보여줍니다.

이것이 아닌 것: 천은 찢어지거나, 서로 엉키거나, 줄에서 날아가지 않습니다(자체 충돌이 없어 강하게 접으면 통과하여 떨어집니다). 또한 인쇄 내용은 업로드한 사진이 아니라 사용자가 작성한 텍스트로 페이지가 그립니다.

필요한 것

  • Node.js 18 이상. 설치할 것은 없습니다.
  • Chrome, Chromium 또는 Edge: 검사 및 녹화용(스크립트가 찾습니다. 찾지 못하면 CHROME_PATH를 설정하세요.)
  • ffmpeg: 비디오용(brew install ffmpeg, winget install ffmpeg, apt install ffmpeg; 또는 FFMPEG_PATH 설정).
  • 페이지가 열릴 때 인터넷 접속: three.js와 폰트가 고정된 버전과 무결성 해시와 함께 jsDelivr에서 로드됩니다. 인터넷이 없으면 방문자는 정지 이미지(동일한 줄과 천, 평평하게 그려짐)와 시스템 폰트를 보게 됩니다. 페이지는 여전히 작동합니다.

이 스킬의 폴더는 아래에 <skill>입니다: 이 SKILL.md가 있는 폴더입니다.

단계

1. 브랜드와 단어 수집

사람에게 물어보거나 현재 사이트에서 다음을 찾으세요:

  • 이름, 그리고 로고를 SVG 파일로(정사각형 또는 거의 정사각형; 스크립트가 없는 일반 파일). 로고가 없으면 세 글자 이하로 모노그램을 만듭니다.
  • 색상: 배경색(수평선의 하늘색이기도 함. 텍스트 색상은 배경과 7:1 대비를 이루어야 함), 그리고 하나의 악센트 색상. 연한 파란색은 짙은 텍스트가 있는 한낮의 하늘을 제공합니다. 진한 네이비 또는 자두색은 밝은 텍스트와 낮고 따뜻한 태양이 있는 황혼의 하늘을 제공합니다.
  • 폰트: 헤드라인과 천 위의 큰 단어를 위한 디스플레이 폰트, 그리고 나머지 텍스트를 위한 본문 폰트. 고정 및 검증된 폰트 로드: Space Grotesk, Inter, Instrument Sans, Instrument Serif, DM Sans, Manrope, Fraunces, Sora, Outfit, Bricolage Grotesque, IBM Plex Sans, JetBrains Mono, Plus Jakarta Sans, Newsreader, Playfair Display. 다른 Google Fonts 패밀리도 작동하지만(고정되지 않음).
  • 페이지 위의 단어: 컬러로 표시할 구문이 있는 몇 단어로 된 헤드라인, 무엇이고 누구를 위한 것인지에 대한 한두 문장, 메인 버튼과 선택적 두 번째 버튼(이동할 위치 포함), 바에 있는 최대 5개의 네비게이션 링크와 버튼. 헤드라인 위의 작은 배지와 버튼 아래의 노트는 선택 사항입니다.
  • 천 위의 단어: 상단에 인쇄할 이름(종종 제품 및 버전), 그 아래 작은 한 줄, 두세 개의 큰 단어(두 줄이 가장 잘 읽힘), 최대 6개의 짧은 스펙 쌍(레이블과 값), 차트의 캡션, 모서리의 웹 주소.

모든 이름, 숫자, 주장 및 날짜는 사람에게서 직접 받아야 합니다. 스펙이나 수치를 임의로 만들지 말고 대신 빼세요. 차트의 막대는 시드를 기반으로 장식으로 그려지며, 데이터가 아닙니다: 숫자를 주장하지 않는 캡션을 제공하거나 차트를 끄세요.

2. hero.json 작성

더 가까운 예제 폴더를 복사하고 모든 것을 교체하세요: examples/paperwind/ (노트 앱, 밝은 한낮 하늘, 4개의 집게) 또는 examples/halden/ (린넨 브랜드, 황혼 하늘, 3개의 집게, 더 정사각형 천).

필드설명제한
brand.name, brand.href좌측 상단의 이름과 링크 대상(기본 /)28
brand.logohero.json 옆에 있는 .svg 파일, 페이지에 인라인됨; 또는 모노그램용 3글자 이하–
nav[]필 스타일의 최대 5개 { "label", "href" } (휴대폰에서 숨김)18
action우측 상단의 버튼, { "label", "href" }; 없으면 false22
hero.badge헤드라인 위의 작은 대문자 줄40
hero.title헤드라인. *phrase*는 악센트 색상으로 표시됨; \n은 줄바꿈(최대 3줄)72
hero.lede무엇이고 누구를 위한 것인지. 인라인 Markdown: code, links, bold, italic220
hero.actions[]1 또는 2개의 { "label", "href" }: 첫 번째는 화살표가 있는 솔리드 메인 버튼, 두 번째는 아웃라인 버튼26
hero.note버튼 아래의 작은 줄90
hero.alignleft (줄과 천이 오른쪽, 기본값) 또는 right (반전). center는 천을 카피 뒤에 배치; 권장하지 않음–
theme.background, theme.ink, theme.accentHex 색상. ink는 background와 7:1 대비를 이루어야 함–
theme.modelight 또는 dark; 생략하면 배경에서 계산–
theme.fonts{ "display", "body", "weight" }: 패밀리 이름(false는 시스템 폰트) 및 헤드라인 두께, 300–800 (기본 500)–
theme.scrim0–1: 카피 뒤 하늘이 배경색으로 얼마나 강하게 희석되는지. 기본값 0.3–
effect아래의 하늘, 줄 및 천 설정–
motion.speed0.25–2, 기본값 1: 모든 움직임의 속도–
motion.pointertrue (기본값)–
metatitle (70) 및 description (170) (검색 및 링크 미리보기용); url 및 image (전체 https 주소), lang (기본 en)–

인쇄 내용 (effect): printTitle 또는 printHeadline 중 하나는 필수입니다.

설정제한기본값설명
printTitle28자없음인쇄물 상단의 이름
printLine64자없음이름 아래의 작은 한 줄
printHeadline48자없음큰 단어; \n은 줄바꿈. 열에 맞게 축소됨
printSpecs0~6 { "label", "value" }, 12 및 14자없음오른쪽의 스펙 열; 레이블은 대문자로 인쇄됨
printCharttrue / falsetrue스펙 아래의 작은 막대 차트, 가장 높은 막대는 theme.accent 색상
printChartLabel32자없음차트 아래 캡션
printFoot40자없음하단 모서리의 작은 텍스트 (예: 웹 주소)
cloth색상#ecebe6천 색상
printInk색상#15181d인쇄 잉크 색상. cloth와 7:1 대비 필요

씬 (effect), 모든 설정은 선택 사항:

설정범위기본값설명
seed1–99997구름과 차트 막대의 시드
skyTop색상#5f9be0 (라이트 모드), 어두운 모드에서 배경을 어둡게 함히어로 상단의 하늘 색상
skyBottom색상theme.background수평선의 하늘 색상
clouds0–10.6하늘에서 구름이 차지하는 비율; 0은 맑음
cloudColor색상흰색(라이트 모드), 부드러운 보라색 회색(다크 모드)구름 색상
drift0–10.35구름이 떠다니는 속도
lightday, dusk라이트 모드 day, 다크 모드 dusk위에서 내리쬐는 한낮의 태양, 또는 낮고 따뜻한 태양과 시원한 하늘 빛
aspect0.8–1.71.35천의 너비 대 높이 비율
pegs2–64상단 가장자리를 따라 있는 나무 빨래집게 수
peg색상#c39a64빨래집게 색상
rope색상#6f6a62 (라이트 모드), #cfc6b8 (다크 모드)줄 색상
breeze0–10.45산들바람이 천을 들어 올리는 강도
weave0–10.5평직 패턴이 근접에서 얼마나 강하게 보이는지
poke0–11포인터 아래 움푹 들어간 깊이; 0은 끔
dragtrue / falsetrue방문자가 천을 잡고 당길 수 있도록 허용
size0.6–10.76카피 옆 공간에서 천이 차지하는 비율 (당길 여유 공간 확보)
hint40자"Press it · pull it · let go"넓은 화면에서 방문자에게 만질 수 있다고 알리는 하단 모서리의 작은 캡션; " · "로 부분 구분; 비우면 없음

작성 팁: 페이지의 헤드라인과 천 위의 큰 단어는 다른 내용을 말해야 합니다. 천은 포스터처럼 읽히므로 단어 수를 적게 유지하고 크게 하세요. 두세 개의 스펙 쌍이 여섯 개보다 더 잘 읽힙니다. 브랜드에 가볍고, 날고, 건조하거나 걸려 있다는 재치 있는 문구가 있다면 천이 그 문구를 넣기에 좋은 장소입니다.

3. 빌드

node <skill>/scripts/build.mjs hero.json out

hero.json의 모든 문제(누락된 필드, 제한 초과 텍스트, 범위를 벗어난 설정, 대비가 맞지 않는 색상, 천에 너무 희미한 인쇄 잉크)를 한 번에 나열하고 수정될 때까지 아무것도 쓰지 않습니다. 그런 다음 사용된 설정과 주목할 만한 사항(예: 헤드라인이 4.5:1로 읽히도록 어두워진 악센트)을 출력합니다.

다음을 생성합니다: out/index.html (CSS, 스크립트, 로고 및 정지 이미지가 인라인됨), out/embed.html 및 out/assets/logo.svg (탭 아이콘).

4. 검사

node <skill>/scripts/check.mjs out/index.html

390, 768, 1024 및 1440 px에서 페이지를 로드하고 각각 ok라고 말해야 합니다: 화면보다 넓거나 잘린 부분이 없고, 배경 하늘에 대해 모든 텍스트 줄의 대비가 읽을 수 있으며, 모든 링크와 버튼에 이름이 있고, h1은 하나입니다. ·로 표시된 줄은 주목할 만하지만 실패로 간주하지 않습니다.

5. 살펴보고, 만져보기

node <skill>/scripts/record.mjs out/index.html --still 1.6 --size 1440x900
node <skill>/scripts/record.mjs out/index.html --still 3.5 --size 1440x900
node <skill>/scripts/record.mjs out/index.html --still 1.6 --size 390x844 --scale 2
node <skill>/scripts/screenshot.mjs out/index.html

첫 번째는 정지된 천, 두 번째는 당겨지는 중간(스크립트된 손이 모서리를 올리고 있음), 세 번째는 휴대폰 화면입니다. 살펴보세요: 천 전체가 주변에 여유 공간을 두고 화면에 표시되는지, 인쇄 내용이 읽히는지, 빨래집게가 줄에 잘 앉아 있는지? screenshot.mjs는 GPU 없이 Chrome을 실행하므로 WebGL이 없거나 네트워크가 실패할 때 방문자가 보게 될 정지 이미지(out/screens/에 저장)를 보여줍니다. 이것도 읽을 수 있는지 확인하세요.

그런 다음 out/index.html을 브라우저에서 열고 가지고 놀아보세요: 호버, 누르기, 줄 위로 모서리 당기기, 놓기. 휴대폰에서는 손가락으로 드래그하고 천 옆을 스와이프할 때 페이지가 여전히 스크롤되는지 확인하세요.

6. 비디오 녹화

node <skill>/scripts/record.mjs out/index.html --seconds 10

히어로를 30fps, 1920×1080 해상도로 10초 동안 스텝 진행하고 out/preview.mp4와 out/poster.png(3.5초 프레임, 당겨지는 중간)를 생성합니다. 비디오에서 그려진 포인터가 2.2초에 아래쪽 모서리를 잡고, 위쪽으로 당기고, 4.4초에 놓고, 6초부터 천 위로 손가락 끝을 움직입니다. 옵션: --size 1080x1350 (세로), --size 1080x1920, --fps 60, --poster 1.6. 프레임은 항상 0부터 시작하므로 모든 기기에서 동일합니다.

7. 라이브로 배포

  • 페이지로: out/index.html과 out/assets/를 정적 호스트(Cloudflare Pages, Netlify, Vercel, GitHub Pages, S3)에 업로드하세요. out/poster.png (또는 1200×630 크롭)을 meta.image로 사용하고 사이트와 함께 업로드하세요.
  • 기존 사이트에: 히어로가 들어갈 곳에 out/embed.html을 붙여넣으세요. 모든 것은 #mh-washing-line 아래로 범위가 지정됩니다. 원하면 폰트 <link>를 <head>로 이동하세요. 사이트에 이미 <script type="importmap">가 있으면 임베드의 imports 및 integrity 항목을 병합하세요. 섹션은 전체 뷰포트 높이입니다. --mh-height를 설정(예: style="--mh-height:760px")하여 줄이세요. React 또는 다른 프레임워크에서는 마크업을 컴포넌트에 넣고 <script> 태그는 페이지에 넣거나 iframe으로 렌더링하세요.
  • 인쇄 내용을 변경하려면 hero.json을 편집하고 다시 빌드하세요.

문제 해결

  • build: fix hero.json first: 각 줄은 필드와 변경해야 할 사항을 알려줍니다. 색상 문제는 작동하는 색상을 제안합니다.
  • 천이 가장자리에서 잘림: size를 낮추거나 천을 더 정사각형으로 만드세요(aspect를 1에 가깝게).
  • 천 위의 큰 단어가 작음: 스펙 열 옆에 맞게 축소됩니다. 더 적은 단어를 사용하거나, \n을 사용하거나, 더 적은 스펙과 차트 없음(단어가 전체 너비를 차지함)을 시도하세요.
  • 천이 안정되지 않거나 너무 많이 흔들림: breeze를 낮추세요.
  • 움푹 들어간 자국이 너무 강하거나 희미함: poke (0은 끔, 드래그는 여전히 작동).
  • record: the effect didn't start: 페이지가 정지 이미지로 폴백되었습니다: Chrome이 jsDelivr에서 three.js를 로드할 수 없거나(연결 또는 프록시 확인) WebGL이 없습니다.
  • ffmpeg not found: 설치하거나 FFMPEG_PATH를 설정하세요.
  • 방문자가 정지된 천을 봄: 브라우저가 WebGL을 껐거나 CDN이 차단되었거나(평면 그림), Reduced motion을 요청했습니다(움직이지 않는 정지된 라이브 천의 한 프레임). 의도된 동작입니다.
  • 휴대폰에서 페이지가 스크롤되지 않음: 손가락이 천을 잡고 있는 동안에만 스크롤이 중지됩니다. 천 옆을 스와이프하세요. 천이 휴대폰 화면을 가득 채우면 size를 낮추세요.

파일

  • scripts/build.mjs, scripts/record.mjs: 실행하는 파일. Motion Heroes 키트를 호출합니다.
  • scripts/kit/: 모든 Motion Heroes 스킬이 공유하는 키트: 빌드 및 검사(build.mjs), 섹션의 CSS(shell.css), 브라우저 런타임(runtime.js: 클록, 일시 중지, 픽셀 비율, Reduced motion, 폴백), 레코더(record.mjs, cdp.mjs), 고정된 three.js 및 폰트(three.json, fonts.json) 및 이들을 설명하는 KIT.md.
  • scripts/effect/: 빨랫줄 자체: effect.mjs (설정, 검사 및 정지 이미지), effect.js (하늘 셰이더, 천...

(원문이 잘려서 이하 생략)

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

관련 스킬