【免费下载链接】blobatar
blobatar 是一个零依赖、gzip 后仅约 4.4 KB 的库:把任何字符串(用户名、邮箱、id)哈希后,确定性地渲染成一张几何头像——同一个名字永远画出同一张脸,无需服务器、无需上传。而它全部 10 种剪影,其实只由三种几何原语拼出来:超椭圆(superellipse)、Catmull-Rom 样条,以及"同色重叠填充"这一巧妙的 SVG 技巧。这篇文章带你从源码层面看清这背后的几何秘密。
从哈希到剪影:一条确定性的流水线
整条链路可以概括为:种子归一化 → 哈希 → 特质(traits)→ 分档选形 → 几何布局 → SVG 序列化。
- packages/blobatar/src/hash.ts:先做 NFC 归一化、去空格、转小写(否则
Alain@x.com和alain@x.com会画出两张脸),再用 FNV-1a 风格的字节混合加 murmur3 finalizer 完成哈希。finalizer 带来"雪崩效应"——alain和alaim的头像在视觉上毫无关联。 - packages/blobatar/src/traits.ts:每个参数按字符串键独立取一个 0–1 的均匀浮点数,而不是从一个序列流里连续取。这样未来新增参数不会扰动任何已有头像——这是"确定性"承诺的关键设计。
- 选形:哈希值落入哪一档区间,就是哪种剪影,下一节详述。
秘密一:超椭圆,一个旋钮覆盖圆、椭圆到圆角矩形
round、boxy、胶囊的圆帽、甚至两只眼睛,画的都是同一个公式:|x/a|^n + |y/b|^n = 1。n 就是那个旋钮:
| n 值 | 形状 | 用途 |
|---|---|---|
| n = 2 | 椭圆 | 眼睛、瞳孔 |
| n ≈ 4 | squircle(超圆) | 默认头部、背景 |
| n → 大 | 趋近矩形 | boxy 剪影 |
实现见 packages/blobatar/src/shape.ts。它没有采样上百个点来逼近曲线,而是用 4 段三次 Bézier 拼出整个轮廓——每象限一段,控制点偏移量 k 按"曲线必须精确穿过 45° 点"推导:当 n=2 时恰好得到经典的 0.5523(圆逼近常数),说明推导是对的。四段路径让每个形状只需约 130 字节的 path 数据,这也是整个库能压到 4.4 KB 的原因之一。
还有一个精心的边界处理:n 超过约 5.55 后控制点会超出半径,曲线不再变"方"而是向 bounding box 外鼓包。代码用Math.min(1, …)钳制 k,宁可牺牲 45° 点的精确性,也保证形状永远不越界——因为 n 再大,视觉上它就是圆角矩形了。
boxy剪影因此极其便宜:它就是round换参数——把 n 从椭圆区间推到 3.4–6,再叠一个 -20°~20° 的倾斜,见 packages/blobatar/src/styles/shapes.ts。
秘密二:Catmull-Rom 样条,"手绘感"石头为什么稳
organic(不规则鹅卵石)和cloud(云朵)需要一种超椭圆给不了的气质:不对称的有机感。答案在 packages/blobatar/src/shape.ts 的blobPath:
- 在圆周上取 6–8 个顶点,每个顶点的半径乘一个 ±16% 的抖动(
t.jitter); - 用闭合 Catmull-Rom 样条穿过这些点,再换算成三次 Bézier 输出给 SVG。
选 Catmull-Rom 而不是直接拟合 Bézier 是刻意为之:它精确插值每一个顶点。这意味着半径参数"说多少就是多少"——凸起多大就凸多大,形状包含关系(containment)变得可预测、可证明。顶点个数则直接控制"瘤状"程度,完全不需要引入噪声函数。
cloud更进一步:核心体仍是这条样条,再在上半圈均匀排 4–6 个"花瓣"圆,用秘密三把它们融成一朵云(shapes.ts#L112-L126)。
秘密三:重叠填充,不做布尔运算的"合体"
10 种剪影里有四种(capsule、nub、sun、droplet)由多个图形"合体"而成。常规做法是 SVG 的clipPath或路径布尔运算,但 blobatar 用的是最朴素也最聪明的一招:同色重叠即并集。
渲染时所有"头部部件"放进同一个<g fill=头色>(packages/blobatar/src/styles/compose.ts),重叠处同色无缝,视觉上天然融为一体:
- capsule:一个矩形(
box)+ 左右两个半径等于半高的圆。圆与矩形恰好沿直径相切,拼出数学上精确的"跑道形"。源码里特意说明为什么不能用超椭圆替代矩形——它的角会按半径的一小部分被磨圆,与圆帽之间出现"腰线",接缝就露馅了。 - nub:身体上贴 1–2 个随机角度、半径为身体 24%–40% 的小圆。
- sun:6–9 个等距小圆排成一圈,远端与身体留出缝隙,读作"光芒"。
唯一例外的droplet(水滴)用了真正的几何:taper(shape.ts#L217-L235)从顶点向椭圆求切线。切线与曲线相接天然无折角,尖端是"长"出来的而不是"贴"上去的——测试甚至专门断言切点必须落在椭圆上(误差 0.01),因为偏一点点,缺口或折痕就会露出来。
分档表:为什么 round 常见,triangle 是稀客
"10 种剪影"不是 10 等分概率。gen2 的分档表(band table)见 packages/blobatar/src/styles/blob.ts:
| 剪影 | 占比 | 剪影 | 占比 |
|---|---|---|---|
| round | 22% | cloud | 7% |
| organic | 26% | droplet | 5.5% |
| boxy | 12% | hexagon | 3.5% |
| capsule | 10% | sun | 3% |
| nub | 9% | triangle | 2% |
round和organic合占近半,是"日常款";triangle只有 2%,是"稀有掉落"。这个设计还有个隐藏约束:分档是冻结的——新剪影加入必然挤占旧剪影的份额,让老用户的面容变样,所以新形状只能随新"代"(generation)出现,这也是 gen1 与 gen2 并存的原因(?gen=1可锁定旧的六种)。
用 6000 个种子证明:眼睛永远在身体里
"重叠填充 + 各种参数化"最怕的是参数调得再好,某天眼睛飞出身体。blobatar 的答案是 packages/blobatar/test/geometry.test.ts 里的几何不变量测试,对 6000 个随机种子全量扫描:
- 眼睛在脸域内,脸域在剪影内:每种剪影声明一个"脸域"椭圆(三角形只有很小一块可用内区),compose.ts 的 faceFit 会在眼睛装不下时整体缩小它——缩而不是挪,所以任何配置下都安全;
- 所有坐标落在 0–100 的 viewBox 内:解析每个生成的 SVG path 的每个数字逐一断言;
- 画出来的轮廓 ⊇ 数学模型:把渲染出的 Bézier 曲线逐点打平采样,验证"包含模型认为在内部的点,一定也在实际画出的轮廓内"——这条检查正是为了一次真实事故而加:capsule 曾一度用超椭圆画中段,所有模型测试都通过,肉眼却能看到"腰线"。模型必须对账到渲染结果,而不是自说自话。
架构小结:形状是值,参数是灵魂
回头看这 10 种剪影,真正的原语只有五个路径函数:superellipse、blobPath、polygon、box、taper,全部集中在 packages/blobatar/src/shape.ts。10 种剪影只是对这些原语的参数化描述:
boxy=round+ 更方的 n + 倾斜;hexagon=triangle+ 六条边;cloud=organic+ 上半圈花瓣。
更妙的是"参数化"的实现方式:新形状通过指名引用同一个函数(如path: spline)来共享,而不是{ ...round, core: 0.86 }式的对象展开——后者会彻底破坏 tree-shaking,实测单个形状多出约 920 字节。这个"字节级抠门"与 4.4 KB 的体积预算,是 docs/adr/0007-shapes-as-values-generations-as-compositions.md 记录的架构决策。
一句话总结:blobatar 用超椭圆一个旋钮收编了所有对称形状,用 Catmull-Rom 精确插值收编了有机形状,用同色重叠填充免掉了布尔运算,最后用分档表与全量几何测试,把"随机感"关进了"确定性"的笼子里——这正是它敢承诺"同一个名字,永远是同一张脸"的底气。
想亲手验证的话,可以从 packages/blobatar/test/geometry.test.ts 的测试与 packages/blobatar/README.md 的完整选项表入手,顺着shape.ts → shapes.ts → compose.ts这条路径读下去,整套几何体系不过几百行。
【免费下载链接】blobatar
相关推荐
MoGe几何约束与投影优化:如何确保3D重建的精确性与一致性
MoGe几何约束与投影优化:如何确保3D重建的精确性与一致性 MoGe(Monocular Geometry Estimation)是一款专注于单目图像3D几何
人工智能计算机视觉深度学习Hindsight开源生态:探索高效AI记忆管理的工具与库
Hindsight开源生态:探索高效AI记忆管理的工具与库 Hindsight作为一款专注于AI智能体记忆管理的开源项目,凭借其强大的记忆学习能力,构建了丰富的
人工智能AI AgentAgent 记忆MCP 服务DLT Viewer汽车电子日志分析工具:终极高效诊断解决方案
DLT Viewer汽车电子日志分析工具:终极高效诊断解决方案 DLT Viewer是一款专为汽车电子系统设计的专业诊断日志分析工具,能够高效解析DLT格式日志
桌面应用日志分析智能硬件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考