04-动效物理学、着色器与环境光影
第四篇:动效物理学、着色器与环境光影
技术领域与英文指代:
Motion Physics, Shaders & Ambient Systems逆向工程溯源:基于 REA (Reverse Engineer Anything) v6.5.0 提取自 macOS 生产包/Applications/Claude.app(@ant/desktop v2.37337.1,Build 时间戳2026-10-13T22:16:06Z),深度解构核心样式资产c6a992d55-sXiDGMFQ.css、frame-window-BEI3vR8Q.css以及运行时内核shared-frame-BfjMqbuN.js。
4.1 全量动效引擎与关键帧规范
技术领域与英文指代:
Motion Engine, CSS Houdini & Spring Presets
4.1.1 核心 CSS 关键帧全集 (@keyframes)
以下关键帧经 REA 从 c6a992d55-sXiDGMFQ.css 完整反编译提取,杜绝任何参数猜测:
/* 1. 字符流式晕染输出 (Grapheme Blur Reveal) */
@keyframes _grapheme-reveal_1plog_1 {
0% { opacity: 0; filter: blur(6px); }
100% { opacity: 1; filter: blur(0); }
}
/* 2. 思考三点跳跃循环 (Quiet Dots Wave - 周期 1.9s) */
@keyframes timeline-quiet-dot {
0%, 8% { opacity: 0; transform: translateY(2px); }
22% { opacity: 1; transform: translateY(-2.5px); }
36%, 70% { opacity: 1; transform: translateY(0); }
90%, 100%{ opacity: 0; transform: translateY(0); }
}
/* 3. 消息气泡微弹进入 (Message Fade Up) */
@keyframes message-fade-up {
0% { opacity: 0; transform: translateY(10px); }
100% { opacity: 1; transform: translateY(0); }
}
/* 4. 用户气泡发送微缩放进入 (User Bubble Enter) */
@keyframes code-user-bubble-enter {
0% { opacity: 0; transform: scale(0.92) translateY(6px); }
100% { opacity: 1; transform: none; }
}
/* 5. 复制对勾衰减消退 (Check Decay - 2.5s 缓动) */
@keyframes saved-check-decay {
0%, 75% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(0.92); }
}
/* 6. 骨架屏高级倾斜扫光 (Skeleton Sweep - 2.0s 线性) */
@keyframes cds-skeleton-sweep {
0% { transform: translate(-100%); }
100% { transform: translate(100%); }
}
/* 7. 分段滑块加载中微呼吸 */
@keyframes df-pill-pending {
to { opacity: 0.45; }
}
/* 8. 附件磁贴入场放大 (File Thumbnail Grow) */
@keyframes file-thumbnail-grow-in {
0% { opacity: 0; transform: scale(0.85); }
100% { opacity: 1; transform: scale(1); }
}4.1.2 可变字形动效引擎 (Variable Font Kinetic Engine)
在 Claude 桌面端中,大量图标微交互并非传统的 SVG 变形或 PNG 替换,而是构建在 CSS Houdini Properties & Values API 与可变字体轴(Variable Font Axes ANIM / ANM2)之上的字形物理驱动引擎(取证自 c6a992d55-sXiDGMFQ.css):
/* 1. 注册原生数值可动画自定义属性 */
@property --cds-anim {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --cds-anim2 {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
/* 2. 字体变异轴驱动核心规则 */
[data-cds-anim] {
--cds-anim: 0;
--cds-anim2: 0;
font-variation-settings:
"opsz" var(--cds-opsz, 20),
"wght" var(--cds-wght, 400),
"ANIM" var(--cds-anim),
"ANM2" var(--cds-anim2);
transition: --cds-anim var(--cds-anim-dur-out, var(--cds-anim-dur, 0.3s))
var(--cds-anim-ease, cubic-bezier(0.34, 1.3, 0.64, 1));
}
/* 3. 循环动效关键帧 */
@keyframes cds-anim-loop {
0%, 49.99% { --cds-anim2: 0; }
50%, 100% { --cds-anim2: 100; }
}
/* 4. 交互触发绑定:Focus 与 Hover 阶梯驱动 */
@media (prefers-reduced-motion: no-preference) {
.group:focus-visible [data-cds-anim],
[data-cds-anim]:focus-visible,
.group:has(:focus-visible) [data-cds-anim] {
--cds-anim: 100;
transition-duration: var(--cds-anim-dur, 0.3s);
}
.group:focus-visible [data-cds-anim-loop],
[data-cds-anim-loop]:focus-visible,
.group:has(:focus-visible) [data-cds-anim-loop] {
animation: 1s linear 0.1s infinite cds-anim-loop;
}
@media (hover: hover) {
.group:hover [data-cds-anim],
[data-cds-anim]:hover {
--cds-anim: 100;
transition-duration: var(--cds-anim-dur, 0.3s);
}
.group:hover [data-cds-anim-loop],
[data-cds-anim-loop]:hover {
animation: 1s linear 0.1s infinite cds-anim-loop;
}
}
}物理质感剖析:
--cds-anim-ease严格绑定--cds-ease-overshoot(即cubic-bezier(0.34, 1.3, 0.64, 1)),使得图标在触发动效时,字形骨架产生 +30% 的机械弹性过冲,随后收敛至稳定态,呈现出独特的机械微动触感。
4.1.3 生产级 Framer Motion 物理弹簧参数矩阵 (Spring Physics Presets)
Claude 在复杂手势吸附、弹出展开与交互响应中采用物理弹簧动效(Framer Motion Spring),基于经典二阶微分方程阻尼振子模拟: $$m \frac{d^2 x}{dt^2} + c \frac{dx}{dt} + k (x - x_{\text{target}}) = 0$$
其中阻尼比 $\zeta = \frac{c}{2\sqrt{m k}}$ 决定了运动的质感形态:
| 预设方案代号 | 刚度 (stiffness) | 阻尼 (damping) | 质量 (mass) | 阻尼比 $\zeta$ | 超调量 (Overshoot) | 收敛时间 | 核心应用场景与物理质感 |
|---|---|---|---|---|---|---|---|
| Button & Small Controls | 600 | 30 | 1.0 | 0.612 (欠阻尼) | +8.8% | 0.22s | 按钮点击、开关切换、图标按压。高频微弹,利落归位无粘滞。 |
| Card / Popover Reveal | 320 | 28 | 1.0 | 0.783 (欠阻尼) | +1.8% | 0.35s | 消息上浮、卡片展开、气泡悬浮窗。沉稳顺滑,微冲后平稳着陆。 |
| Bouncy Light Feedback | 380 (或 dur 0.32) | 18 (或 bounce 0.15) | 1.0 | 0.462 (明显欠阻尼) | +19.4% | 0.58s | 点赞、复制成功勾选、新消息微提示。明显两周期弹簧跳跃感。 |
| High Damping Panel Drag | 1200 | 80 | 0.1 | 3.650 (过阻尼) | 0% (绝对零过冲) | 0.14s | 侧边栏与浮层手势拖拽吸附。超高刚度与阻尼,松手瞬间极速绝对咬合。 |
生产级动效常数与 Hook 实现:
code-examples/ClaudeMotionPresets.ts。
4.2 动态光效、着色器与推理氛围感
技术领域与英文指代:
Ambient Shimmer, Glow & Pulse
4.2.1 生产级动态光波着色器提取 (c6a992d55-sXiDGMFQ.css)
在官方混淆样式表 c6a992d55-sXiDGMFQ.css 中提取出的官方核心关键帧与光场着色规则:
/* 1. 官方文本渐变光波扫描 (Shimmer Text Shine) */
@keyframes cds-shimmer-text-shine {
0%, 15% {
background-position: 83.333% 0;
animation-timing-function: cubic-bezier(0.714, 0.121, 0.211, 0.888);
}
85%, 100% {
background-position: 16.667% 0;
}
}
/* 官方高对比扫光增强版 (Shimmer Text Shine Strong) */
@keyframes cds-shimmer-text-shine-strong {
0%, 5% {
background-position: 83.333% 0;
animation-timing-function: cubic-bezier(0.4, 0.15, 0.6, 0.85);
}
95%, 100% {
background-position: 16.667% 0;
}
}
/* 2. 官方深度思考光晕脉冲 (wl-glow) - 周期 1.8s ease-in-out */
@keyframes wl-glow {
0%, 100% {
box-shadow:
0 10px 15px -3px #0000001a,
0 4px 6px -4px #0000001a,
0 0 0 2px var(--cds-fill-brand),
0 0 14px 3px color-mix(in srgb, var(--cds-fill-brand) 60%, transparent);
}
50% {
box-shadow:
0 10px 15px -3px #0000001a,
0 4px 6px -4px #0000001a,
0 0 0 2px var(--cds-fill-brand),
0 0 16px 5px color-mix(in srgb, var(--cds-fill-brand) 85%, transparent);
}
}
/* 3. 官方光晕外圈脉冲 (wl-halo) - 周期 2.2s ease-in-out */
@keyframes wl-halo {
0%, 100% {
box-shadow:
0 0 0 2px var(--cds-fill-brand),
0 0 14px 3px color-mix(in srgb, var(--cds-fill-brand) 60%, transparent);
}
50% {
box-shadow:
0 0 0 2px var(--cds-fill-brand),
0 0 16px 5px color-mix(in srgb, var(--cds-fill-brand) 85%, transparent);
}
}
/* 4. 官方三点差分跳跃脉冲 (cds-dot-pulse - 周期 1.8s) */
@keyframes cds-dot-pulse {
0%, 5% {
opacity: 0.2857;
animation-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
}
15%, 25% {
opacity: 1;
animation-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
}
65%, 100% {
opacity: 0.2857;
}
}
/* 5. 官方线性扫光条 (Epitaxy Linear Sweep - 严格 1.1s cubic-bezier(.45, 0, .55, 1)) */
@keyframes epitaxy-linear-sweep {
0% { transform: translate(-100%); }
100% { transform: translate(350%); }
}
/* RTL 镜像扫光 */
@keyframes epitaxy-linear-sweep-rtl {
0% { transform: translate(100%); }
100% { transform: translate(-350%); }
}
/* 6. 成功对勾矢量绘制动效 (Epitaxy Check Draw - 0.18s) */
@keyframes epitaxy-check-draw {
0% { clip-path: inset(0 100% 0 0); }
100% { clip-path: inset(0); }
}4.2.2 陶土暖光推理晕染与 color-mix() 物理光场剖析
在进行思维链(Extended Thinking)或复杂任务处理时,Claude 容器激活 wl-glow 动态光场:
- 物理光圈:内层为硬质发丝边框
0 0 0 2px var(--cds-fill-brand),配合环境投影0 10px 15px -3px #0000001a与0 4px 6px -4px #0000001a; - 动态漫反射:外层光晕不再使用陈旧的固定 RGBA,而是采用现代 CSS 标准
color-mix(in srgb, var(--cds-fill-brand) X%, transparent):- 基础态:
0 0 14px 3px,混合比例 60%; - 峰值态(50%):
0 0 16px 5px,混合比例跃升至 85%;
- 基础态:
- 呼吸频率配比:
wl-glow为 1.8s,wl-halo为 2.2s,双正弦异频相位叠加有效消除了人眼视觉机械性疲劳。
4.2.3 文本扫光波纹物理学 (cds-shimmer-text-shine)
- Claude 采用高度非对称的贝塞尔曲线
cubic-bezier(0.714, 0.121, 0.211, 0.888): 在 0% - 15% 区间进行能量蓄积并保持在83.333% 0,随后在中段以非线性冲量掠过文本,最后在 85% - 100% 平缓回落至16.667% 0,完美模拟了高能光子穿透介质时的波前延迟与骤亮现象。
4.2.4 三相差分跳跃点与 Epitaxy 线性扫光 (cds-dot-pulse, epitaxy-linear-sweep)
- 三点脉冲:基础不透明度严格锚定为
0.2857(即 $\frac{2}{7}$ 精确常数),高亮跃升至1.0,时钟曲线绑定--cds-ease-out(cubic-bezier(0.165, 0.84, 0.44, 1)); - 线性扫光:生产环境执行周期为 1.1s(绝非旧文档误报的 1.6s),速度曲线为对称 S 曲线
cubic-bezier(0.45, 0, 0.55, 1),扫光范围跨越-100%至+350%。
4.2.5 生产级完整 React 落地实现
完整独立源码已落地至:code-examples/ReasoningAmbientGlow.tsx。
4.3 原生 CSS Scroll-Driven 滚动驱动遮罩系统
技术领域与英文指代:
CSS Scroll-Driven Animations & 7-Stop Non-Linear Fade Masks
在会话气泡流、横向分段胶囊及各类溢出滚动列表中,Claude 全面采用了纯 CSS 原生驱动的羽化遮罩系统,不占用主线程 JS 计算与事件侦听(提取自 c6a992d55-sXiDGMFQ.css)。
4.3.1 原生 CSS Scroll-Driven 动画声明 (@supports (animation-timeline: scroll()))
@supports (animation-timeline: scroll()) {
.scroll-fade {
/* 动态计算当前各方向生效遮罩深度 */
--cds-scroll-fade-top: calc(var(--cds-scroll-fade-top-raw) * var(--cds-scroll-fade-y-active) * var(--cds-scroll-fade-top-on));
--cds-scroll-fade-bottom: calc(var(--cds-scroll-fade-bottom-raw) * var(--cds-scroll-fade-y-active) * var(--cds-scroll-fade-bottom-on));
--cds-scroll-fade-left: calc(var(--cds-scroll-fade-left-raw) * var(--cds-scroll-fade-x-active) * var(--cds-scroll-fade-left-on));
--cds-scroll-fade-right: calc(var(--cds-scroll-fade-right-raw) * var(--cds-scroll-fade-x-active) * var(--cds-scroll-fade-right-on));
/* 纵横双轴复合 7-Stop 非线性遮罩图层 */
mask-image:
linear-gradient(to bottom,
transparent,
#0000000d calc(var(--cds-scroll-fade-top) * .15),
#00000026 calc(var(--cds-scroll-fade-top) * .3),
#0000004d calc(var(--cds-scroll-fade-top) * .45),
#00000080 calc(var(--cds-scroll-fade-top) * .6),
#000000b3 calc(var(--cds-scroll-fade-top) * .75),
#000000d9 calc(var(--cds-scroll-fade-top) * .87),
#000 var(--cds-scroll-fade-top),
#000 calc(100% - var(--cds-scroll-fade-bottom)),
#000000d9 calc(100% - var(--cds-scroll-fade-bottom) * .87),
#000000b3 calc(100% - var(--cds-scroll-fade-bottom) * .75),
#00000080 calc(100% - var(--cds-scroll-fade-bottom) * .6),
#0000004d calc(100% - var(--cds-scroll-fade-bottom) * .45),
#00000026 calc(100% - var(--cds-scroll-fade-bottom) * .3),
#0000000d calc(100% - var(--cds-scroll-fade-bottom) * .15),
transparent
),
linear-gradient(to right,
transparent,
#0000000d calc(var(--cds-scroll-fade-left) * .15),
#00000026 calc(var(--cds-scroll-fade-left) * .3),
#0000004d calc(var(--cds-scroll-fade-left) * .45),
#00000080 calc(var(--cds-scroll-fade-left) * .6),
#000000b3 calc(var(--cds-scroll-fade-left) * .75),
#000000d9 calc(var(--cds-scroll-fade-left) * .87),
#000 var(--cds-scroll-fade-left),
#000 calc(100% - var(--cds-scroll-fade-right)),
#000000d9 calc(100% - var(--cds-scroll-fade-right) * .87),
#000000b3 calc(100% - var(--cds-scroll-fade-right) * .75),
#00000080 calc(100% - var(--cds-scroll-fade-right) * .6),
#0000004d calc(100% - var(--cds-scroll-fade-right) * .45),
#00000026 calc(100% - var(--cds-scroll-fade-right) * .3),
#0000000d calc(100% - var(--cds-scroll-fade-right) * .15),
transparent
);
/* 6 路并行原生滚动驱动时间轴绑定 */
animation-name:
cds-scroll-fade-top,
cds-scroll-fade-bottom,
cds-scroll-fade-left,
cds-scroll-fade-right,
cds-scroll-fade-y-active,
cds-scroll-fade-x-active;
animation-timing-function: linear;
animation-fill-mode: both, both, both, both, none, none;
animation-duration: auto;
animation-timeline:
scroll(self),
scroll(self),
scroll(self inline),
scroll(self inline),
scroll(self),
scroll(self inline);
animation-range:
0px var(--cds-scroll-fade-size),
calc(100% - var(--cds-scroll-fade-size)) 100%,
0px var(--cds-scroll-fade-size),
calc(100% - var(--cds-scroll-fade-size)) 100%,
0px 101%,
0px 101%;
-webkit-mask-composite: source-in;
mask-composite: intersect;
}
}4.3.2 官方 7 档非线性透明度采样阶梯 (7-Stop Non-Linear Alpha Sampling)
常规两点线性渐变在高 DPI 视网膜屏幕上极易因伽马响应产生突兀色阶断裂。Claude 研发的 7 组采样点高度契合人眼视觉感知幂律曲线:
- 距离阶梯 (Position Stops):
[15%, 30%, 45%, 60%, 75%, 87%, 100%]; - 真实 Alpha 阶梯 (True Hex Alpha):
15%:#0000000d(Alpha $\approx 5.1%$)30%:#00000026(Alpha $\approx 14.9%$)45%:#0000004d(Alpha $\approx 30.2%$)60%:#00000080(Alpha $\approx 50.2%$)75%:#000000b3(Alpha $\approx 70.2%$)87%:#000000d9(Alpha $\approx 85.1%$)100%:#000000(Alpha $100%$)
4.3.3 生产级完整 React 落地实现
组件已支持现代原生 CSS Scroll-Driven 模式,并在不支持该 API 的宿主环境中自动平滑回退至 JS onScroll 响应式计算:code-examples/ScrollFadeContainer.tsx。