Communitygithub.com

키네틱 타이포그래피

텍스트를 올바르게 움직이게 하는 방법 — 타이틀 카드, 애니메이션 캡션, 로우어 서드, 콜아웃, 단어별 표시 등. 단어당 읽기 시간 예산을 적용하여 복사본이 읽을 수 있을 만큼 오래 유지되도록 하고, 진입/퇴장 타이밍, 굵기 및 크기 전환, 모션에서의 타이포그래피 계층 구조를 다룹니다.

키네틱 타이포그래피란 무엇인가요?

키네틱 타이포그래피는 움직이는 텍스트의 가독성을 최우선으로 하는 AI 에이전트 스킬입니다. 이 스킬은 텍스트가 화면에 머무는 시간(hold), 진입(entrance) 및 퇴장(exit) 타이밍을 계산하여 사용자가 제공한 복사본이 자연스럽게 읽힐 수 있도록 보장합니다. 'type_budget.js'라는 자체 포함된 Node.js 스크립트를 사용하여 단어 수와 익숙하지 않은 용어 유무에 따라 프레임 예산을 계산합니다. 이 스킬은 'remotion-compose'에 구체적인 프레임 번호(enter@, holdStart@, holdEnd@, exitOut@)를 전달하여 React/TypeScript 기반의 Remotion 컴포넌트를 작성하도록 돕습니다. 주요 원칙은 '읽기를 위해 움직임'이며, 불필요한 애니메이션(예: 반복 펄스, 여러 속성 동시 애니메이션, 글자 재배열)을 금지합니다. 이 스킬은 'motion-design-principles', 'video-storyboard', 'product-demo-director' 등 여러 형제 스킬과 협력하여 전체 모션 디자인 워크플로우에서 단 하나의 역할(텍스트 타이밍 및 가독성)을 담당합니다.

지원 대상~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/SkillMedev/tutorial-video-studio/tree/main/skills/kinetic-typography

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

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

문서

키네틱 타이포그래피은(는) 무엇을 하나요?

움직이는 텍스트는 다른 모든 작업보다 먼저 한 가지 임무를 수행해야 합니다: 읽을 수 있어야 합니다. 애니메이션 처리된 텍스트에서 가장 흔한 실패는 추함이 아니라, 시청자가 첫 단어를 마치기도 전에 지나쳐 버리는 텍스트, 또는 눈이 읽기보다 움직임을 쫓도록 너무 많이 움직이는 텍스트입니다. 이것은 장인 계층입니다. 각 줄이 얼마나 오래 머무르는지, 어떻게 들어오고 나가는지, 무엇이 움직일 수 있는지를 결정하며, 이를 실제로 렌더링하는 React/TypeScript를 작성하는 remotion-compose에 구체적인 프레임 예산을 전달합니다.

지배적인 규칙: 읽기를 돕기 위해 애니메이션을 적용하고, 장식을 위해 절대 적용하지 마십시오. 움직임은 눈을 안내하거나, 계층을 설정하거나, 박자를 표시할 때만 그 자리를 얻습니다. 아래의 모든 내용은 이를 강화합니다.

하나의 예시를 통해 작업합니다: 16:9 제품 타이틀 카드로 "Ship video in one prompt" (5단어), 30fps, 그리고 아래에 애니메이션 로우어-서드 캡션 트랙이 있습니다.

워크플로우

이 순서대로 실행하십시오. 홀드 예산을 먼저 계산하기 전에는 진입 애니메이션을 선택하지 마십시오. 예산은 움직일 여유가 있는지 알려줍니다.

1단계 - 먼저 단어당 읽기 시간 예산을 계산하십시오

텍스트는 여유로운 속도로 읽을 수 있을 만큼 오래 화면에 머물러야 하며, 더하기 진입 및 퇴장 시간도 포함해야 합니다. 애니메이션을 다루기 전에 홀드 시간을 예산으로 잡으십시오.

  • 온스크린 비디오의 기준 읽기 속도는 인쇄물보다 느립니다: 약 3.5단어/초 (약 200 wpm)로 편안하게 읽는다고 가정합니다. 캡션/자막 규칙도 유사합니다 — 단어당 읽을 수 있는 홀드 시간을 0.3초 미만으로 떨어뜨리지 마십시오.
  • 최소 온스크린 홀드 = 단어 ÷ 3.5초, 단 0.8초의 최소값(한 단어라도 인식할 시간이 필요함)과 익숙하지 않은 용어, 숫자 또는 이름에 대한 +0.3초 세금을 추가합니다.
  • 진입 및 퇴장 시간은 추가입니다 — 텍스트가 전환 중에 완전히 읽을 수 없기 때문에 읽기 시간으로 계산되지 않습니다. 총 슬롯 = 진입 + 홀드 + 퇴장.

type_budget.js(아래)를 실행하여 복사본 줄을 프레임 예산으로 변환합니다. 타이틀 카드의 경우 약 43프레임의 홀드를 반환합니다. 이 숫자를 remotion-compose에 Sequence의 읽을 수 있는 창으로 전달하며, 진입/퇴장은 그 위에 추가됩니다.

2단계 - 컷에 맞는 진입/퇴장 타이밍을 선택하고 기본값을 사용하지 마십시오

진입과 퇴장은 구두점일 뿐, 문장이 아닙니다. 짧게 유지하고 홀드가 작업을 수행하도록 하십시오.

  • 진입: 8-15프레임 (0.25-0.5초) @ 30fps. 빠르게 느껴질 만큼 빠르고, 의도적으로 읽힐 만큼 느립니다. 타이틀 카드는 긴 쪽을 사용할 수 있고, 빠른 캡션 트랙은 짧은 쪽을 사용합니다.
  • 퇴장: 진입과 같거나 더 짧습니다. 퇴장은 절대 오래 머물지 않아야 합니다 — 읽은 후에는 텍스트가 사라져야 합니다. 6-12프레임.
  • 퇴장을 뒤에 오는 것에 맞추십시오. 다음 장면으로 하드 컷 → 텍스트를 컷 지점에 퇴장시킵니다(페이드 없음, 컷이 처리하게 함). 크로스-디졸브 → 디졸브 동안 텍스트를 페이드 아웃합니다. 정교한 퇴장을 하드 컷에 절대 애니메이션하지 마십시오. 편집과 맞지 않습니다. 이것은 motion-design-principles(컷과 이징)과 이 스킬이 만나는 지점입니다 — 이징 곡선은 거기서 가져와서 여기 텍스트에 적용하십시오.
  • 다중 요소 표시를 지연시키고, 동시에 애니메이션하지 마십시오. 타이틀 + 서브타이틀은 서브타이틀이 타이틀이 안정된 후 4-8프레임 후에 진입할 때 가장 잘 읽히므로, 눈이 위에서 아래로 이끌립니다.

3단계 - 줄당 하나의 진입 기술을 선택하고 하나의 속성만 애니메이션하십시오

한 번에 더 많은 속성이 움직일수록 전환 중 텍스트를 읽기가 어려워집니다. 기본값으로 단일 속성을 애니메이션하고, 의도가 있을 때만 두 개를 결합하십시오(예: 불투명도 + 작은 이동).

  • 페이드 (불투명도 0→1) - 가장 안전하고, 항상 읽을 수 있으며, 캡션 트랙과 본문 줄의 올바른 기본값입니다.
  • 상승 / 슬라이드 (작은 이동, 20-60px, 페이드와 함께) - 방향과 생동감을 추가합니다; 타이틀 카드의 주력입니다. 거리를 작게 유지하십시오 — 큰 슬라이드는 눈이 읽기 대신 이동을 추적하게 만듭니다.
  • 단어별 표시 - 각 단어가 자체 짧은 지연으로 순서대로 페이드/상승합니다. 강조 줄과 가사 스타일 조각에 사용하고, 밀집된 캡션에는 사용하지 마십시오(읽기가 끊깁니다). 전체 줄의 표시가 홀드 내에서 잘 끝나도록 예산을 세우십시오.
  • 확대 / 팝 (0.85→1에서 스프링) - 활기차고, 단일 히어로 단어나 숫자 콜아웃에 좋습니다. 전체 문장을 확대하지 마십시오. 재배치되어 읽을 수 없습니다.
  • 마스크 / 와이프 표시 - 프리미엄, 방향성, 단일 헤드라인에 좋습니다. 구축 비용이 더 많이 들고; 중요한 하나의 타이틀을 위해 남겨두십시오.

무엇을 선택하든, 속성은 애니메이션됩니다; 텍스트 자체는 애니메이션 중에 절대 재배치되지 않습니다. opacity와 transform (translate/scale/clip)을 애니메이션하십시오 — 글리프를 다시 배치하는 font-size, width 또는 letter-spacing은 절대 사용하지 마십시오. 레이아웃 기반 애니메이션은 떨리고 읽을 수 없기 때문입니다.

4단계 - 굵기와 크기를 전환으로 애니메이션하고, 노이즈로 만들지 마십시오

굵기와 크기는 유형이 움직임에서 강조를 표현하는 방법입니다 — 하지만 이것들은 고정 상태 간의 전환이지, 지속적인 흔들림이 아닙니다.

  • 굵기 전환: 단어가 더 가벼운 굵기에서 더 무거운 굵기로 정착하여 강조를 표현할 수 있습니다(예: 8프레임 동안 400→700). 실제 가변 글꼴 굵기 축이나 패밀리의 두 가지 컷을 사용하십시오. 확대로 가짜 굵기를 만들지 마십시오.
  • 크기 전환: 숫자나 키워드는 계층을 주장하기 위해 한 번 확대된 후 유지될 수 있습니다. 확대-후-유지, 확대-후-펄스가 아닙니다. 텍스트에 반복되는 펄스는 깨진 렌더링처럼 읽히고 강조가 아닙니다.
  • 이것들은 악센트입니다. 줄당 최대 한 개의 굵기/크기 악센트를 가장 중요한 단어에만 넣으십시오. 모든 것이 강조되면 아무것도 강조되지 않습니다.

5단계 - 모션에서 유형 계층 설정 (순서, 크기, 굵기, 타이밍)

모션의 계층은 네 가지 신호로 구축됩니다. 함께 사용하여 눈이 어디를 보고 어떤 순서로 볼지 알게 하십시오.

  1. 진입 순서 - 먼저 애니메이션되는 것이 먼저 읽힙니다. 헤드라인으로 시작하고, 서브타이틀을 따르며, CTA로 끝냅니다.
  2. 크기 대비 - 명확한 비율을 유지하십시오 (헤드라인 ≥ 1.6× 서브타이틀). 움직임은 약한 정적 계층을 구하지 못합니다.
  3. 굵기 대비 - 더 무거움 = 더 중요합니다. 한 번에 화면에 최대 두 가지 굵기.
  4. 타이밍 - 가장 중요한 줄이 가장 긴 홀드와, 가능하다면 가장 존재감 있는 진입을 얻습니다. 가장 덜 중요한 것(지속적인 로우어-서드, 워터마크)은 단일 진입 후 애니메이션되지 않습니다.

motion-type-spec 템플릿(아래)을 줄별 예산, 기술 및 계층 역할로 채우십시오. 채워진 스펙이 remotion-compose로의 핸드오프입니다.

6단계 - 애니메이션하지 않을 위치를 결정하십시오

선배의 움직임은 절제입니다. 최종 확정 전에 아래 "Do NOT" 목록에서 애니메이션을 제거하십시오. 하나의 잘 예산된 상승이 있는 타이틀 카드는 모든 단어가 무언가 하는 것보다 더 잘 읽힙니다.

품질 기준

완성된 모션-유형 스펙은 모든 홀드가 다음을 충족할 때만 A+입니다:

  • 모든 줄이 읽기 시간 예산을 통과합니다 - 홀드 ≥ max(0.8s, 단어 ÷ 3.5 + 용어 세금), type_budget.js에 의해 계산되며, 진입/퇴장은 위에 추가되고, 절대 그에서 빼지 않습니다.
  • 각 줄은 하나의 속성을 애니메이션합니다 (두 개는 명시적 의도로만), 어떤 줄도 애니메이션 중에 글리프를 재배치하지 않습니다 - opacity/transform만.
  • 진입은 8-15프레임, 퇴장 ≤ 진입, 퇴장은 기본값이 아닌 다음 편집(컷 vs. 디졸브)에 맞춰집니다.
  • 계층이 순서대로 읽힙니다: 진입 순서, 크기 비율 (≥1.6×), 굵기 모두가 동일한 가장 중요한 줄을 가리킵니다.
  • 줄당 최대 하나의 굵기/크기 악센트, 그리고 아무것도 반복되거나 펄스하지 않습니다.
  • 스펙은 프레임 번호를 지정합니다 (진입, 홀드 시작, 홀드 종료, 퇴장) 그래서 remotion-compose가 추측 없이 Sequences를 작성할 수 있습니다.

하지 말아야 할 것

  • 읽기 예산보다 짧게 유지되는 텍스트를 제공하지 마십시오 - 가장 흔한 키네틱 타입 실패입니다. 유지할 공간이 없으면, 홀드 시간이 아닌 단어를 줄이십시오.
  • font-size, width, letter-spacing 또는 글리프를 재배치하는 것을 애니메이션하지 마십시오; 레이아웃 쓰레기는 읽을 수 없습니다. transform을 통해 크기를 조정하십시오.
  • 줄당 하나 또는 두 개 이상의 속성을 애니메이션하지 마십시오, 밀집된 캡션을 단어별로 절대 애니메이션하지 마십시오 - 읽기가 끊깁니다.
  • 반복, 펄스, 여러 번 바운스 또는 텍스트를 지속적인 움직임으로 유지하지 마십시오; 멈추지 않는 움직임은 읽을 수 없습니다.
  • 모든 요소를 애니메이션하지 마십시오. 로우어-서드, 워터마크, 지속적인 레이블 및 법적 텍스트는 하나의 진입 후 가만히 있습니다. 본문/캡션 텍스트를 정교한 진입으로 애니메이션하지 마십시오 - 페이드가 올바릅니다.
  • 기본 이징 곡선이나 장면 컷을 여기서 결정하지 마십시오 - 그것은 motion-design-principles입니다. Remotion 컴포넌트를 여기서 작성하지 마십시오 - 채워진 스펙을 remotion-compose에 전달하십시오.
  • 복사본을 만들지 마십시오. 사용자가 제공한 단어를 애니메이션하십시오. 줄이 너무 길어 유지할 수 없으면 짧게 해달라고 요청하십시오.

형제 스킬 - 핸드오프, 흡수하지 마십시오

이 스킬은 텍스트 타이밍과 가독성을 소유합니다. 인접한 결정은 형제에 속합니다. 그들에게서 가져오고, 여기서 그들의 작업을 다시 하지 마십시오.

  • motion-design-principles - 컷, 비텍스트 모션의 속도, 그리고 이징 곡선 (가속 형태). 곡선을 거기서 가져와 여기 텍스트에 적용하십시오.
  • video-storyboard - 어떤 장면과 샷이 존재하며, 어떤 순서인지. 먼저 장면 목록을 얻으십시오; 이 스킬은 장면 내에서만 텍스트를 시간화합니다.
  • motion-color-and-light - 배경에 대한 텍스트의 색상, 대비 및 가독성. 색상 때문에 텍스트가 읽기 어렵다면, 그것은 여기서 타이밍 변경이 아닌 그 스킬의 작업입니다.
  • product-demo-director - 제품 데모의 전체 내러티브와 비트 목록. 타이틀 카드가 무엇을 말하고 언제 배치될지 결정합니다; 이 스킬은 각각이 어떻게 애니메이션되는지 시간화합니다.
  • sound-and-music-sync - 텍스트 표시를 비트나 다운비트에 맞추기. holdStart@ / 진입 프레임 번호를 전달하여 표시가 트랙에 스냅될 수 있도록 하십시오.
  • social-video-formatter - 플랫폼(9:16 TikTok, 1:1 피드, 안전 영역)에 대한 캡션 트랙 크기 조정 및 자르기. 여기서 한 번 타이밍을 작성하고; 그 스킬이 플랫폼별로 재배치하게 하십시오.

계산기

자체 포함된 Node 스크립트. type_budget.js로 저장하고 node type_budget.js로 실행하십시오. 종속성 없음. lines 배열을 실제 복사본으로 편집하십시오. fps에서 각 줄의 프레임 예산을 반환합니다.

// Kinetic-type reading budget. Edit lines + fps, then: node type_budget.js
const fps = 30
const WORDS_PER_SEC = 3.5   // comfortable on-screen read (~200 wpm)
const FLOOR_SEC = 0.8       // minimum hold for any line, even one word
const TERM_TAX_SEC = 0.3    // per line containing a number/name/jargon term
const ENTRANCE_FRAMES = 12  // 0.4s entrance
const EXIT_FRAMES = 9       // exit <= entrance

const lines = [
  { text: 'Ship video in one prompt', hasUnfamiliarTerm: false }, // title card
  { text: 'Rendered headless in 4K',  hasUnfamiliarTerm: true  }, // caption: '4K'
  { text: 'Go',                       hasUnfamiliarTerm: false }, // hero word
]

const sec2frames = (s) => Math.ceil(s * fps)

function budget(line) {
  const words = line.text.trim().split(/\s+/).length
  const raw = words / WORDS_PER_SEC + (line.hasUnfamiliarTerm ? TERM_TAX_SEC : 0)
  const holdSec = Math.max(FLOOR_SEC, raw)
  const holdFrames = sec2frames(holdSec)
  const totalFrames = ENTRANCE_FRAMES + holdFrames + EXIT_FRAMES
  return { words, holdSec, holdFrames, totalFrames }
}

let cursor = 0
for (const line of lines) {
  const b = budget(line)
  const enterIn = cursor
  const holdStart = enterIn + ENTRANCE_FRAMES
  const holdEnd = holdStart + b.holdFrames
  const exitOut = holdEnd + EXIT_FRAMES
  console.log(`"${line.text}" (${b.words}w)`)
  console.log(`  hold:        ${b.holdSec.toFixed(2)}s = ${b.holdFrames} frames`)
  console.log(`  total slot:  ${b.totalFrames} frames (enter ${ENTRANCE_FRAMES} + hold ${b.holdFrames} + exit ${EXIT_FRAMES})`)
  console.log(`  Sequence:    enter@${enterIn}  holdStart@${holdStart}  holdEnd@${holdEnd}  exitOut@${exitOut}`)
  cursor = exitOut
}
console.log(`Total track length: ${cursor} frames (${(cursor / fps).toFixed(2)}s)`)

작업된 예제 출력

"Ship video in one prompt" (5w)
  hold:        1.43s = 43 frames
  total slot:  64 frames (enter 12 + hold 43 + exit 9)
  Sequence:    enter@0  holdStart@12  holdEnd@55  exitOut@64
"Rendered headless in 4K" (4w)
  hold:        1.44s = 44 frames
  total slot:  65 frames (enter 12 + hold 44 + exit 9)
  Sequence:    enter@64  holdStart@76  holdEnd@120  exitOut@129
"Go" (1w)
  hold:        0.80s = 24 frames
  total slot:  45 frames (enter 12 + hold 24 + exit 9)
  Sequence:    enter@129  holdStart@141  holdEnd@165  exitOut@174
Total track length: 174 frames (5.80s)

읽어보십시오: 5단어 타이틀은 43프레임의 고정된, 완전히 읽을 수 있는 시간이 필요합니다 - 그리고 그것은 12프레임 진입 및 9프레임 퇴장 위에 있으므로 실제 슬롯은 64프레임입니다. 4단어 캡션은 더 짧아 보이지만 숫자(4K)를 포함하므로 용어 세금이 홀드를 44프레임으로 밀어 올립니다 - 단어가 더 적음에도 불구하고 타이틀보다 약간 더 깁니다. 단일 단어 Go는 0.8초 최소값에 도달합니다: 한 단어라도 박자를 얻습니다. 이러한 enter@ / holdStart@ / holdEnd@ / exitOut@ 프레임 번호는 <Sequence from={…} durationInFrames={…}> 경계로 remotion-compose에 직접 들어갑니다 - 텍스트가 얼마나 오래 유지되어야 하는지 추측할 필요가 없습니다.

템플릿: motion-type-spec

이것을 채우고 remotion-compose에 전달하십시오. 텍스트 줄당 하나의 블록.

MOTION TYPE SPEC. [FILL: composition name].  fps: [FILL]  canvas: [FILL: 1920x1080 / 1080x1920]

LINE 1
  Copy (verbatim):     [FILL]
  Hierarchy role:      [FILL: headline / subtitle / caption / lower-third / CTA / hero-word]
  Size:                [FILL]px        Weight: [FILL: 400 / 700 / variable axis]
  Reading budget:      [FILL]w -> hold [FILL]s = [FILL] frames   (from type_budget.js)
  Entrance:            [FILL: fade / rise+fade / word-by-word / pop / wipe]  over [FILL: 8-15] frames
  Exit:                [FILL: fade / cut-on-edit]  over [FILL: <=entrance] frames
  Property animated:   [FILL: opacity / opacity+translateY / scale]   (NO font-size/width)
  Accent (max one):    [FILL: none / weight 400->700 on word "X" / scale-up on "X"]
  Frame numbers:       enter@[FILL]

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

Captions From Transcript

Produce an accurate, properly timed caption track (SRT or WebVTT) from a video

Motion Design Principles

The craft layer for motion: pick the right easing (ease-in / ease-out / ease-in-out / spring), get timing and spacing right, build the anticipation→action→follow-through arc, and apply Disney

Narration Script

Write the spoken voiceover for a tutorial or demo - the actual words, phrased for the ear and synced one-instruction-per-action to what is on screen, with a pacing budget and a confident, jargon-checked tone. Use when someone says

Product Demo Director

Direct the craft of putting a real software UI on screen - cursor choreography, zoom/pan/callout language, screen-recording vs recreated-UI, and making state changes legible with highlights, focus pulls, and slow-downs. Use when filming or recreating an app for a product demo, feature walkthrough, onboarding clip, or release reel and asking

Remotion Compose

Turns a natural-language video brief into a complete, ready-to-preview Remotion composition - extracts duration, scenes, brand colors, aspect ratio, and real copy; plans the frame budget; and writes data-driven React/TypeScript using useCurrentFrame, interpolate, spring, AbsoluteFill, and Sequence, registered in Root.tsx. Use when someone says

Remotion Render

Renders a Remotion composition to MP4 and runs the edit-and-re-render loop - CLI render commands, 1080p/4K/9:16 presets, concurrency tuning, codec selection, batch variants from a JSON data file, and Lambda for cloud rendering. Use when someone says

Remotion Setup

Scaffolds a new Remotion video project wired for Claude Code Agent Skills - Node check, create-video scaffold, skills install, folder conventions, Google Fonts, and a smoke-test render. Use whenever someone wants to start making videos with Remotion and Claude, even just

Screencast Capture

Capture clean raw screen and camera footage for a tutorial or product demo - choosing the recorder (macOS Screenshot toolbar, QuickTime, OBS, Windows Game Bar), setting resolution / frame-rate / cursor / microphone, prepping a distraction-free stage, and recording in retakeable segments. Use when someone says

SkillMedev/tutorial-video-studio

Plan a product demo, feature announcement, or launch video as a beat sheet and shot list BEFORE animating - hook in the first 3s, problem, reveal, proof, CTA - with target duration and pacing per scene type, output as a JSON scene plan that remotion-compose consumes directly. Use when someone says

Social Video Formatter

Reframe and export a finished video for social platforms - 9:16 ↔ 16:9 cropping, burned-in captions, a platform-native first frame, loop design, and per-platform specs (aspect, length, safe areas) for TikTok, Reels, Shorts, X, and LinkedIn. Use when someone says

Sound and Music Sync

Score a video like an editor: beat-match cuts to the music, land SFX on transitions, pace the voiceover so it breathes, source royalty-free tracks safely, and duck the music so the VO sits clearly on top. Use when adding music, sound effects, or voiceover to a video, when asked to

관련 스킬