baseline before Darwin animation-practices round

Snapshots current state as fallback point:
- SKILL.md: Step 9 now defaults to SFX+BGM audio export (not optional)
- SKILL.md: §1.a core asset protocol adds Step 3.4 "5-10-2-8" quality gate for non-logo assets
- New assets/sfx/* library (37 SFX across 9 categories)
- New references/audio-design-rules.md + sfx-library.md + apple-gallery-showcase.md

Next: Darwin will propose animation-practices integration from the 参考动画
reference corpus (BEST-PRACTICES.md, ref-1/2/3 analysis). This commit is the
rollback point if the round doesn't land cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
alchainandClaude Opus 4.7 committed 2026-04-20 22:10:46 +08:00
1 parent 48c677e470
commit e1b94a4680
41 files changed
+861 -1

No files matched your search

+37 -1
View File
@@ -167,6 +167,34 @@ curl -A "Mozilla/5.0" -L "<hero-image-url>" -o assets/<brand>-brand/product-hero
- 产品官方 Twitter/X 的发布截图(常是最新版本)
- 用户有账号时,直接截屏真实产品界面
**3.4 · 素材质量门槛「5-10-2-8」原则(铁律)**
> **Logo 的规则不同于其他素材**。Logo 有就必须用(没有就停下问用户);其他素材(产品图/UI/参考图/配图)遵循「5-10-2-8」质量门槛。
>
> 2026-04-20 花叔原话:「我们的原则是搜索 5 轮,找到 10 个素材,选择 2 个好的。每个需要评分 8/10 以上,宁可少一些,也不为了完成任务滥竽充数。」
| 维度 | 标准 | 反模式 |
|---|---|---|
| **5 轮搜索** | 多渠道交叉搜(官网 / press kit / 官方社媒 / YouTube 截帧 / Wikimedia / 用户账号截屏),不是一轮抓前 2 个就停 | 第一页结果直接用 |
| **10 个候选** | 至少凑 10 个备选才开始筛 | 只抓 2 个,没得选 |
| **选 2 个好的** | 从 10 个里精选 2 个作为最终素材 | 全都用 = 视觉过载 + 品位稀释 |
| **每个 8/10 分以上** | 不够 8 分**宁可不用**,用诚实 placeholder(灰块+文字标签)或 AI 生成(nano-banana-pro 以官方参考为基底)| 凑数 7 分素材进 brand-spec.md |
**8/10 评分维度**(打分时记录在 `brand-spec.md`):
1. **分辨率** · ≥2000px(印刷/大屏场景 ≥3000px)
2. **版权清晰度** · 官方来源 > 公共领域 > 免费素材 > 疑似盗图(疑似盗图直接 0 分)
3. **与品牌气质契合度** · 和 brand-spec.md 里的「气质关键词」一致
4. **光线/构图/风格一致性** · 2 个素材放一起不打架
5. **独立叙事能力** · 能单独表达一个叙事角色(不是装饰)
**为什么这个门槛是铁律**:
- 花叔的哲学:**宁缺毋滥**。滥竽充数的素材比没有更糟——污染视觉品味、传递「不专业」信号
- **「一个细节做到 120%,其他做到 80%」的量化版**:8 分是"其他 80%" 的底线,真正 hero 素材要 9-10 分
- 消费者看作品时,每一个视觉元素都在**积分或扣分**。7 分素材 = 扣分项,不如留空
**Logo 例外**(重申):有就必须用,不适用「5-10-2-8」。因为 logo 不是「多选一」问题,而是「识别度根基」问题——就算 logo 本身只有 6 分,也比没有 logo 强 10 倍。
##### Step 4 · 验证 + 提取(不只是 grep 色值)
| 资产 | 验证动作 |
@@ -601,7 +629,15 @@ Screen 组件接 callback props(`onEnter`、`onClose`、`onTabChange`、`onOpe
7. **验证**:用Playwright截图(见 `references/verification.md`),检查控制台错误,发给用户。
🛑 **检查点4:交付前自己肉眼过一遍浏览器**。AI写的代码经常有interaction bug。
8. **总结**:极简,只说caveats和next steps。
9. **(可选)导出视频**:如果是动画HTML,用户若提「导出/MP4/GIF/60fps」,按 `references/video-export.md` 走:`scripts/render-video.js` 录 25fps MP4 → `scripts/convert-formats.sh` 派生 60fps MP4 + palette 优化 GIF → `scripts/add-music.sh` 加 BGM(6 首场景化配乐,按 `--mood=tech/ad/educational/tutorial` 选)。
9. **(默认)导出视频 · 必带 SFX + BGM**:动画 HTML 的**默认交付形态是带音频的 MP4**,不是纯画面。无声版本等于半成品——用户潜意识感知「画在动但没声音响应」,廉价感的根源就在这里。流水线:
- `scripts/render-video.js` 录 25fps 纯画面 MP4(只是中间产物,**不是成品**)
- `scripts/convert-formats.sh` 派生 60fps MP4 + palette 优化 GIF(视平台需要)
- `scripts/add-music.sh` 加 BGM(6 首场景化配乐:tech/ad/educational/tutorial + alt 变体)
- SFX 按 `references/audio-design-rules.md` 设计 cue 清单(时间轴 + 音效类型),用 `assets/sfx/<category>/*.mp3` 37 个预制资源,按配方 A/B/C/D 选密度(发布 hero ≈ 6个/10s,工具演示 ≈ 0-2个/10s)
- **BGM + SFX 双轨制必须同时做**——只做 BGM 是 ⅓ 分完成度;SFX 占高频、BGM 占低频,频段隔离见 audio-design-rules.md 的 ffmpeg 模板
- 交付前 `ffprobe -select_streams a` 确认有 audio stream,没有则不是成品
- **跳过音频的条件**:用户明确说「不要音频」「纯画面」「我要自己配音」——否则默认带。
- 参考完整流程见 `references/video-export.md` + `references/audio-design-rules.md` + `references/sfx-library.md`。
10. **(可选)专家评审**:用户若提「评审」「好不好看」「review」「打分」,或你对产出有疑问想主动质检,按 `references/critique-guide.md` 走 5 维度评审——哲学一致性 / 视觉层级 / 细节执行 / 功能性 / 创新性各 0-10 分,输出总评 + Keep(做得好的)+ Fix(严重程度 ⚠️致命 / ⚡重要 / 💡优化)+ Quick Wins(5 分钟能做的前 3 件事)。评审设计不评设计师。
**检查点原则**:碰到🛑就停下,明确告诉用户"我做了X,下一步打算Y,你确认吗?"然后真的**等**。不要说完自己就开始做。
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+338
View File
@@ -0,0 +1,338 @@
# Apple Gallery Showcase · 画廊展示墙动画风格
> 灵感来源:Claude Design 官网 hero 视频 + 苹果产品页「作品墙」式陈列
> 实战出处:huashu-design 发布 hero v5
> 适用场景:**产品发布 hero 动画、skill 能力演示、作品集展示**——任何需要把「多件高质量产出」同时展陈并引导观众注意力的场景
---
## 触发判断:什么时候用这个风格
**适合**:
- 有10张以上真实产出要同屏展示(PPT、App、网页、信息图)
- 观众是专业受众(开发者、设计师、产品经理),对「质感」敏感
- 希望传递的气质是「克制、展览式、高级、有空间感」
- 需要焦点和全局同时存在(看细节但不失整体)
**不适合**:
- 单产品聚焦(用 frontend-design 的产品 hero 模板)
- 情绪向/故事性强的动画(用时间轴叙事模板)
- 小屏幕 / 竖屏(倾斜视角在小画面上会糊)
---
## 核心视觉 Token
```css
:root {
/* 浅色画廊调板 */
--bg: #F5F5F7; /* 主画布底 — 苹果官网灰 */
--bg-warm: #FAF9F5; /* 温暖米白变体 */
--ink: #1D1D1F; /* 主字色 */
--ink-80: #3A3A3D;
--ink-60: #545458;
--muted: #86868B; /* 次级文字 */
--dim: #C7C7CC;
--hairline: #E5E5EA; /* 卡片1px边框 */
--accent: #D97757; /* 赤陶橙 — Claude brand */
--accent-deep:#B85D3D;
--serif-cn: "Noto Serif SC", "Songti SC", Georgia, serif;
--serif-en: "Source Serif 4", "Tiempos Headline", Georgia, serif;
--sans: "Inter", -apple-system, "PingFang SC", system-ui;
--mono: "JetBrains Mono", "SF Mono", ui-monospace;
}
```
**关键原则**:
1. **绝不用纯黑底**。黑底会让作品看起来像电影、不像「可以被采用的工作成果」
2. **赤陶橙是唯一色相accent**,其他全部是灰阶 + 白
3. **三字体栈**(serif英+serif中+sans+mono)营造「出版物」而非「互联网产品」的气质
---
## 核心布局模式
### 1. 悬浮卡片(整个风格的基本单元)
```css
.gallery-card {
background: #FFFFFF;
border-radius: 14px;
padding: 6px; /* 内边距是「装裱纸」 */
border: 1px solid var(--hairline);
box-shadow:
0 20px 60px -20px rgba(29, 29, 31, 0.12), /* 主阴影,软且长 */
0 6px 18px -6px rgba(29, 29, 31, 0.06); /* 第二层近光,制造浮感 */
aspect-ratio: 16 / 9; /* 统一 slide 比例 */
overflow: hidden;
}
.gallery-card img {
width: 100%; height: 100%;
object-fit: cover;
border-radius: 9px; /* 比卡片圆角略小,视觉嵌套 */
}
```
**反面教材**:不要贴边瓷砖(无padding无border无shadow)——那是信息图密度表达,不是展览。
### 2. 3D倾斜作品墙
```css
.gallery-viewport {
position: absolute; inset: 0;
overflow: hidden;
perspective: 2400px; /* 深一些的透视,倾斜不夸张 */
perspective-origin: 50% 45%;
}
.gallery-canvas {
width: 4320px; /* 画布 = 2.25× viewport */
height: 2520px; /* 留出pan空间 */
transform-origin: center center;
transform: perspective(2400px)
rotateX(14deg) /* 向后倾 */
rotateY(-10deg) /* 向左转 */
rotateZ(-2deg); /* 轻微倾斜,去掉太规整 */
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: 40px;
padding: 60px;
}
```
**参数 sweet spot**:
- rotateX: 10-15deg(再多就像开酒会 VIP 背景板)
- rotateY: ±8-12deg(左右对称感)
- rotateZ: ±2-3deg(「这不是机器摆的」的人味)
- perspective: 2000-2800px(小于2000会鱼眼,大于3000接近正投影)
### 3. 2×2 四角汇聚(选择场景)
```css
.grid22 {
display: grid;
grid-template-columns: repeat(2, 800px);
gap: 56px 64px;
align-items: start;
}
```
每张卡片从对应角落(tl/tr/bl/br)向中心滑入 + fade in。对应的 `cornerEntry` 向量:
```js
const cornerEntry = {
tl: { dx: -700, dy: -500 },
tr: { dx: 700, dy: -500 },
bl: { dx: -700, dy: 500 },
br: { dx: 700, dy: 500 },
};
```
---
## 五种核心动画模式
### 模式 A · 四角汇聚(0.8-1.2s)
4 个元素从视口四角滑入,同时缩放 0.85→1.0,对应 ease-out。适合「展示多方向选择」的开场。
```js
const inP = easeOut(clampLerp(t, start, end));
card.style.transform = `translate3d(${(1-inP)*ce.dx}px, ${(1-inP)*ce.dy}px, 0) scale(${0.85 + 0.15*inP})`;
card.style.opacity = inP;
```
### 模式 B · 选中放大 + 其他滑出(0.8s)
被选中的卡片放大 1.0→1.28,其他卡片 fade out + blur + 向四角漂回:
```js
// 被选中
card.style.transform = `translate3d(${cellDx*outP}px, ${cellDy*outP}px, 0) scale(${1 + 0.28*easeOut(zoomP)})`;
// 未选中
card.style.opacity = 1 - outP;
card.style.filter = `blur(${outP * 1.5}px)`;
```
**关键**:未选中的要 blur,不是纯 fade。blur 模拟景深,视觉上把被选中的「推出来」。
### 模式 C · Ripple 涟漪展开(1.7s)
从中心向外,按距离 delay,每张卡片依次淡入 + 从 1.25x 缩到 0.94x(「镜头拉远」):
```js
const col = i % COLS, row = Math.floor(i / COLS);
const dc = col - (COLS-1)/2, dr = row - (ROWS-1)/2;
const dist = Math.sqrt(dc*dc + dr*dr);
const delay = (dist / maxDist) * 0.8;
const localT = Math.max(0, (t - rippleStart - delay) / 0.7);
card.style.opacity = easeOut(Math.min(1, localT));
// 同时整体 scale 1.25→0.94
const galleryScale = 1.25 - 0.31 * easeOut(rippleProgress);
```
### 模式 D · Sinusoidal Pan(持续漂移)
用正弦波 + 线性漂移组合,避免 marquee 那种「有起点有终点」的循环感:
```js
const panX = Math.sin(panT * 0.12) * 220 - panT * 8; // 横向左漂
const panY = Math.cos(panT * 0.09) * 120 - panT * 5; // 纵向上漂
const clampedX = Math.max(-900, Math.min(900, panX)); // 防止露边
```
**参数**:
- 正弦周期 `0.09-0.15 rad/s`(慢,约30-50秒一个摆动)
- 线性漂移 `5-8 px/s`(比观众眨眼慢)
- 振幅 `120-220 px`(大到能感觉,小到不会晕)
### 模式 E · Focus Overlay(焦点切换)
**关键设计**:focus overlay 是一个**平面元素**(不倾斜),浮在倾斜画布之上。被选中的 slide 从瓦片位置(约400×225)缩放到屏幕中央(960×540),背景画布不倾斜变化但**变暗到 45%**:
```js
// Focus overlay (flat, centered)
focusOverlay.style.width = (startW + (endW - startW) * focusIntensity) + 'px';
focusOverlay.style.height = (startH + (endH - startH) * focusIntensity) + 'px';
focusOverlay.style.opacity = focusIntensity;
// 背景卡片变暗,但依然可见(关键!不要100%遮罩)
card.style.opacity = entryOp * (1 - 0.55 * focusIntensity); // 1 → 0.45
card.style.filter = `brightness(${1 - 0.3 * focusIntensity})`;
```
**清晰度铁律**:
- Focus overlay 的 `<img>` 必须 `src` 直连原图,**不要复用 gallery 里的压缩缩略**
- 提前 preload 所有原图到 `new Image()[]` 数组
- overlay 自身 `width/height` 按帧计算,浏览器每帧 resample 原图
---
## 时间轴架构(可复用骨架)
```js
const T = {
DURATION: 25.0,
s1_in: [0.0, 0.8], s1_type: [1.0, 3.2], s1_out: [3.5, 4.0],
s2_in: [3.9, 5.1], s2_hold: [5.1, 7.0], s2_out: [7.0, 7.8],
s3_hold: [7.8, 8.3], s3_ripple: [8.3, 10.0],
panStart: 8.6,
focuses: [
{ start: 11.0, end: 12.7, idx: 2 },
{ start: 13.3, end: 15.0, idx: 3 },
{ start: 15.6, end: 17.3, idx: 10 },
{ start: 17.9, end: 19.6, idx: 16 },
],
s4_walloff: [21.1, 21.8], s4_in: [21.8, 22.7], s4_hold: [23.7, 25.0],
};
// 核心 easing
const easeOut = t => 1 - Math.pow(1 - t, 3);
const easeInOut = t => t < 0.5 ? 4*t*t*t : 1 - Math.pow(-2*t+2, 3)/2;
function lerp(time, start, end, fromV, toV, easing) {
if (time <= start) return fromV;
if (time >= end) return toV;
let p = (time - start) / (end - start);
if (easing) p = easing(p);
return fromV + (toV - fromV) * p;
}
// 单一 render(t) 函数读时间戳、写所有元素
function render(t) { /* ... */ }
requestAnimationFrame(function tick(now) {
const t = ((now - startMs) / 1000) % T.DURATION;
render(t);
requestAnimationFrame(tick);
});
```
**架构精髓**:**所有状态由时间戳 t 推导**,没有状态机、没有 setTimeout。这样:
- 播放到任意时刻 `window.__setTime(12.3)` 立刻跳转(方便 playwright 逐帧截)
- 循环天然无缝(t mod DURATION)
- Debug 时能冻结任意一帧
---
## 质感细节(容易被忽略但致命)
### 1. SVG noise texture
浅色底最怕「太平」。叠加一层极弱的 fractalNoise:
```html
<style>
.stage::before {
content: '';
position: absolute; inset: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.078 0 0 0 0 0.078 0 0 0 0 0.074 0 0 0 0.035 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
opacity: 0.5;
pointer-events: none;
z-index: 30;
}
</style>
```
看上去没区别,去掉就知道有了。
### 2. 角落品牌标识
```html
<div class="corner-brand">
<div class="mark"></div>
<div>HUASHU · DESIGN</div>
</div>
```
```css
.corner-brand {
position: absolute; top: 48px; left: 72px;
font-family: var(--mono);
font-size: 12px;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--muted);
}
```
只在作品墙 scene 显示,淡入淡出。像美术馆展签。
### 3. 品牌收束 wordmark
```css
.brand-wordmark {
font-family: var(--sans);
font-size: 148px;
font-weight: 700;
letter-spacing: -0.045em; /* 负字距是关键,让字紧凑成标志 */
}
.brand-wordmark .accent {
color: var(--accent);
font-weight: 500; /* accent字符反而细一点,视觉差 */
}
```
`letter-spacing: -0.045em` 是苹果产品页大字的标准做法。
---
## 常见失败模式
| 症状 | 原因 | 解法 |
|---|---|---|
| 看起来像 PPT 模板 | 卡片没有 shadow / hairline | 加上两层 box-shadow + 1px border |
| 倾斜感廉价 | 只用了 rotateY 没加 rotateZ | 加 ±2-3deg rotateZ 打破工整 |
| Pan 感觉「卡顿」 | 用了 setTimeout 或 CSS keyframes 循环 | 用 rAF + sin/cos 连续函数 |
| Focus 时字看不清 | 复用了 gallery 瓦片的低分图 | 独立 overlay + 原图 src 直连 |
| 背景太空 | 纯色 `#F5F5F7` | 叠加 SVG fractalNoise 0.5 opacity |
| 字体太"互联网" | 只有 Inter | 加 Serif(中英各一)+ mono 三栈 |
---
## 引用
- 完整实现样本:`/Users/alchain/Documents/写作/01-公众号写作/项目/2026.04-huashu-design发布/配图/hero-animation-v5.html`
- 原始灵感:claude.ai/design hero 视频
- 参考审美:Apple 产品页、Dribbble shot 集合页
遇到「多件高质量产出要陈列」的动画需求,直接从此文件 copy 骨架,换内容 + 调 timing 即可。
+260
View File
@@ -0,0 +1,260 @@
# 音频设计规则 · huashu-design
> 所有动画 demo 的音频应用配方。和 `sfx-library.md`(资产清单)配套使用。
> 实战锤炼:huashu-design 发布 hero v1-v9 迭代 · Anthropic 三支官方片子的 Gemini 深度拆解 · 8000+ 次 A/B 对比
---
## 核心原则 · 音频双轨制(铁律)
动画音频**必须分两层独立设计**,不能只做一层:
| 层 | 作用 | 时间尺度 | 和视觉的关系 | 占据频段 |
|---|---|---|---|---|
| **SFX(节拍层)** | 标记每个视觉 beat | 0.2-2 秒短促 | **强同步**(帧级对齐) | **高频 800Hz+** |
| **BGM(氛围底)** | 情绪铺底、声场 | 连续 20-60 秒 | 弱同步(段落级) | **中低频 <4kHz** |
**只做BGM的动画是残废的**——观众潜意识感知到「画在动但没声音响应」,廉价感的根源就在这里。
---
## 金标准 · 黄金配比
这几组数值是实测 Anthropic 三支官方片子 + 我们自己 v9 定版对比得出的**工程硬参数**,直接套用即可:
### 音量
- **BGM 音量**:`0.40-0.50`(相对满刻度 1.0)
- **SFX 音量**:`1.00`
- **响度差**:BGM 比 SFX peak **低 -6 到 -8 dB**(不是靠SFX绝对响度突出,靠响度差)
- **amix 参数**:`normalize=0`(绝不用 normalize=1,会把动态范围压平)
### 频段隔离(P1 硬优化)
Anthropic 的秘诀不是「SFX 音量大」,是**频段分层**:
```bash
[bgm_raw]lowpass=f=4000[bgm] # BGM 限制在 <4kHz 的中低频
[sfx_raw]highpass=f=800[sfx] # SFX 推到 800Hz+ 的中高频
[bgm][sfx]amix=inputs=2:duration=first:normalize=0[a]
```
为什么:人耳对 2-5kHz 区间最敏感(即「presence 频段」),SFX 如果都在这个区间,BGM 又全频段覆盖,**SFX 会被BGM的高频部分遮盖**。用 highpass 把 SFX 推高 + lowpass 把 BGM 压下,两者在频谱上各占一方,SFX 清晰度直接上一档。
### Fade
- BGM 入:`afade=in:st=0:d=0.3`(0.3s,避免硬切)
- BGM 出:`afade=out:st=N-1.5:d=1.5`(1.5s 长尾,收束感)
- SFX 自带 envelope,不需要额外 fade
---
## SFX cue 设计规则
### 密度(每10秒多少个SFX)
实测 Anthropic 三支片子的 SFX 密度有三档:
| 片子 | 每10s SFX 数 | 产品性格 | 场景 |
|---|---|---|---|
| Artifacts(ref-1) | **~9个/10s** | 功能密集、信息多 | 复杂工具演示 |
| Code Desktop(ref-2) | **0个** | 纯氛围、冥想感 | 开发工具专注状态 |
| Word(ref-3) | **~4个/10s** | 平衡、办公节奏 | 生产力工具 |
**启发式**:
- 产品性格冷静/专注 → SFX 密度低(0-3个/10s),BGM 为主
- 产品性格活泼/信息多 → SFX 密度高(6-9个/10s),SFX 驱动节奏
- **不要填满每个视觉 beat**——留白比密集更高级。**删掉 30-50% 的 cue 会让剩下的更有戏剧性**。
### Cue 选择优先级
每个视觉 beat 不都要配 SFX。按这个优先级选:
**P0 必配**(省略会有违和感):
- 打字(终端/输入)
- 点击/选择(用户决策时刻)
- 焦点切换(视觉主角转移)
- Logo reveal(品牌收束)
**P1 推荐配**:
- 元素入场/离场(modal / card)
- 完成/成功反馈
- AI 生成开始/结束
- 重大过渡(scene 切换)
**P2 选配**(多了会乱):
- hover / focus-in
- 进度 tick
- 装饰性 ambient
### 时间戳对齐精度
- **同帧对齐**(0ms 误差):点击/焦点切换/Logo 落定
- **前置 1-2 帧**(-33ms):快速 whoosh(给观众心理预期)
- **后置 1-2 帧**(+33ms):物体落地/impact(符合真实物理)
---
## BGM 选择决策树
huashu-design skill 自带 6 首 BGM(`assets/bgm-*.mp3`):
```
动画性格是什么?
├─ 产品发布 / 技术演示 → bgm-tech.mp3(minimal synth + piano)
├─ 教程讲解 / 工具使用 → bgm-tutorial.mp3(warm, instructional)
├─ 教育学习 / 原理解释 → bgm-educational.mp3(curious, thoughtful)
├─ 营销广告 / 品牌宣传 → bgm-ad.mp3(upbeat, promotional)
└─ 同类风格需要变体 → bgm-*-alt.mp3(各自替代版)
```
### 无 BGM 的场景(值得考虑)
参考 Anthropic Code Desktop(ref-2):**0 SFX + 纯 Lo-fi BGM** 也能很高级。
**何时选无BGM**:
- 动画时长 <10s(BGM 建立不起来)
- 产品性格是「专注/冥想」
- 场景本身有环境音/讲解声
- SFX 密度很高时(避免听觉过载)
---
## 场景配方(开箱即用)
### 配方 A · 产品发布 hero(huashu-design v9 同款)
```
时长:25 秒
BGM:bgm-tech.mp3 · 45% · 频段 <4kHz
SFX 密度:~6个/10s
cue:
终端打字 → type × 4(间隔0.6s)
回车 → enter
卡片汇聚 → card × 4(错峰 0.2s)
选中 → click
Ripple → whoosh
4次焦点 → focus × 4
Logo → thud(1.5s)
音量:BGM 0.45 / SFX 1.0 · amix normalize=0
```
### 配方 B · 工具功能演示(参考 Anthropic Code Desktop)
```
时长:30-45 秒
BGM:bgm-tutorial.mp3 · 50%
SFX 密度:0-2个/10s(极少)
策略:让 BGM + 讲解 voiceover 驱动,SFX 只在**决定性时刻**(文件保存/命令执行完成)
```
### 配方 C · AI 生成演示
```
时长:15-20 秒
BGM:bgm-tech.mp3 或无 BGM
SFX 密度:~8个/10s(高密度)
cue:
用户输入 → type + enter
AI 开始处理 → magic/ai-process(1.2s 循环)
生成完成 → feedback/complete-done
结果呈现 → magic/sparkle
亮点:ai-process 可以循环 2-3 次贯穿整个生成过程
```
### 配方 D · 纯氛围长镜头(参考 Artifacts)
```
时长:10-15 秒
BGM:无
SFX:单独使用 3-5 个精心设计的 cue
策略:每个 SFX 都是主角,没有BGM「糊在一起」的问题。
适合:单产品慢镜头、特写展示
```
---
## ffmpeg 合成模板
### 模板 1 · 单 SFX 叠加到视频
```bash
ffmpeg -y -i video.mp4 -itsoffset 2.5 -i sfx.mp3 \
-filter_complex "[0:a][1:a]amix=inputs=2:normalize=0[a]" \
-map 0:v -map "[a]" output.mp4
```
### 模板 2 · 多 SFX 时间轴合成(按cue时间对齐)
```bash
ffmpeg -y \
-i sfx-type.mp3 -i sfx-enter.mp3 -i sfx-click.mp3 -i sfx-thud.mp3 \
-filter_complex "\
[0:a]adelay=1100|1100[a0];\
[1:a]adelay=3200|3200[a1];\
[2:a]adelay=7000|7000[a2];\
[3:a]adelay=21800|21800[a3];\
[a0][a1][a2][a3]amix=inputs=4:duration=longest:normalize=0[mixed]" \
-map "[mixed]" -t 25 sfx-track.mp3
```
**关键参数**:
- `adelay=N|N`:前面是左声道延迟(ms),后面是右声道,写两遍保证立体声对齐
- `normalize=0`:保留动态范围,关键!
- `-t 25`:截断到指定时长
### 模板 3 · 视频 + SFX track + BGM(带频段隔离)
```bash
ffmpeg -y -i video.mp4 -i sfx-track.mp3 -i bgm.mp3 \
-filter_complex "\
[2:a]atrim=0:25,afade=in:st=0:d=0.3,afade=out:st=23.5:d=1.5,\
lowpass=f=4000,volume=0.45[bgm];\
[1:a]highpass=f=800,volume=1.0[sfx];\
[bgm][sfx]amix=inputs=2:duration=first:normalize=0[a]" \
-map 0:v -map "[a]" -c:v copy -c:a aac -b:a 192k final.mp4
```
---
## 失败模式速查
| 症状 | 根因 | 修复 |
|---|---|---|
| SFX 听不见 | BGM 高频部分遮盖 | 加 `lowpass=f=4000` 给BGM + `highpass=f=800` 给SFX |
| 音效过响刺耳 | SFX 绝对音量太大 | SFX 音量降到 0.7,同时降低 BGM 到 0.3,保持差值 |
| BGM 和 SFX 节奏冲突 | BGM 选错了(用了有强beat的music) | 换成 ambient / minimal synth 的 BGM |
| 动画结束 BGM 突然断 | 没做 fade out | `afade=out:st=N-1.5:d=1.5` |
| SFX 重叠成糊 | cue 太密 + 每个 SFX 时长太长 | SFX 时长控到 0.5s 以内,cue 间隔 ≥ 0.2s |
| 公众号 mp4 没声音 | 公众号有时会 mute auto-play | 不用担心,用户点开会有声音;gif 本来就没声音 |
---
## 和视觉的联动(高级)
### SFX 音色要和视觉风格匹配
- 暖米/纸张感视觉 → SFX 用**木质/柔和**音色(Morse, paper snap, soft click)
- 冷黑科技视觉 → SFX 用**金属/数字**音色(beep, pulse, glitch)
- 手绘/童趣视觉 → SFX 用**卡通/夸张**音色(boing, pop, zap)
我们当前 `apple-gallery-showcase.md` 的暖米底色 → 搭配 `keyboard/type.mp3`(mechanical)+ `container/card-snap.mp3`(soft)+ `impact/logo-reveal-v2.mp3`(cinematic bass)
### SFX 可以引导视觉节奏
高级技巧:**先设计 SFX 时间轴,然后调整视觉动画去对齐 SFX**(不是反过来)。
因为 SFX 每个 cue 都是一个「钟表 tick」,视觉动画适配 SFX 节奏会非常稳——反之 SFX 去追视觉,常常 ±1 帧对不上就有违和感。
---
## 质量检查清单(发布前自检)
- [ ] 响度差:SFX peak - BGM peak = -6 到 -8 dB?
- [ ] 频段:BGM lowpass 4kHz + SFX highpass 800Hz?
- [ ] amix normalize=0(保留动态范围)?
- [ ] BGM fade-in 0.3s + fade-out 1.5s?
- [ ] SFX 数量是否合适(按场景性格选密度)?
- [ ] 每个 SFX 和视觉 beat 同帧对齐(±1 帧内)?
- [ ] Logo reveal 音效时长够(建议 1.5s)?
- [ ] 关闭 BGM 听一遍:SFX 单独是否足够有节奏感?
- [ ] 关闭 SFX 听一遍:BGM 单独是否有情绪起伏?
两层任何一层单独听都应该自洽。如果只有两层叠加才好听,说明没做好。
---
## 参考
- SFX 资产清单:`sfx-library.md`
- 视觉风格参考:`apple-gallery-showcase.md`
- Anthropic 三支片子深度音频分析:`/Users/alchain/Documents/写作/01-公众号写作/项目/2026.04-huashu-design发布/参考动画/AUDIO-BEST-PRACTICES.md`
- huashu-design v9 实战案例:`/Users/alchain/Documents/写作/01-公众号写作/项目/2026.04-huashu-design发布/配图/hero-animation-v9-final.mp4`
+226
View File
@@ -0,0 +1,226 @@
# SFX Library · huashu-design
> 全部由 ElevenLabs Sound Generation API 生成,苹果发布会级音质。
> 产品级 SFX 资产库,覆盖花叔动画/演示/产品 Demo 全场景。
**资产位置**:`assets/sfx/<category>/<name>.mp3`
**总数**:37 个 SFX(30 批量生成 + 7 个 v7b 保留)
**生成模型**:ElevenLabs Sound Generation API(prompt_influence 0.4)
**音质**:44.1kHz MP3,苹果发布会级清晰度,无额外混响
---
## 目录结构
```
assets/sfx/
├── keyboard/ type, type-fast, delete-key, space-tap, enter
├── ui/ click, click-soft, focus, hover-subtle, tap-finger, toggle-on
├── transition/ whoosh, whoosh-fast, swipe-horizontal, slide-in, dissolve
├── container/ card-snap, card-flip, stack-collapse, modal-open
├── feedback/ success-chime, error-tone, notification-pop, achievement
├── progress/ loading-tick, complete-done, generate-start
├── impact/ logo-reveal, logo-reveal-v2, brand-stamp, drop-thud
├── magic/ sparkle, ai-process, transform
└── terminal/ command-execute, output-appear, cursor-blink
```
---
## 快速索引
### ⌨️ Keyboard(键盘输入)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/keyboard/type.mp3` | 0.5s | 单键敲击(mechanical keyboard single key) | mechanical keyboard single key press |
| `sfx/keyboard/type-fast.mp3` | 1.5s | 连续快速打字(演示输入提示词) | fast continuous typing rhythm, apple magic keyboard |
| `sfx/keyboard/delete-key.mp3` | 0.5s | backspace 回删 | single backspace key, low pitched thud |
| `sfx/keyboard/space-tap.mp3` | 0.5s | 空格键轻击 | soft spacebar tap, wide flat |
| `sfx/keyboard/enter.mp3` | 0.5s | 回车确认(v7b 保留) | enter key press, crisp tactile |
### 🎯 UI(界面交互)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/ui/click.mp3` | 0.5s | 标准 UI 点击(v7b 保留) | crisp modern interface click |
| `sfx/ui/click-soft.mp3` | 0.5s | 柔和 UI click(次要按钮/链接) | soft gentle button click, mid pitched |
| `sfx/ui/focus.mp3` | 0.5s | 元素聚焦/选中(v7b 保留) | subtle focus tone, element highlight |
| `sfx/ui/hover-subtle.mp3` | 0.5s | 悬停提示(微秒级反馈) | barely audible tick, air whisper |
| `sfx/ui/tap-finger.mp3` | 0.5s | 移动端 tap(iOS 界面) | finger tap on touchscreen, muted thud |
| `sfx/ui/toggle-on.mp3` | 0.5s | 开关打开 | ios toggle switch flip, satisfying click |
### 🌊 Transition(过渡)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/transition/whoosh.mp3` | 0.5s | 标准 whoosh(v7b 保留) | air whoosh transition |
| `sfx/transition/whoosh-fast.mp3` | 0.6s | 快速 whoosh(标题闪入、标签切换) | quick fast air whoosh, cinematic |
| `sfx/transition/swipe-horizontal.mp3` | 0.7s | 横向滑动(轮播、tab 切换) | smooth left-to-right air movement |
| `sfx/transition/slide-in.mp3` | 0.6s | 元素滑入(side panel、抽屉) | smooth soft whoosh with arrival |
| `sfx/transition/dissolve.mp3` | 0.8s | 柔化融化(图片淡出淡入) | soft dissolve, airy shimmer |
### 🃏 Container(卡片/容器)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/container/card-snap.mp3` | 0.5s | 卡片吸附/定位(v7b 保留) | card snap into place |
| `sfx/container/card-flip.mp3` | 0.7s | 卡片翻转(前后面切换) | playing card flip, crisp snap |
| `sfx/container/stack-collapse.mp3` | 0.8s | 堆叠合拢(列表聚合) | cards stacking, paper taps collapsing |
| `sfx/container/modal-open.mp3` | 0.6s | 模态框打开 | modal popping open, whoosh + thud |
### 🔔 Feedback(通知/反馈)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/feedback/success-chime.mp3` | 1.0s | 成功提示(支付成功、任务完成) | two ascending bell tones, ios-style |
| `sfx/feedback/error-tone.mp3` | 0.7s | 错误提示(警告、失败) | descending two-note warning, soft |
| `sfx/feedback/notification-pop.mp3` | 0.6s | 消息弹出(toast、通知) | notification bloop, ios message alert |
| `sfx/feedback/achievement.mp3` | 1.5s | 成就达成(里程碑、徽章) | triumphant rising arpeggio, game-style |
### ⏳ Progress(进度/状态)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/progress/loading-tick.mp3` | 0.5s | 加载计时(进度条节拍) | soft short pulse, minimal ambient |
| `sfx/progress/complete-done.mp3` | 0.8s | 完成确认(step 完成) | two ascending satisfying tones |
| `sfx/progress/generate-start.mp3` | 0.8s | AI 开始生成 | soft rising shimmer, magical whoosh |
### 💥 Impact(品牌/冲击)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/impact/logo-reveal.mp3` | 0.7s | Logo impact(v7b 保留) | logo reveal thud |
| `sfx/impact/logo-reveal-v2.mp3` | 1.5s | 更长的 Logo impact(电影感) | cinematic bass hit with shimmer tail |
| `sfx/impact/brand-stamp.mp3` | 1.0s | 印章重击(认证、盖章) | rubber stamp thud, paper contact |
| `sfx/impact/drop-thud.mp3` | 0.7s | 物件落地(插入、放置) | heavy thud, wood surface contact |
### ✨ Magic(AI 变换)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/magic/sparkle.mp3` | 0.8s | 魔法闪光(AI 高亮、惊喜) | bright twinkling stars, fairy dust |
| `sfx/magic/ai-process.mp3` | 1.2s | AI 处理音(thinking 状态) | modulating digital hum with shimmer |
| `sfx/magic/transform.mp3` | 1.0s | 变换过渡(morph 效果) | rising shimmer whoosh with sparkle tail |
### 💻 Terminal(命令行)
| 文件 | 时长 | 用途 | Prompt 要点 |
|---|---|---|---|
| `sfx/terminal/command-execute.mp3` | 0.5s | 命令执行 | crisp digital beep with tick, hacker ui |
| `sfx/terminal/output-appear.mp3` | 0.6s | 输出出现 | rapid digital ticks, retro printout |
| `sfx/terminal/cursor-blink.mp3` | 0.5s | 光标闪烁 | subtle soft digital pulse, rhythmic |
---
## 按场景推荐搭配
### 💻 Terminal 交互演示
```
type (0.5s) → enter (0.5s) → command-execute (0.5s) → output-appear (0.6s)
```
循环元素:`cursor-blink` 作为 idle 时的环境音。
### 🃏 卡片选择流程
```
hover-subtle (0.5s, UI悬停) → click-soft (0.5s, 点击) → card-snap (0.5s, 定位)
```
或进阶版:`card-flip` 做前后面切换。
### 🤖 AI 生成全流程
```
generate-start (0.8s, 启动) → ai-process (1.2s, 处理) → sparkle (0.8s, 闪现) → complete-done (0.8s, 完成)
```
错误时用 `error-tone` 替代 `complete-done`。
### 🎬 Logo Reveal(品牌时刻)
```
whoosh-fast (0.6s, 铺垫) → logo-reveal-v2 (1.5s, 落点) → sparkle (0.8s, 尾韵)
```
简版:`whoosh → logo-reveal`(直接 v7b 两件套)。
### 📱 UI 交互演示(移动端)
```
tap-finger (0.5s, 点击) → slide-in (0.6s, 面板滑入) → toggle-on (0.5s, 开关)
```
完成后:`success-chime` 或 `notification-pop`。
### 📊 数据可视化/仪表盘
```
loading-tick (0.5s, 节拍) × N → complete-done (0.8s, 数据到位) → achievement (1.5s, 惊艳落点)
```
### 🎯 表单提交流程
```
click-soft (0.5s) → loading-tick ×2 (1.0s) → success-chime (1.0s)
```
失败分支:`error-tone (0.7s)`。
### 🪄 Magic Transform 场景
```
whoosh-fast (0.6s) → transform (1.0s) → sparkle (0.8s)
```
适合:元素变形、效果前后对比、"AI 重写"等演示。
---
## 使用规范
### 音量建议(来自 apple-gallery-showcase.md 音频双轨制)
- **SFX 主轨**:`1.0`(不做衰减)
- **BGM 背景轨**:`0.4 ~ 0.5`(SFX 明显穿透)
- **多 SFX 叠加**:用 `amix=inputs=N:duration=longest:normalize=0` 保留动态范围
### ffmpeg 拼接模板
```bash
# 单 SFX 对齐时间点:
ffmpeg -i video.mp4 -itsoffset 2.5 -i sfx/ui/click.mp3 \
-filter_complex "[0:a][1:a]amix=inputs=2:duration=longest:normalize=0[a]" \
-map 0:v -map "[a]" output.mp4
# 多 SFX + BGM:
ffmpeg -i video.mp4 \
-itsoffset 1.0 -i sfx/transition/whoosh-fast.mp3 \
-itsoffset 1.6 -i sfx/impact/logo-reveal-v2.mp3 \
-i bgm.mp3 \
-filter_complex "[3:a]volume=0.4[bgm];[0:a][1:a][2:a][bgm]amix=inputs=4:normalize=0[a]" \
-map 0:v -map "[a]" output.mp4
```
### 选型决策树
1. **有 tactile 动作**(打字/点击/滑动)→ `keyboard/` or `ui/`
2. **元素进场/出场** → `transition/`
3. **容器层操作**(卡片/模态) → `container/`
4. **状态反馈**(成功/失败/通知) → `feedback/`
5. **进度/时间流逝** → `progress/`
6. **品牌落点/重要时刻** → `impact/`
7. **AI 魔法/变换** → `magic/`
8. **命令行/代码演示** → `terminal/`
### 避免叠音堆积
- 同一个时间点 `max 2 个 SFX` 并发
- BGM 降到 0.3 以下时可以放 3 个
- 品牌 impact 时清空其他 SFX(留空 0.2s 再落点)
---
## Prompt 撰写原则(供复用)
参考风格:`apple keynote, tight, minimal, no reverb unless ambient, crisp, elegant`
**好 prompt 的三要素**:
1. **声音物理描述**:什么物体、什么动作("mechanical keyboard single key press")
2. **质感/风格限定**:apple-style / ios-style / cinematic / retro
3. **反例排除**:no reverb / clean studio / minimal
❌ "click sound"
✅ "crisp ui button click, clean modern interface sound, apple-style, high pitched"
❌ "magic"
✅ "bright twinkling stars sound, high pitched glittery chime, fairy dust"
---
## 详见
- 音频双轨制与 ffmpeg 拼接:`apple-gallery-showcase.md`
- 原始生成脚本:`/tmp/gen_sfx_batch.sh`(一次性批量生成器)