3.2.38 自动头像补 4 套风格:avataaars / bottts 及其带底色版 #7
上一版只收录 14 套,把 avataaars、bottts 两个系列漏掉了。原因是 3.2.36 盘点时,这四套的 npm 包里 license 字段写的是「See LICENSE file」,被我 当成「措辞不明、先不收」。点进去看实际条款是 「Free for personal and commercial use」(设计者 Pablo Stanley, 来源 avataaars.com / bottts.com),而且不要求署名 —— 比收录的 CC BY 那十几套还宽松。方向判断反了,这是错误,不是许可限制。 改动: - 新增 inc/avatar-styles/ 四份模板:avataaars、avataaars_neutral、 bottts、bottts_neutral(合计 227 KB,风格总数 14 → 18) - yang_avatar_styles() 注册四套中文名与说明,排在「首字母」之后 - avataaars 的 onPostCreate 三条规则逐条复刻: ① style 组为 circle 时清空背景; ② 背景恰好只剩 65c9ff 一项时清空(判「恰好只有一个」,不是「包含」); ③ 戴头巾且胡子概率非 100 时去掉胡子。 为此 yang_avatar_post_create() 增加 $picked 形参(官方读 components.style.name / components.top.name,不传拿不到), 返回值由 2 项改为 3 项($on 会被改,必须带出来)。 - 后台风格说明由「都是 CC0 或 MIT 许可」改为「都可自由使用与商用, 且不要求署名」—— 加了这四套后前者已不准确 - 文件头许可清单补上「作者自定义许可」一类 验证(先证明判据真能红,再谈通过): - 逐字节 80/0:四套各 20 种种子(含中文、emoji、超长、空串)比对官方 Node 库。第一版 avataaars 20 个全错,差异正是背景那块天蓝,补规则后对齐 - 逐字节反向 3/3:删分支、不清 65c9ff、返回值退 2 项,各红 20 项 - 规则白盒 9/0:circle / 恰好 65c9ff / 多色保留 / 含 65c9ff 不只一项保留 / 头巾 10% 删胡子 / 头巾 100% 保留胡子 / 不戴头巾不受影响 / 别风格不受影响 / 返回 3 项 - 规则反向 6/6:写坏任一分支,都恰好在预期那条上报错 - 原有 14 套回归 108/0(原 84 + 新 24) - 18 套全量冒烟:每套合法 SVG、三种种子互异 - 严格错误级别 PHP 8.4.25 与 8.5.12(线上同版)各 47/0 - 几何+交互 29/0:18 卡片、18 单选、18 缩略图全部解码 - 源码守卫 55/0,反向 17/17 - 包内契约 34/0,反向 8/8 - 后台标签 88/0、CDN 56/0 与 77/0、3.2.28 13/0 - 93 个 php 文件 php -l 全通过 顺带修正两处错误的守卫(都是这次暴露出来的): - _guard336_avatar.py 把 avataaars / bottts 错列进「CC BY 禁止收录」 清单,改按实测许可证重写(CC BY 实为 13 套,不含这两个) - _guard336_falsify.py 的 F2 锚点仍在匹配旧名「自动头像」,3.2.37 改名后恒失效;版本锚点也停在上一个版本
This commit is contained in:
+67
-9
@@ -12,11 +12,16 @@
|
||||
*
|
||||
* ── 素材与算法来源 ────────────────────────────────────────────────
|
||||
* 算法与图形素材来自 DiceBear(https://www.dicebear.com)9.x。
|
||||
* 收录的 14 套风格全部是 CC0 1.0 或 MIT 许可,可自由使用与商用:
|
||||
* 收录的 18 套风格全部可自由使用与商用,且**都不要求署名**:
|
||||
* CC0 1.0:glass identicon initials lorelei lorelei-neutral
|
||||
* notionists notionists-neutral open-peeps pixel-art
|
||||
* pixel-art-neutral rings shapes thumbs
|
||||
* MIT :icons
|
||||
* 作者自定义许可(Free for personal and commercial use,不要求署名):
|
||||
* avataaars avataaars-neutral bottts bottts-neutral
|
||||
* 设计者 Pablo Stanley,来源 avataaars.com / bottts.com。
|
||||
* 这四套在 npm 包里写的是「See LICENSE file」,必须点进去看才知道
|
||||
* 条款 —— 别把「措辞不明」当成「不能商用」,实际比 CC BY 还宽松。
|
||||
* 每套模板都是把 DiceBear 的风格包「编译」成纯数组后的产物
|
||||
* (inc/avatar-styles/*.php),文件里没有任何可执行 JS。
|
||||
*
|
||||
@@ -534,6 +539,22 @@ function yang_avatar_styles()
|
||||
'label' => __('首字母', 'kratos'),
|
||||
'desc' => __('显示邮箱对应的首字母文字。若访客用中文邮箱会显示拼音首字母。', 'kratos'),
|
||||
),
|
||||
'avataaars' => array(
|
||||
'label' => __('美式卡通', 'kratos'),
|
||||
'desc' => __('美式插画风,表情与发型最丰富的一套。不画背景,头像直接压在页面上。', 'kratos'),
|
||||
),
|
||||
'avataaars-neutral' => array(
|
||||
'label' => __('美式卡通(带底色)', 'kratos'),
|
||||
'desc' => __('同一套画风,带一块背景色,更醒目一点。', 'kratos'),
|
||||
),
|
||||
'bottts' => array(
|
||||
'label' => __('机器人', 'kratos'),
|
||||
'desc' => __('机器脑袋,靠零件与配色区分,没有人脸所以不会"崩脸"。不画背景。', 'kratos'),
|
||||
),
|
||||
'bottts-neutral' => array(
|
||||
'label' => __('机器人(带底色)', 'kratos'),
|
||||
'desc' => __('同一套机器人画风,带背景色块。', 'kratos'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -572,7 +593,7 @@ function yang_avatar_style()
|
||||
/**
|
||||
* 加载某套风格的编译后模板
|
||||
*
|
||||
* 只 require 用到的那一份,其余不解析 —— 14 套全量 1.1MB,
|
||||
* 只 require 用到的那一份,其余不解析 —— 18 套全量 1.2MB,
|
||||
* 每次请求都加载是不必要的开销。
|
||||
*
|
||||
* @param string $style
|
||||
@@ -1029,11 +1050,13 @@ function yang_avatar_render($style, $seed, $size = 96, $palette = array())
|
||||
$colors[$ck] = yang_avatar_color($p->pick($vals, 'transparent'));
|
||||
}
|
||||
|
||||
/* ── 3. onPostCreate(会改 colors / options.backgroundColor) ── */
|
||||
/* ── 3. onPostCreate(会改 colors / options.backgroundColor / 组件开关) ──
|
||||
必须把 $picked 传进去:官方这里读的是 components.style.name 与 components.top.name。 */
|
||||
if (!empty($style['has_post_create'])) {
|
||||
$res = yang_avatar_post_create($style['name'], $d, $colors, $on);
|
||||
$res = yang_avatar_post_create($style['name'], $d, $colors, $on, $picked);
|
||||
$d = $res[0];
|
||||
$colors = $res[1];
|
||||
$on = $res[2];
|
||||
}
|
||||
|
||||
/* ── 4. 展开 body ── */
|
||||
@@ -1136,7 +1159,7 @@ function yang_avatar_int_range($p, $spec, $d)
|
||||
* onPreCreate:按风格名精确复刻
|
||||
*
|
||||
* 这些是**代码**(会动态改 options),不能当数据编译。
|
||||
* 收录的 14 套里只有 shapes 有,且它会消耗 3 次 pick。
|
||||
* 收录的 18 套里只有 shapes 有,且它会消耗 3 次 pick。
|
||||
*
|
||||
* @param string $name
|
||||
* @param Yang_Avatar_Prng $p
|
||||
@@ -1184,11 +1207,46 @@ function yang_avatar_pre_create($name, $p, $d)
|
||||
* @param array $d
|
||||
* @param array $colors
|
||||
* @param array $on
|
||||
* @return array array($d, $colors)
|
||||
* @param array $picked getComponents 已抽到的组件名(官方 onPostCreate 读的是
|
||||
* components.style.name / components.top.name,必须传进来)
|
||||
* @return array array($d, $colors, $on)
|
||||
*/
|
||||
function yang_avatar_post_create($name, $d, $colors, $on)
|
||||
function yang_avatar_post_create($name, $d, $colors, $on, $picked = array())
|
||||
{
|
||||
if ($name === 'lorelei' || $name === 'lorelei-neutral') {
|
||||
if ($name === 'avataaars') {
|
||||
/* 官方 onPostCreate 的三条,逐条复刻(顺序也要一样):
|
||||
① style 组取到 'circle' ⇒ 背景整个清空;
|
||||
② style 不是 'circle'、但背景**恰好只有 65c9ff 这一项** ⇒ 也清空。
|
||||
65c9ff 是这款的默认背景色,意思是「用户没主动选过背景」,
|
||||
留着会在脸后面糊一块天蓝,看着像没去底。
|
||||
⚠️ 注意这里判的是「只有一个、且等于 65c9ff」,不是「包含 65c9ff」:
|
||||
若用户给了多个颜色,就说明是主动选的,要留着。
|
||||
③ 戴头巾(top = hijab)且没强制 100% 胡子 ⇒ 去掉胡子
|
||||
(头巾配胡子现实中不存在)。
|
||||
清空 backgroundColor 不是「不画背景」那么简单:下游
|
||||
yang_avatar_bg_colors() 对空数组会走 shuffle + next() 消耗 PRNG,
|
||||
与官方 getBackgroundColors() 的空数组分支步数一致 —— 两边都恰好消耗一次。 */
|
||||
$styleName = isset($picked['style']) ? $picked['style'] : '';
|
||||
|
||||
if ($styleName === 'circle') {
|
||||
$d['backgroundColor'] = array();
|
||||
} elseif (isset($d['backgroundColor']) && is_array($d['backgroundColor'])
|
||||
&& count($d['backgroundColor']) === 1
|
||||
&& $d['backgroundColor'][0] === '65c9ff') {
|
||||
$d['backgroundColor'] = array();
|
||||
}
|
||||
|
||||
// ③ 头巾与胡子互斥
|
||||
if (!empty($on['top'])) {
|
||||
$topName = isset($picked['top']) ? $picked['top'] : '';
|
||||
$prob = isset($d['facialHairProbability']) ? $d['facialHairProbability'] : 10;
|
||||
if ((int) $prob !== 100 && $topName === 'hijab') {
|
||||
// 官方置 undefined ⇒ 展开时该组不出现;这里同步关掉 bool,避免取到残留值
|
||||
$d['facialHair'] = array();
|
||||
$on['facialHair'] = false;
|
||||
}
|
||||
}
|
||||
} elseif ($name === 'lorelei' || $name === 'lorelei-neutral') {
|
||||
// 有胡子且胡子与嘴同色时,把嘴改成白色,否则看不出嘴
|
||||
if (!empty($on['beard']) && isset($colors['hair'], $colors['mouth'])
|
||||
&& $colors['hair'] === $colors['mouth']) {
|
||||
@@ -1229,7 +1287,7 @@ function yang_avatar_post_create($name, $d, $colors, $on)
|
||||
}
|
||||
}
|
||||
}
|
||||
return array($d, $colors);
|
||||
return array($d, $colors, $on);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user