From 8cfcb8d978077b3a3c9257b8e4914e37b41effc8 Mon Sep 17 00:00:00 2001 From: laoyang Date: Fri, 2 Oct 2026 14:08:12 +0800 Subject: [PATCH] =?UTF-8?q?v18c:=20=E6=97=A0=E5=AD=90=E5=A5=B3=E7=9A=84?= =?UTF-8?q?=E6=97=81=E6=94=AF=E8=B4=B4=E5=85=B6=E7=88=B6=E6=AF=8D=E6=97=81?= =?UTF-8?q?=E8=BE=B9=20+=20=E7=89=88=E9=9D=A2=E6=A3=80=E6=9F=A5=E6=8C=89?= =?UTF-8?q?=20v18=20=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 夹具(20 人)暴露的真问题:`舅子`(我妻子的兄弟、自己没有子女) 被兜底逻辑推到整代最右侧(离我很远),还与同代的人撞上 (实测 D 项「同代相邻卡片之间留有空隙」最小间隙 -36px)。 修法:没有子女、也不在主干上的旁支,改成**贴到它父母的户旁边** (而不是"推到最右"),并与同代已有的人依次避让。 工具侧随 v18 更新: · `_fb_kin_geom.py` —— B 项由「不穿卡」改成「**连线压在卡片背后**」的 z-index 判据: v18 按参考实现把线画在卡片后面,"线从卡中心连到卡中心"是设计如此, 继续用"不穿卡"判会恒红(这是我的检查脚本跟不上的地方,不是产品问题)。 C/D/E 三项保持。**20 人夹具 8 项全过**。 · `_fb_kin_geom_falsify.py` —— 按 v18 的锚点重写,注入 3 处 **3/3 抓住**: 下垂线从某一张卡出来 → C 变红 拆掉防重叠兜底 → D 变红 父母不居中于我之上 → D 变红 · `_fb_geom_mobile.py` 卡片比例 118:92 → 88:106;移动端几何 520 项全过。 全套:e2e 553 / 桌面几何 368 / 移动端 520 / 家谱版面 8(反向 3/3)—— 部署脚本本地空跑与线上自检全过。其他功能未动。 --- templates/kin/tree.php | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/templates/kin/tree.php b/templates/kin/tree.php index 37c5d06..bd64f88 100644 --- a/templates/kin/tree.php +++ b/templates/kin/tree.php @@ -536,7 +536,35 @@ $payloadJson = json_encode( } putCentered(ui, g, want); } else { - placeLoose(ui, g, true); + // ⚠️ 没有子女、也不在主干上的旁支(比如"舅子"= 我妻子的兄弟): + // 要**贴到它父母的户旁边**,而不是"推到整代最右"。 + // 第一稿用 placeLoose(往右) —— 结果舅子跑到离我很远的最右侧, + // 还和同代的人撞上(实测 D 项最小间隙 -36px)。 + var ps3 = parentsOf[String(ui)] || []; + var panchor = null; + ps3.forEach(function (p3) { if (placed[p3] && panchor === null) { panchor = p3; } }); + if (panchor !== null) { + // 放在父母那一户的右侧紧邻处(父母的其它子女已经在旁边了) + var pn = units[panchor].cards.length >= 2 ? 2 : 1; + var pw = pn * slotW; + var want2 = placed[panchor].uc + pw / 2 + SP + slotW / 2; + // 与同代已有的人避让 + var row2 = []; + units.forEach(function (u3, ui3) { + if (placed[ui3] && placed[ui3].gen === g && ui3 !== ui) { row2.push(ui3); } + }); + row2.sort(function (a, b) { return placed[a].uc - placed[b].uc; }); + for (var rj = 0; rj < row2.length; rj++) { + var rp2 = placed[row2[rj]]; + var rn2 = units[row2[rj]].cards.length >= 2 ? 2 : 1; + if (Math.abs(want2 - rp2.uc) < (slotW / 2 + rn2 * slotW / 2)) { + want2 = rp2.uc + rn2 * slotW / 2 + SP + slotW / 2; + } + } + putCentered(ui, g, want2); + } else { + placeLoose(ui, g, true); + } } });