mcpField
K
kinetic-typography

kinetic-typography

github.com/iart-ai创意与媒体162.4k 次安装18 周前更新
代码仓库

关于 kinetic-typography

kinetic-typography 是一套动态文字设计技能,面向网页和视频标题、字幕及歌词动画制作。它涵盖逐行、逐词和逐字拆分与多种揭示效果,并提供可运行代码及无障碍和画面验证指导。

主要功能

  1. 01按行、词或字符拆分文本
  2. 02制作遮罩、模糊及剪切揭示效果
  3. 03为可变字体制作字重动画
  4. 04支持网页、Remotion 和 After Effects 方案
  5. 05提供无障碍与定格画面验证指导

适用场景

  1. 01制作网页标题和标语入场动画
  2. 02设计歌词视频与字幕揭示效果
  3. 03为可变字体添加动态效果
  4. 04制作文字沿路径移动或描边显现效果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/iart-ai/kinetic-typography-skills --skill kinetic-typography

安装后在 Claude Code 中输入/kinetic-typography确认已加载。

附带文件README.mdreferences/reveal-recipes.md

详细介绍

动态排版

富有表现力地为文本添加动画:将文案拆分为行、单词或字符,错开显示、遮罩、模糊、字重变形,并让文字沿路径运行。可生成适用于网页(CSS、GSAP、Framer Motion)和视频(Remotion)的可运行代码,另外还提供 After Effects 表达式方案。

适用场景

  • 标题/标语入场动画和动态标题卡片。
  • 歌词视频、字幕显示动画、动态排版作品。
  • 可变字体动画(字重、字宽、倾斜度、光学尺寸)。
  • 沿路径排布文字、描边绘制效果,以及逐字符变形效果。

核心工作流程

1. 先把静态排版做好

动画无法挽救糟糕的字体排版。开始动画前,先确定行高(展示型标题为 1.1-1.2,正文为 1.4-1.6)、字距(展示型文字收紧 -1% 到 -3%,例如 letter-spacing: -0.02em)、对齐方式和字重。然后再拆分并制作动画。

2. 选择拆分粒度
  • 按行 —— 最平静、最显高级;最适合多行段落和优雅的标题。
  • 按单词 —— 更有活力,适合标语和歌词重点。
  • 按字符 —— 动感最强、最活泼;长文案容易显得繁杂。仅用于短字符串。

工具:网页端使用 SplitType 或 GSAP SplitText;Remotion 中使用 .split('') / .split(' ') 加 interpolate;Framer Motion 中使用错开的 motion 子元素。

重要的无障碍提示:拆分为逐字符的 span 会破坏屏幕阅读器读取文本的效果,也会导致复制粘贴异常。务必在容器上设置包含完整字符串的 aria-label,并在拆分后的片段上设置 aria-hidden="true"。

3. 应用显示动画技巧

四种常用显示动画:

  • 遮罩/裁剪显示(最稳健) —— 将每一行包裹在 overflow: hidden 的容器中;让子元素从 translateY(100%) 动画到 0。文字从隐藏的基线向上擦入。没有模糊伪影,GPU 开销低,是行业标准的标题显示动画。
  • 模糊入场 —— 将 filter: blur(12px) -> blur(0) 与 opacity 0 -> 1 一起制作动画。效果柔和、高级,有“拉焦”感。渲染开销较大;请保持模糊半径适中,并优先使用较短时长。
  • clip-path 擦入 —— 将 clip-path: inset(0 100% 0 0) 动画到 inset(0 0 0 0),在不移动字形的情况下实现定向显示。
  • 字符错开 —— 拆分为字符后,逐个淡入/平移,每个字符间隔 20-40ms。
4. 遵循动效原则设置时序

内联的关键要点(确保本技能可独立使用):

  • 入场使用缓出:cubic-bezier(0.16, 1, 0.3, 1)(easeOutExpo)显得高级。
  • 每个片段的时长为 400-600ms。
  • 错开间隔:行与行之间为 60-100ms,单词之间为 40-70ms,字符之间为 20-40ms。
  • 将显示动画的总时长控制在约 800ms 以内;对于长字符串,请缩短逐字符间隔,或改用按单词/按行拆分。
5. 遮罩显示,可直接复制粘贴(原生 CSS + JS 行拆分)
<h1 class="reveal" aria-label="Designed for motion">Designed for motion</h1>
.reveal .line { overflow: hidden; }
.reveal .line > span {
  display: inline-block;
  transform: translateY(110%);
  animation: rise 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.reveal .line:nth-child(2) > span { animation-delay: 0.08s; }
.reveal .line:nth-child(3) > span { animation-delay: 0.16s; }
@keyframes rise { to { transform: translateY(0); } }
6. 可变字体字重动画
@keyframes thicken {
  from { font-variation-settings: "wght" 200; }
  to   { font-variation-settings: "wght" 800; }
}
.headline {
  font-family: "Inter var", sans-serif;
  animation: thicken 0.8s cubic-bezier(0.65, 0, 0.35, 1) forwards;
}

为 font-variation-settings 制作动画(可涵盖任意轴:wght、wdth、slnt、opsz 以及自定义轴),不要使用 font-weight,这样才能使用非标准值并实现平滑插值。开始动画前,请确认已加载的字体确实是可变字体,并检查轴的取值范围(例如 wght 100-900),否则该值会被静默限制。

交付与验证(独立 HTML)

打包的辅助脚本(scripts/):scripts/seek-shot.sh anim.html 0 1.5 3 会冻结 ?t=N 测试框架并截取每个时刻的画面;scripts/contact-sheet.sh sheet.png frame-*.png 会将它们拼成一张图,便于一目了然地检查。参阅 scripts/README.md。

对于网页文字显现/动态标题交付物,请提供一个可直接在浏览器中打开的 .html 文件——无需构建步骤。对于标题、标题卡或单次显现效果,一个文件就足够。

输出约定:

  • 一个 .html 文件:标记中,容器带有 aria-label;显现效果写在内联 <style> 中(或使用一个来自 CDN 的内联 GSAP <script>)。
  • 一个动画驱动方式——CSS @keyframes 显现效果,或单个 GSAP 时间轴;不要两者兼用。
  • 加入下方的冻结测试框架,以便确定性地截取任意时刻的画面。
  • 在 document.fonts.ready 之后进行拆分,以确保冻结帧中的换行正确。

冻结测试框架——固定帧以供截图。

<script>
  const t = new URLSearchParams(location.search).get("t");
  if (t !== null) {
    // CSS @keyframes reveal:
    document.querySelectorAll(".reveal *").forEach(el => {
      el.style.animationDelay = (-parseFloat(t)) + "s";
      el.style.animationPlayState = "paused";
    });
    // GSAP timeline instead? → tl.pause(); tl.seek(parseFloat(t));
  }
  window.__ready = true;                                          // ready signal for headless wait
</script>

验证流程——渲染 → 冻结 → 截图 → 检查:

  1. 打开文件并冻结在开始/中间/结束时刻:…/type.html?t=0、?t=<dur/2>、?t=<dur>。
  2. 为每个冻结帧截图。
  3. 检查保真度(是否符合需求说明)和瑕疵——字形/下伸部被裁切、遮罩未能完全隐藏基线、字体加载前出现 FOUC 或换行错误、模糊边缘。
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/type.html?t=0.4" frame-mid.png

完成前:

  1. 可在浏览器中独立打开——没有控制台错误,也没有缺失的 CDN/字体。
  2. 只有一个显现驱动方式;?t=N 能正确冻结精确帧。
  3. 已在开始/中间/结束时刻截图——没有字形被裁切或 FOUC,换行正确。
  4. 遵循 prefers-reduced-motion(文本显示为最终状态,不播放动画)。
  5. 容器带有 aria-label;拆分片段带有 aria-hidden——复制内容和屏幕阅读器文本保持完整。

快速参考

效果核心 CSS/实现方式
向上遮罩显现父元素设为 overflow:hidden;子元素 translateY(110%)->0
模糊显现filter: blur(12px)->0 + 透明度
定向擦除clip-path: inset(0 100% 0 0)->inset(0)
字符错开拆分字符,间隔 20-40ms,淡入并上移
可变字重动画化 font-variation-settings:"wght" a->b
沿路径排布文本SVG <textPath href="#curve">
描边绘制将 SVG 文本设为路径,动画化 stroke-dashoffset

沿路径排布文本(SVG)

<svg viewBox="0 0 600 200">
  <path id="curve" d="M20,150 Q300,20 580,150" fill="none" />
  <text font-size="42" fill="#fff">
    <textPath href="#curve" startOffset="0%">Follow the curve</textPath>
  </text>
</svg>

动画化 startOffset 属性(0% -> 100%)可让文本沿路径滚动;也可以动画化路径 d,让文本沿变形曲线流动。

参考文件

  • references/reveal-recipes.md — 可直接复制粘贴的显现效果指南:CSS 中的遮罩/模糊/裁剪/字符错开、GSAP SplitText 时间轴、Framer Motion 错开变体、Remotion 逐字符插值、可变字体关键帧,以及对屏幕阅读器友好的拆分辅助函数。

评论

支持 Markdown