color-motion

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Color in Motion

动态中的色彩

Choose, pair, and animate color for motion design: building restrained palettes, constructing gradients that read as premium, interpolating colors in perceptually-uniform spaces, and grading a piece for mood and consistency. Produces palettes with exact OKLCH/hex values, gradient CSS/code, and transition parameters.
为动态设计选择、配对并动画化色彩:构建克制的配色方案、打造质感高级的渐变、在感知均匀空间中插值颜色,并针对氛围与一致性对作品进行调色。输出包含精确 OKLCH/hex 值的配色方案、渐变 CSS/代码以及过渡参数。

When to use

使用场景

  • Picking or pairing a palette for a motion or video piece.
  • Building gradient backgrounds (mesh, noise, animated drift).
  • Animating color transitions (button states, theme switch, loaders).
  • Grading a video for mood, or fixing dull/gray gradient interpolation.
  • Fixing washed-out, gamma-shifted, or platform-inconsistent After Effects renders, and choosing correct per-platform export/color tags.
  • 为动态或视频作品挑选或搭配配色方案。
  • 构建渐变背景(网格、噪点、动态漂移)。
  • 制作颜色过渡动画(按钮状态、主题切换、加载动画)。
  • 为视频营造氛围而调色,或修复暗淡/灰色的渐变插值。
  • 修复发灰、gamma shift 或存在平台差异的 After Effects 渲染结果,并选择正确的各平台导出方式/颜色标签。

Core techniques

核心技术

1. Build a restrained palette

1. 构建克制的配色方案

Limit hues. A strong motion palette is 1 primary + 1 accent + 2-3 neutrals. Derive contrast and depth from lightness and chroma, not from adding more hues. Extra hues fight for attention and read as amateur.
In dark scenes, make the accent pop with low-to-moderate chroma and high lightness rather than maximum saturation — a blown-out saturated accent vibrates and looks cheap on dark backgrounds.
Use OKLCH to reason about color:
oklch(L C H)
where L is perceptual lightness (0-1), C is chroma (0 ≈ 0.37 max), H is hue angle (0-360). Holding L and C constant while rotating H gives hues of genuinely equal visual weight — impossible to do reliably in HSL.
Primary:   oklch(0.62 0.19 264)   /* confident blue */
Accent:    oklch(0.78 0.17 50)    /* warm amber, lighter so it pops */
Neutral-0: oklch(0.97 0.005 264)  /* near-white, faint hue tint */
Neutral-1: oklch(0.55 0.01 264)
Neutral-2: oklch(0.18 0.015 264)  /* near-black, same hue family */
Tinting neutrals slightly toward the primary hue (tiny chroma) unifies the frame; pure gray neutrals next to colored elements look disconnected.
限制色相数量。出色的动态配色方案应采用 1 个主色 + 1 个强调色 + 2–3 个中性色。通过亮度和彩度,而非增加更多色相,来营造对比度与层次感。额外的色相会争夺注意力,并显得业余。
在深色场景中,应让强调色凭借低至中等彩度和较高亮度突出,而不是使用最高饱和度——过饱和的强调色会产生刺眼的震颤感,在深色背景上显得廉价。
使用 OKLCH 分析颜色:
oklch(L C H)
,其中 L 是感知亮度(0-1),C 是彩度(0 ≈ 0.37 max),H 是色相角度(0-360)。保持 L 和 C 不变并旋转 H,可得到视觉权重真正相等的色相——用 HSL 无法可靠实现这一点。
Primary:   oklch(0.62 0.19 264)   /* confident blue */
Accent:    oklch(0.78 0.17 50)    /* warm amber, lighter so it pops */
Neutral-0: oklch(0.97 0.005 264)  /* near-white, faint hue tint */
Neutral-1: oklch(0.55 0.01 264)
Neutral-2: oklch(0.18 0.015 264)  /* near-black, same hue family */
将中性色略微向主色相染色(使用极低彩度)可统一画面;彩色元素旁的纯灰中性色会显得脱节。

2. Interpolate in OKLCH or Lab — never raw sRGB

2. 在 OKLCH 或 Lab 中插值——绝不直接在原始 sRGB 中插值

Linearly interpolating two colors in sRGB passes through a desaturated, often gray or muddy midpoint (blue->yellow goes through gray; blue->red through muddy purple). Perceptual spaces (OKLCH, OKLab, CIE Lab) keep midpoints vivid and lightness even.
CSS gradients support this natively:
css
/* Vivid, even midpoint */
background: linear-gradient(in oklch, #2b6cff, #ffb02e);

/* Control hue path around the wheel for two-stop gradients */
background: linear-gradient(in oklch longer hue, #2b6cff, #ffb02e);
background: conic-gradient(in oklch, red, blue, red);
For animated transitions interpolate with a library (see references) and emit per-frame colors, or for two-color CSS transitions register a typed custom property so the browser interpolates in the chosen space.
在 sRGB 中对两种颜色进行线性插值,会经过一个去饱和的中点,而这个中点通常是灰色或浑浊色(蓝色->黄色会经过灰色;蓝色->红色会经过浑浊的紫色)。感知空间(OKLCH、OKLab、CIE Lab)能让中点保持鲜明,并保持亮度均匀。
CSS 渐变原生支持这一点:
css
/* Vivid, even midpoint */
background: linear-gradient(in oklch, #2b6cff, #ffb02e);

/* Control hue path around the wheel for two-stop gradients */
background: linear-gradient(in oklch longer hue, #2b6cff, #ffb02e);
background: conic-gradient(in oklch, red, blue, red);
对于动画过渡,可使用库进行插值(参见参考资料)并输出逐帧颜色;对于双颜色 CSS 过渡,可注册一个带类型的自定义属性,让浏览器在所选空间中插值。

3. Gradients that read as premium

3. 打造质感高级的渐变

  • Mesh / multi-radial: stack several
    radial-gradient
    s at different positions over a base color. Soft, organic, expensive-looking.
  • Add grain: a faint noise overlay (SVG
    feTurbulence
    or a tiled PNG at ~3-5% opacity) kills banding and adds texture.
  • Animate slowly: drift gradient positions over 8-20s with
    ease-in-out alternate
    . Slow is premium; fast gradient motion looks like a screensaver.
css
.mesh {
  background-color: #0b0f1a;
  background-image:
    radial-gradient(at 20% 25%, oklch(0.62 0.19 264 / 0.7), transparent 50%),
    radial-gradient(at 80% 30%, oklch(0.70 0.16 320 / 0.6), transparent 55%),
    radial-gradient(at 50% 85%, oklch(0.78 0.17 50  / 0.5), transparent 50%);
  animation: drift 16s ease-in-out infinite alternate;
}
@keyframes drift {
  to { background-position: 8% -6%, -8% 6%, 4% 8%; }
}
  • 网格 / 多重径向渐变:在基础色上,将多个位于不同位置的
    radial-gradient
    叠加起来。效果柔和自然且富有高级感。
  • 添加颗粒:叠加一层极淡的噪点(SVG
    feTurbulence
    ,或约 3–5% 不透明度的平铺 PNG)可消除色带并增加纹理。
  • 缓慢动画:在 8–20 秒内使用
    ease-in-out alternate
    让渐变位置缓慢漂移。慢即高级;渐变运动过快会像屏保。
css
.mesh {
  background-color: #0b0f1a;
  background-image:
    radial-gradient(at 20% 25%, oklch(0.62 0.19 264 / 0.7), transparent 50%),
    radial-gradient(at 80% 30%, oklch(0.70 0.16 320 / 0.6), transparent 55%),
    radial-gradient(at 50% 85%, oklch(0.78 0.17 50  / 0.5), transparent 50%);
  animation: drift 16s ease-in-out infinite alternate;
}
@keyframes drift {
  to { background-position: 8% -6%, -8% 6%, 4% 8%; }
}

4. Color transition animation

4. 颜色过渡动画

Inline timing essentials so this skill stands alone: enter/highlight with ease-out (
cubic-bezier(0.16, 1, 0.3, 1)
), state changes 150-300ms, theme/full-screen washes 400-800ms. Use
linear
only for continuous loops.
css
@property --c { syntax: "<color>"; initial-value: #2b6cff; inherits: false; }
.btn { background: var(--c); transition: --c 200ms cubic-bezier(0.16,1,0.3,1); }
.btn:hover { --c: #ffb02e; }
@property
registration is what makes the color actually interpolate (unregistered custom properties jump instantly).
为使此 skill 可独立使用,这里给出关键时序参数:进入/高亮使用 ease-out(
cubic-bezier(0.16, 1, 0.3, 1)
),状态变化为 150–300ms,主题/全屏色彩覆盖为 400–800ms。仅在连续循环中使用
linear
。
css
@property --c { syntax: "<color>"; initial-value: #2b6cff; inherits: false; }
.btn { background: var(--c); transition: --c 200ms cubic-bezier(0.16,1,0.3,1); }
.btn:hover { --c: #ffb02e; }
正是
@property
注册让颜色能够真正插值(未注册的自定义属性会瞬间跳变)。

5. Grade for mood — correct order

5. 按正确顺序为氛围调色

Apply grading operations in this order; reordering changes the result:
  1. Exposure / white balance — fix overall brightness and neutralize/intentionally set the cast first.
  2. Contrast — set black and white points; expand or compress the tonal range.
  3. Midtones / saturation — adjust overall saturation and midtone color.
  4. Split-tone — tint shadows and highlights separately. The classic cinematic look is teal shadows + orange highlights (complementary, flatters skin). Keep it subtle.
  5. Unify — a final overall tint/LUT and a subtle vignette to bind the frame.
In code, grade by chaining CSS filters or a fragment shader; for video, an actual LUT or grading panel. Always grade the whole piece consistently so shots cut together.
按以下顺序执行调色操作;调整顺序会改变结果:
  1. 曝光 / 白平衡 —— 先修正整体亮度,并将色偏中性化或有意设定。
  2. 对比度 —— 设置黑场和白场;扩展或压缩色调范围。
  3. 中间调 / 饱和度 —— 调整整体饱和度和中间调颜色。
  4. 分离色调 —— 分别给阴影和高光着色。经典电影感是青色阴影 + 橙色高光(互补色,更能衬托肤色)。应保持微妙。
  5. 统一 —— 最后添加整体色调/LUT 和轻微暗角,将画面统一起来。
在代码中,可通过串联 CSS filter 或 fragment shader 进行调色;对于视频,则使用真正的 LUT 或调色面板。始终对整个作品统一调色,以确保各镜头剪辑在一起时保持一致。

6. Video / render color management

6. 视频 / 渲染色彩管理

When a render looks correct in the After Effects comp viewer but washed-out, too bright, milky, or gamma-shifted in QuickTime, a browser, or across macOS/Windows, the cause is a gamma/transfer mismatch across four stages — AE working space, the render's embedded tag, the player's interpretation, and the display/OS gamma — not the artwork.
Core rules:
  • Set an explicit working space. File > Project Settings > Color tab: Working Space = Rec.709 Gamma 2.4 for SDR video (or sRGB for UI/stills); "None" disables color management and the viewer lies about the final look. Set Depth to 16 bpc for grades/gradients to avoid banding.
  • Rec.709 vs sRGB. They share primaries but differ in transfer (sRGB ~2.2 piecewise vs Rec.709 display 2.4 / BT.1886). Using the wrong one shifts midtone brightness — Rec.709 for video, sRGB for screenshots/PNG/UI.
  • Embed a color tag on export. The shift across macOS/Windows/players comes from untagged files; each player guesses its own default. Tag Rec.709 (or sRGB) explicitly via Render Queue > Output Module > Color Management (do not leave "Preserve RGB" when a shift occurs).
  • The QuickTime gamma bug. QuickTime/AVFoundation apply an extra ~1.96 gamma, so a file can look fine in QuickTime but dark/contrasty in Chrome. Never grade or approve to QuickTime — Chrome, Premiere, or Resolve is the correct reference for web delivery.
  • Match preview to final. Toggle "Use Display Color Management" in the comp viewer while reviewing, and verify the export numerically: place a 50% grey (RGB 128) patch, render, re-sample — a value that rises (128 → 150+) confirms a washed-out gamma shift. Confirm the embedded tag with
    ffprobe
    (
    color_primaries
    /
    color_transfer
    /
    color_space
    = bt709).
Per-platform export at a glance: ProRes 422 HQ/4444 tagged Rec.709 for editing masters; H.264 (MP4) tagged Rec.709 for web/
<video>
/social (verify in Chrome); ProRes 4444 + alpha → PNG (sRGB) for transparency; ProRes 4444 / HEVC 10-bit Rec.2020 PQ/HLG for HDR (needs 32 bpc float).
See
references/color-management.md
for the full diagnosis decision tree, exact menu paths, per-platform export table, the QuickTime workarounds, per-OS/player gamma values, the numeric test-patch method,
ffprobe
/
ffmpeg
tag commands, limited-vs-full-range pitfalls, and the pre-export checklist.
当渲染结果在 After Effects 合成查看器中看起来正确,但在 QuickTime、浏览器或 macOS/Windows 上显得发灰、过亮、乳白或出现 gamma shift 时,问题通常源于以下四个阶段之间的 gamma/传输函数不匹配——AE 工作空间、渲染文件中嵌入的标签、播放器的解释方式以及显示器/操作系统的 gamma——而不是作品本身。
核心规则:
  • 设置明确的工作空间。 File > Project Settings > Color tab:将 Working Space 设为 SDR 视频使用 Rec.709 Gamma 2.4(或 UI/静态图像使用 sRGB);“None”会禁用色彩管理,导致查看器无法呈现最终效果。调色/渐变应将 Depth 设为 16 bpc,以避免色带。
  • Rec.709 与 sRGB。 两者使用相同的基色,但传输函数不同(sRGB 约 2.2,使用分段函数;Rec.709 显示为 2.4 / BT.1886)。使用错误的标准会改变中间调亮度——视频使用 Rec.709,截图/PNG/UI 使用 sRGB。
  • 导出时嵌入颜色标签。 macOS/Windows/播放器之间出现的偏移源于未带标签的文件;每个播放器都会猜测自己的默认值。通过 Render Queue > Output Module > Color Management 明确标记 Rec.709(或 sRGB)(发生偏移时,不要保留“Preserve RGB”)。
  • QuickTime gamma 缺陷。 QuickTime/AVFoundation 会额外应用约 1.96 的 gamma,因此文件在 QuickTime 中看起来正常,到了 Chrome 中却可能偏暗、对比度过高。切勿以 QuickTime 作为调色或验收基准——面向 web 交付时,应以 Chrome、Premiere 或 Resolve 为准。
  • 让预览与最终效果一致。 审阅时,在合成查看器中切换“Use Display Color Management”,并以数值方式验证导出结果:放置一个 50% 灰色(RGB 128)色块,渲染后重新采样;若数值升高(128 → 150+),则表明存在发灰的 gamma shift。使用
    ffprobe
    确认嵌入的标签(
    color_primaries
    /
    color_transfer
    /
    color_space
    = bt709)。
各平台导出概览:用于编辑母版的 ProRes 422 HQ/4444 应标记为 Rec.709;用于 web/
<video>
/社交媒体的 H.264 (MP4) 应标记为 Rec.709(在 Chrome 中验证);ProRes 4444 + alpha → PNG (sRGB) 用于透明图像;用于 HDR 的 ProRes 4444 / HEVC 10-bit Rec.2020 PQ/HLG(需要 32 bpc float)。
有关完整诊断决策树、精确菜单路径、各平台导出表、QuickTime 变通方案、各 OS/播放器 gamma 数值、数值测试色块方法、
ffprobe
/
ffmpeg
标签命令、有限范围与全范围陷阱,以及导出前检查清单,请参阅
references/color-management.md
。

Deliver & verify (standalone HTML)

交付与验证(独立 HTML)

Packaged helper (
scripts/
):
scripts/seek-shot.sh anim.html 0 1.5 3
freezes the
?t=N
harness and screenshots each moment;
scripts/contact-sheet.sh sheet.png frame-*.png
tiles them for one-glance review. See
scripts/README.md
.
For a web palette/gradient/color-transition deliverable, ship one
.html
file that opens directly in a browser
— no build step. CSS handles the color work; the file is self-contained.
Output contract:
  • One
    .html
    file: your markup + the gradient/transition in inline
    <style>
    (CDN only if a JS interpolation lib is needed).
  • One animation driver — a CSS
    @keyframes
    drift or a single
    @property
    transition; nothing competing.
  • Include the freeze harness below so any moment can be screenshotted deterministically.
Freeze harness — pin a CSS-animation frame for screenshots.
?t=N
sets a negative
animation-delay
and pauses, so the gradient/transition lands on the exact frame at
N
seconds.
html
<script>
  const t = new URLSearchParams(location.search).get("t");
  if (t !== null) {
    document.querySelectorAll(".bg, .btn").forEach(el => {       // animated elements
      el.style.animationDelay = (-parseFloat(t)) + "s";
      el.style.animationPlayState = "paused";
    });
  }
  window.__ready = true;                                          // ready signal for headless wait
</script>
Verify loop — render → freeze → screenshot → check:
  1. Open the file frozen at start / mid / end:
    …/color.html?t=0
    ,
    ?t=<period/2>
    ,
    ?t=<period>
    .
  2. Screenshot each frozen frame.
  3. Check fidelity (matches the palette/brief) and color artifacts — at each frozen frame confirm the gradient/transition has no banding and no muddy or gray midpoint (the OKLCH/Lab path stays vivid). Add grain if banding appears.
  4. Iterate: if banding or a muddy/gray midpoint shows up, adjust the OKLCH/Lab chroma & lightness (or add grain), re-render the same
    ?t=N
    , and re-screenshot to confirm the fix — loop until every frozen frame is clean.
bash
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/color.html?t=8" frame-mid.png
Before you finish:
  1. Opens standalone in a browser — no console errors, no missing CDN.
  2. One color driver;
    ?t=N
    freezes the exact frame correctly.
  3. Screenshotted at start / mid / end — no banding, no muddy/gray midpoints, lightness even.
  4. prefers-reduced-motion
    honored (drift paused on a static, readable frame).
  5. Interpolation is in OKLCH/Lab (gradients/
    @property
    ), never raw sRGB.
打包辅助工具(
scripts/
):
scripts/seek-shot.sh anim.html 0 1.5 3
会冻结
?t=N
测试工具并截取每个时刻的画面;
scripts/contact-sheet.sh sheet.png frame-*.png
将这些画面拼接成一张便于快速审阅的图。参见
scripts/README.md
。
针对 web 配色方案/渐变/颜色过渡交付物,应提供一个可直接在浏览器中打开的
.html
文件
——无需构建步骤。CSS 负责颜色处理;文件应为自包含文件。
输出约定:
  • 一个
    .html
    文件:包含标记以及内联
    <style>
    中的渐变/过渡(仅当需要 JS 插值库时才使用 CDN)。
  • 一个动画驱动方式——CSS
    @keyframes
    漂移动画或单个
    @property
    过渡;不得使用相互竞争的动画。
  • 包含下方的冻结测试工具,以便可确定地为任意时刻生成屏幕截图。
冻结测试工具——为屏幕截图锁定 CSS 动画帧。
?t=N
会设置负的
animation-delay
并暂停动画,使渐变/过渡精确落在 N 秒对应的帧上。
html
<script>
  const t = new URLSearchParams(location.search).get("t");
  if (t !== null) {
    document.querySelectorAll(".bg, .btn").forEach(el => {       // animated elements
      el.style.animationDelay = (-parseFloat(t)) + "s";
      el.style.animationPlayState = "paused";
    });
  }
  window.__ready = true;                                          // ready signal for headless wait
</script>
验证循环——渲染 → 冻结 → 截图 → 检查:
  1. 打开冻结在起始 / 中间 / 结束时刻的文件:
    …/color.html?t=0
    、
    ?t=<period/2>
    、
    ?t=<period>
    。
  2. 截取每个冻结帧的屏幕截图。
  3. 检查保真度(是否符合配色方案/需求)和颜色伪影——在每个冻结帧中确认渐变/过渡没有色带,也没有浑浊或灰色中点(OKLCH/Lab 路径应保持鲜明)。如果出现色带,请添加颗粒。
  4. 迭代:如果出现色带或浑浊/灰色中点,请调整 OKLCH/Lab 的彩度与亮度(或添加颗粒),重新渲染同一个
    ?t=N
    ,并重新截图确认修复——循环直到每个冻结帧都干净。
bash
npx playwright screenshot --wait-for-timeout=500 "file://$PWD/color.html?t=8" frame-mid.png
完成前:
  1. 可在浏览器中独立打开——无控制台错误,无缺失的 CDN。
  2. 仅使用一种颜色驱动方式;
    ?t=N
    能正确冻结目标帧。
  3. 已截取起始 / 中间 / 结束帧——无色带、无浑浊或灰色中点,亮度均匀。
  4. 遵循
    prefers-reduced-motion
    (将漂移动画暂停在静态且清晰可读的帧上)。
  5. 在 OKLCH/Lab 中进行插值(渐变/
    @property
    ),绝不直接在原始 sRGB 中插值。

Quick reference

快速参考

NeedDo
Palette size1 primary + 1 accent + 2-3 neutrals
Equal-weight hueshold L,C in OKLCH, vary H
Vivid gradient
linear-gradient(in oklch, ...)
Smooth color animinterpolate in OKLCH/Lab, register via
@property
Premium bgstacked radials + grain + 8-20s slow drift
Cinematic gradeteal shadows / orange highlights, subtle
Fix washed-out AE rendertag Rec.709 in Output Module > Color Management; verify in Chrome
Avoidraw-sRGB interpolation (muddy midpoints); grading to QuickTime
需求做法
配色方案规模1 个主色 + 1 个强调色 + 2–3 个中性色
视觉权重相等的色相在 OKLCH 中保持 L、C 不变,仅改变 H
鲜明渐变
linear-gradient(in oklch, ...)
流畅的颜色动画在 OKLCH/Lab 中插值,通过
@property
注册
高级感背景叠加径向渐变 + 颗粒 + 8–20 秒缓慢漂移
电影感调色青色阴影 / 橙色高光,保持微妙
修复发灰的 AE 渲染在 Output Module > Color Management 中标记 Rec.709;在 Chrome 中验证
避免原始 sRGB 插值(浑浊中点);以 QuickTime 为调色基准

Reference files

参考文件

  • references/palettes-and-interpolation.md
    — palette construction rules with OKLCH values and named recipes, gradient cookbook (mesh, conic, grain), culori and d3-interpolate code for perceptual interpolation and scales, and the full grading-order checklist with filter/shader examples.
  • references/color-management.md
    — full video/render color management: diagnosis decision tree, AE project/output color settings with exact menu paths, per-platform export table, QuickTime gamma-bug workarounds, per-OS/player gamma values, the numeric test-patch method,
    ffprobe
    /
    ffmpeg
    tag verification, limited-vs-full-range pitfalls, and the pre-export checklist.
  • references/palettes-and-interpolation.md
    —— 配色方案构建规则,包含 OKLCH 数值和命名配方、渐变配方手册(网格、conic、grain)、用于感知插值与色阶的 culori 和 d3-interpolate 代码,以及包含 filter/shader 示例的完整调色顺序检查清单。
  • references/color-management.md
    —— 完整的视频/渲染色彩管理指南:诊断决策树、含精确菜单路径的 AE 项目/输出颜色设置、各平台导出表、QuickTime gamma 缺陷变通方案、各 OS/播放器 gamma 数值、数值测试色块方法、
    ffprobe
    /
    ffmpeg
    标签验证、有限范围与全范围陷阱,以及导出前检查清单。