Community코딩 & 개발github.com

iart-ai/ecommerce-video-skills

스크린샷, 가격 정보, 이미지 폴더에서 바로 제품 데모, 세일 프로모션, 사진 슬라이드쇼 등 전자상거래/제품 비디오를 생성합니다.

ecommerce-video-skills란 무엇인가요?

이 스킬은 정적인 제품 스크린샷이나 디자인을 세련된 애니메이션 데모 비디오로 변환합니다. 사용자가 '제품 데모 비디오 만들기', '앱 데모 비디오 생성', '기능 발표 비디오 제작', 'SaaS 데모', 'UI 둘러보기 비디오', '제품 스크린샷을 데모로 애니메이션화', '애니메이션 커서/클릭 추가', 'UI 일부 확대' 등을 요청할 때 사용합니다. 화면 녹화가 아닌 정적 스크린샷/디자인을 입력으로 사용하여, 기기/브라우저 프레임, 애니메이션 커서 + 클릭 리플, 초점 UI로의 확대/이동, 설명 주석, 단계별 템포, 화면 간 전환, 기능 캡션 등을 제공합니다. Remotion 프레임워크 기반이며, 모든 움직임(커서 이동, 확대 등)은 프레임 번호에 따른 순수 함수로 계산되어 재현 가능하고 일관된 결과를 보장합니다.

지원 대상~Claude Code~Codex CLI✓Cursor
npx skills add iart-ai/ecommerce-video-skills

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

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

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

문서

제품 데모 비디오

정적인 제품 스크린샷이나 디자인을 세련된 애니메이션 데모로 변환합니다. 화면 녹화기, 떨리는 실제 커서, UI 버전 차이가 없습니다. 각 화면을 프레임하고, 합성 커서를 정확한 픽셀로 이동시키고, 클릭 리플을 만든 다음, 중요한 부분으로 확대하여 기능을 캡션합니다. 입력이 정적이고 움직임이 코드로 처리되므로 모든 값은 결정론적이며 스크린샷이 변경되어도 동일하게 다시 렌더링됩니다.

사용 시기

  • 앱/SaaS 데모, 기능 발표, 온보딩 둘러보기 (15~90초)
  • 스크린샷/디자인만 있는 UI의 클릭 경로 표시
  • 복잡한 대시보드의 한 초점 영역 강조 (영역 확대 + 설명 주석)

스크린샷이 화면 녹화보다 나은 이유

화면 녹화스크린샷 기반 (이 스킬)
실제 커서가 흔들리고, 벗어나고, 떨림커서가 완화된 경로를 따라 정확한 대상으로 이동
한 단계 수정하려면 전체 테이크 재녹화하나의 PNG를 교체하고 동일한 코드 다시 렌더링
녹화 중 UI 변경, 마우스 찾기 힘듦각 화면은 깔끔하고 최종 상태의 에셋
픽셀화 없이 확대 어려움스크린샷을 2배(DPR 2)로 내보내기 → 선명한 확대

입력을 디스플레이 크기의 두 배(레티나 / deviceScaleFactor: 2)로 캡처하여 2배 확대해도 선명하게 유지하세요. Playwright 캡처 스크립트는 references/screenshot-demo.md를 참조하세요.

데모 루프

모든 데모는 기능별로 동일한 비트를 반복합니다. 읽을 수 있을 만큼 충분히 유지하고, 의도를 가지고 이동하며, 클릭을 정확히 하고, 결과를 보여줍니다.

비트시간 할당작업
화면에 안착0.5~1초시청자가 움직이기 전에 방향을 잡도록 함
커서가 대상으로 이동0.4~0.8초완화된 이동 (ease-in-out), 선형 아님
클릭 리플 + 상태 변경0.2~0.3초촉각적 피드백; 화면이 같은 프레임에서 반응
초점 영역으로 확대12초 확대, 24초 유지2배가 최적 — 충분한 디테일, 맥락 유지
기능 캡션확대와 함께 유지하나의 이점 구문, 예: "원클릭 내보내기"

카메라 또는 커서를 동시에 움직이지 말고, 한 번에 하나만 움직이세요. 두 가지 동시 움직임은 주의를 분산시킵니다.

스크린샷 프레임

원시 스크린샷은 버그 보고서처럼 읽히지만, 프레임이 있는 것은 제품처럼 읽힙니다. 모든 화면을 브랜드 배경의 브라우저 또는 기기 크롬으로 감싸세요.

// 브라우저 프레임 — 스크린샷을 넣으면 신뢰할 수 있는 창이 나타남
const BrowserFrame = ({ url, children }) => (
  <div style={{ borderRadius: 12, overflow: "hidden", background: "#1e1e22",
                boxShadow: "0 40px 80px rgba(0,0,0,.35)" }}>
    <div style={{ height: 40, display: "flex", alignItems: "center", gap: 8, padding: "0 14px" }}>
      {["#ff5f57", "#febc2e", "#28c840"].map((c) => (
        <span key={c} style={{ width: 12, height: 12, borderRadius: "50%", background: c }} />
      ))}
      <div style={{ marginLeft: 12, flex: 1, height: 24, borderRadius: 6, background: "#2b2b30",
                    color: "#9aa", fontSize: 13, display: "flex", alignItems: "center", padding: "0 10px" }}>
        {url}
      </div>
    </div>
    <div style={{ background: "#fff" }}>{children}</div>
  </div>
);

주소 표시줄에 실제 URL을 넣고(진정성), 부드러운 그림자와 그라데이션 배경을 추가하세요. 모바일의 경우 노치와 둥근 모서리가 있는 전화 프레임으로 전환하세요. 모든 화면이 일치하도록 프레임 스타일을 하나의 테마 객체에 유지하세요.

애니메이션 커서 + 클릭 리플 (핵심 동작)

CSS 전환이나 벽시계가 아닌, 항상 현재 프레임에서 위치를 계산하세요. 비디오 렌더러는 모든 프레임이 프레임 번호의 순수 함수여야 합니다. 그렇지 않으면 커서가 동기화되지 않고 깜박입니다.

import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";

// `from`에서 `to`로 startFrame과 startFrame+dur 사이를 완화하여 이동
const useCursor = (from, to, startFrame, dur) => {
  const frame = useCurrentFrame();
  const t = interpolate(frame, [startFrame, startFrame + dur], [0, 1],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: (x) => x * x * (3 - 2 * x) }); // smoothstep
  return { x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t };
};

export const Cursor = ({ from, to, startFrame, dur, clickAt }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const { x, y } = useCursor(from, to, startFrame, dur);

  // 리플은 한 번, 클릭 프레임에서 확장
  const since = frame - clickAt;
  const showRipple = since >= 0 && since < 18;
  const r = spring({ frame: since, fps, config: { damping: 18 }, durationInFrames: 18 });

  return (
    <>
      {showRipple && (
        <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)",
          width: 12 + r * 60, height: 12 + r * 60, borderRadius: "50%",
          border: "2px solid rgba(80,140,255,.9)", opacity: 1 - r }} />
      )}
      <svg width="28" height="28" viewBox="0 0 28 28"
           style={{ position: "absolute", left: x, top: y, filter: "drop-shadow(0 2px 3px rgba(0,0,0,.4))" }}>
        <path d="M3 2 L3 21 L9 15 L13 24 L16 23 L12 14 L20 14 Z" fill="#fff" stroke="#222" strokeWidth="1.4" />
      </svg>
    </>
  );
};

커서는 smoothstep을 사용하여 정지 상태에서 가속하고 대상에서 감속합니다(선형 커서는 로봇처럼 읽힙니다). 동일한 clickAt 프레임에서 리플 과 화면 상태 변경을 실행하여 원인과 결과가 일치하도록 하세요. 여러 화면에 걸쳐 여러 클릭을 연결하는 전체 구성은 references/screenshot-demo.md를 참조하세요.

영역 확대 (UI용 Ken Burns 효과)

초점 요소로 확대하려면 화면을 확대하고 transform-origin을 해당 요소의 중앙으로 설정하여 프레임 중앙 대신 해당 요소에 수렴하도록 합니다.

const ZoomToRegion = ({ target, scale = 2, startFrame, dur, children }) => {
  const frame = useCurrentFrame();
  const s = interpolate(frame, [startFrame, startFrame + dur], [1, scale],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: (x) => 1 - Math.pow(1 - x, 3) }); // easeOutCubic
  return (
    <div style={{ transform: `scale(${s})`, transformOrigin: `${target.x}px ${target.y}px`,
                  willChange: "transform" }}>
      {children}
    </div>
  );
};

확대 배율을 2배 정도로 제한하세요(3배 이상은 맥락을 잃고 방향 감각을 잃게 합니다). 확대된 상태를 2~4초 유지하여 디테일을 읽을 수 있을 만큼 충분히 시간을 확보한 다음, 다음 화면으로 이동하기 전에 부드럽게 축소하세요. 확대를 항상 설명 주석과 함께 사용하고, 단독으로 사용하지 마세요.

설명 주석 및 기능 캡션

중요 지점에 주석을 달고, 그런 다음 지우세요. 설명 주석은 초점 요소를 가리키는 레이블 + 연결선(화살표, 원, 밑줄)입니다.

  • 강조 요소는 부드러운 링이나 주변을 어둡게 처리하여 강조합니다(box-shadow: 0 0 0 9999px rgba(0,0,0,.45)는 스포트라이트 구멍을 만듭니다).
  • 캡션은 비트당 하나의 이점을 설명합니다. 짧은 명사구("실시간 분석"), 문장이 아닙니다. 확대와 함께 나타나고, 다음 단계 전에 사라집니다.
  • 캡션을 아래쪽 1/3 지점에, 타이틀 안전 영역 내에 유지하여 9:16으로 자를 때도 잘리지 않도록 합니다.

스포트라이트 마스크, 화살표 연결선 및 입력된 캡션 트랙은 references/annotation-and-transitions.md를 참조하세요.

화면 간 전환

단계 사이에 일관된 언어로 화면을 이동하세요. 하나를 선택하고 유지하세요:

전환느낌사용
밀기 / 슬라이드"다음 단계" 전진 동작선형 둘러보기
교차 확대모멘텀, 앱과 유사세부 보기로 점프
교차 페이드차분함, 중립적컨텍스트 전환 (설정 → 대시보드)
공유 요소에 대한 매치 컷매끄러움동일한 카드가 여러 화면에 걸쳐 지속됨

클릭이 해결될 때까지 나가는 화면을 유지한 다음 전환하세요. 절대 움직임 중간에 자르지 마세요. references/annotation-and-transitions.md를 참조하세요.

출력 체크리스트

  • 입력을 2배(DPR 2)로 캡처; 2배에서 확대가 선명하게 유지됨.
  • 모든 커서/확대 값은 useCurrentFrame()의 순수 함수임 — 애니메이션 상태에 CSS 전환 사용 금지.
  • 커서는 완화된 경로(smoothstep)로 이동; 리플과 상태 변경은 동일한 클릭 프레임에서 실행됨.
  • 각 화면은 실제 URL과 일관된 테마로 프레임 처리됨(브라우저/기기).
  • 한 번에 하나의 움직임(카메라 또는 커서); 확대 ≤ 2배, 2~4초 유지.
  • 비트당 하나의 이점 캡션, 타이틀 안전 영역 아래쪽 1/3 지점에 위치; 전환은 하나의 일관된 언어 사용.

제공 및 확인 (렌더링된 스틸 → MP4)

패키지 도우미 (scripts/): scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png로 스틸을 바둑판식으로 배열한 다음, scripts/probe-mp4.sh out.mp4 [WxH] [fps]로 인코딩을 확인하세요. scripts/README.md를 참조하세요.

이것은 무거운 계층입니다: 결과물은 MP4이지 라이브 페이지가 아닙니다. 데모는 사용자 에셋(스크린샷/디자인, 선택적 로고)을 사용하므로, 확인은 주로 올바른 이미지가 실제로 로드되어 프레임 안에 들어갔는지에 관한 것입니다.

출력 계약:

  • 구성이 등록된 Remotion 프로젝트 (<Composition> + zod schema + defaultProps); 모든 커서/확대/전환 값은 useCurrentFrame()의 순수 함수임 (CSS 전환, 타이머, Date.now() 사용 금지).
  • 스크린샷은 staticFile()을 통해 로드되고 delayRender/continueRender로 게이트되어 2배 PNG(및 모든 웹 폰트)가 프레임 렌더링 전에 존재하도록 함 — 그렇지 않으면 화면이 데모 중간에 빈 상태로 나타남.
  • 결과물 = 렌더링된 out/*.mp4 + 프로젝트(스크린샷이 변경되면 다시 렌더링).

확인 루프 — 스틸 렌더링 → 검사 → 인코딩. 저렴한 PNG부터 먼저 확인하고, 비디오는 올바른 경우에만.

# 전달할 PROPS(실제 스크린샷 경로)를 사용한 프레임 정확 스틸, defaultProps 사용 금지
npx remotion still ProductDemo out/f-settle.png --frame=15  --props=demo.json   # 화면 프레임 처리, 이동 전
npx remotion still ProductDemo out/f-click.png  --frame=90  --props=demo.json   # 대상 위의 커서 + 리플
npx remotion still ProductDemo out/f-zoom.png   --frame=150 --props=demo.json   # 초점 영역 확대 + 캡션
# 종료 프레임 = durationInFrames - 1 (npx remotion compositions가 읽음)

각 PNG를 충실도(올바른 스크린샷 로드됨; 커서가 정확한 픽셀에 있음; 클릭 리플과 상태 변경이 동일한 프레임에 있음; 캡션 텍스트가 올바름) 및 아티팩트(이미지가 비어 있거나 로드되지 않음, 화면이 캔버스 밖에 있음, 확대/축소가 픽셀화되거나 프레임을 넘어감, 캡션이 타이틀 안전 영역 아래쪽 1/3 지점을 벗어남, 잘못된 종횡비/레터박싱)에 대해 검사합니다.

# 스틸이 깨끗한 경우에만:
npx remotion render ProductDemo out/demo.mp4 --props=demo.json
npx remotion render ProductDemo out/demo.gif --props=demo.json --codec=gif   # README 첫 화면 증명

배치(하나의 템플릿, 여러 제품): 제품별로 데모를 다시 스킨할 때는 카탈로그를 배치 렌더링하기 전에 스틸을 통해 대표 제품 하나의 props를 확인하세요. 빈 이미지 또는 캔버스 밖 버그를 N번이 아닌 한 번에 잡을 수 있습니다.

완료 전:

  1. 스틸이 안착/클릭/종료 시 깨끗하게 렌더링됨 — 오류 없음, 스크린샷이 실제로 로드됨(비어 있지 않음).
  2. 커서가 정확한 대상에 도달함; 리플 + 상태 변경이 동일한 프레임에 있음; 캡션 텍스트가 올바르고 타이틀 안전 영역 아래쪽 1/3 지점에 있음.
  3. 모든 모션은 프레임 기반 — CSS 전환 / 타이머 / Date.now() / Math.random() 사용 금지.
  4. 제공된 props(실제 스크린샷 경로)가 올바르게 렌더링되며, defaultProps만이 아님.
  5. 전체 MP4가 인코딩되어 재생됨; (선택 사항) README용 GIF가 렌더링됨.

참조 파일

  • references/screenshot-demo.md — 완전히 실행 가능한 Remotion 데모: Playwright로 2배 스크린샷 캡처, 브라우저/전화 프레임 컴포넌트, 여러 화면에 걸쳐 커서를 이동시키고 클릭 리플을 포함하는 다단계 구성, 렌더링 명령어.
  • references/annotation-and-transitions.md — 스포트라이트 마스크, 화살표 연결선 및 입력된 캡션 트랙; 화면 간 전환에 대한 안내.

Individual skills in this repo

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

관련 스킬