Bruce brand / emotion system

布鲁斯动态表情 Emotion Studio

以 brand/bruce-mark.svg 的主图基因重绘的 12 枚可循环矢量表情。 每一帧都显式烘焙进 SVG 的 values / keyTimes, 不依赖 JavaScript、不叠图片,可直接作为 <img> 嵌进产品的等待、祝贺与博客插画里。

引擎 claude-opus-6-high 表情 — 烘焙帧 — @ 30fps 动画轨道 — 纯矢量 — SMIL · 零 JS · 无缝循环
t = 0.00s
02

产品场景演示

下面三处均使用 <img src="emotions/…svg">,验证独立文件在真实容器中的表现。

等待过程 / loading64px
等待中的布鲁斯
正在索引工作区…已扫描 1,284 个文件
祝贺过程 / success118px
撒花祝贺的布鲁斯 全部 248 项测试通过本次提交已经可以合并了
博客插画 / editorial96px
Engineering blog让 Agent 写出能读的提交信息 打字中的布鲁斯
Bruce · 工程手记 #122026-11-11 · 8 min read
03

设计方案摘要

完整版见同目录 README.md。

素材溯源

只取品牌原生矢量,不复制参考项目的几何数据:

  • bruce-mark.svg:冰蓝底板、navy / cream 毛色、cyan 护目镜、violet » 徽章、六组原生渐变
  • bruce-head.svg / bruce-agent.svg:耳朵、抬起的护目镜、警觉眼神与微笑的小尺寸语法
  • story/bruce-good-job.svg:#C3EBF4 / #A79BE6 / #152736 插画配色
  • grok-icon-study-main:只借鉴动画原理(弹簧、挤压拉伸、眨眼队列、阻尼跳跃、状态播放表、overlay),造型与数据全部原创

角色再设计

主图是左侧脸,无法做对称双眼、挤压拉伸与大表情。因此把品牌元素重排为正面 chibi: 两只奶油色内耳的尖耳、navy 头罩、奶油色面罩、推到额头上的青色双镜片护目镜、 navy 杏仁眼 + 白色高光、navy 鼻头与微笑、青色项圈和 violet » 徽章,背后仍是冰蓝圆角方板。

所有部件都是可动画的独立图层:耳、护目镜、眉、眼、嘴、徽章、底板、地面阴影, 以及一层特效轨道。轮廓加粗到 3–4.5px,保证 32px 下仍可辨认。

动画工程

  • 预烘焙帧:每条轨道在 30fps 下逐帧求值,写入 values + keyTimes,calcMode="linear",浏览器按刷新率插值 → 观感 60fps+
  • 零依赖:SMIL <animate> / <animateTransform>,SVG 内无脚本、无外链,<img> 里照常播放
  • 造型变换:眼睛用固定 16 顶点多边形做 points 形变;变换用「平移 → 旋转 → 缩放」嵌套组,避免 additive 顺序歧义
  • 物理:体积守恒挤压、1 − e⁻ᵈᵗcos(ωt) 弹簧包络、四段阻尼落地(1 : .58 : .29 : .125)、ease-out-back 弹出
  • 循环闭合:所有轨道 p=0 与 p=1 同值,整圈旋转以 360° ≡ 0° 收尾;粒子在窗口外完全透明

示意:一个 2.4s 循环的 72 个显式关键帧,紫色为分镜节点。

#表情场景时长帧数轨道 分镜体积
04

接入方式

同一份文件,四种用法;静态海报在 frames/。

<!-- 1. 最常用:img,SMIL 会在 img 上下文中播放 -->
<img src="/brand/emotion/…/emotions/05-celebrate.svg"
     width="96" height="96" alt="祝贺" />

<!-- 2. CSS 背景 / 伪元素 -->
.spinner::after {
  content: ""; width: 64px; height: 64px;
  background: url("emotions/02-waiting.svg") center/contain no-repeat;
}

<!-- 3. 内联:可脚本控制(本页即用此法逐帧检视)-->
const svg = document.querySelector("svg[data-emotion]");
svg.pauseAnimations();          // 冻结
svg.setCurrentTime(1.2);        // 跳到 1.2s 那一帧
svg.unpauseAnimations();

<!-- 4. 尊重减少动态偏好:换静态海报 -->
@media (prefers-reduced-motion: reduce) {
  .sticker { content: url("frames/05-celebrate-hero.svg"); }
}

目录:emotions/ 动画成品 · frames/*-hero.svg 静态海报 · frames/*-strip.svg 8 帧矢量接触条 · manifest.json 元数据 · tools/ 生成器 · contact-sheet.png 总览 · README.md 完整设计方案。

工程约束与验收

  • 纯矢量:没有位图、没有雪碧图、没有帧图片叠加
  • 单文件自包含:渐变 ID 按表情名前缀隔离,同页放 12 个不冲突
  • 透明背景由冰蓝底板承担,深色界面下底板仍保持品牌色,无需反色
  • 每个 <animate> 都有 values / keyTimes / dur / repeatCount,可被 setCurrentTime() 精确定位
  • 16 顶点眼睛使 points 形变在所有 SMIL 实现中可插值
  • 32 / 64 / 128 / 256px 四档尺寸均可读;小尺寸优先使用 01 / 02 / 10 等低频表情
  • 循环无缝:首末帧完全一致,粒子在循环边界 opacity = 0