图谱卡常量按广场卡实测重算(214/20、每行 10 字、紧凑 210)+ 规范同步卡统一口径
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
This commit is contained in:
@@ -465,8 +465,13 @@ A 路线里那个必须提前知道的互斥点已经按既有做法绕开:`cr
|
||||
- **角标成组、永不叠印**:代际 / 主干 / 当前作品 / 父代-子代 / ▶游玩数 统一放进 `.game-lineage-node__badges`(flex + gap + 可换行)。此前它们各自 `position: absolute`(代际左上、主干右上、「当前作品」在流内),在窄容器里会**互相叠印成乱码字形**(大纲行的「第 1 代」与「主干」);现在组内一律静态定位,重叠在结构上不可能发生。**2026-10-07 起两种形态都把该组放在封面下方**(画布卡片的信息区第一行),不再作为封面浮层。
|
||||
- **缩略图统一 16:9**:大纲行的封面与画布同一比例(16:9,4.5rem 宽),不再被角标撑成窄竖条;行用 `min-height: 3.5rem` 做统一基线,标题最多 2 行 clamp → 同层行等宽、跨行等高,连线端点一致。
|
||||
- **信息密度**:代际 + 主干 + 当前作品 + 父代/子代 由「三行」收敛成**一行角标组**,标题 2 行 clamp、作者一行 → 每行比改版前少一行。
|
||||
- **画布卡片版式与层高自适应(2026-10-07 追加,来自真机截图复盘)**:
|
||||
- **层高按该层最高卡片**:布局新增输入 `cardHeights`(每个节点的卡片高度,由**纯函数** `estimateLineageCardHeight` 估算:基础高 + (标题行数−1)×行高,标题行数按字符宽度估、上限 2 行)。竖版 `第 N 层的 y = 上一层 y + 上一层最高卡片高度 + rowGap`,层内所有卡片取该层最大高度(同层等高,`min-height` 撑开),因此「同层里有一张 2 行标题的高卡」也不会被下一层压住;横版(窄屏图谱)槽位高取全局最大卡片高。**不测量 DOM**(纯函数可单测、离线复算,不会先渲染再重排抖动)。常量由真机校准:桌面 1 行 376px / 2 行 399px → 取 380 / +24;窄屏紧凑卡 1 行 350 / 2 行 373 → 取 352 / +24(估算 ≥ 实测,只多不少)。
|
||||
- **图谱卡 = 广场作品卡的同一个组件(2026-10-07 用户口径:「不是要长得像,而是就应该是广场卡」)**:画布节点卡与图下方「父代 / 子代」清单卡**都直接渲染** `@genarrative/shared/components` 的 `GameCard`(不是仿制样式、也不是 CSS 覆盖)。为此对共享卡做了**纯加法**扩展:`game` 参数放宽为结构化子集(按「字段是否在对象上」决定是否渲染该行,广场用法行为不变)、新增可选 `badges` 角标槽与 `className`。
|
||||
- **卡面不再有动作按钮**:「打开作品 / 开始共创」已从卡面移除(用户口径:看封面决定不了共创,必须点进去看)——**整卡就是入口**(`GameCard` 本身是 `<button>`,点击 → 作品详情;占位节点点击不导航)。
|
||||
- **图谱语义走角标槽**:第 N 代 / 主干 / 当前作品 / 父代-子代 / `▶N`(子树合计)全部通过 `badges` 槽承载;高亮 / 变暗 / 主干线状态仍在外层最薄 wrapper 的 class(wrapper 只负责定位与连线锚点、不改卡内视觉)。选中/高亮改为**悬停或键盘聚焦**驱动(点击已让位给「进详情」)。
|
||||
- **封面**:`.game-card--lineage .game-cover { aspect-ratio: 16/9; min-height: 0 }` + 图片 `100%×100% + object-fit: cover`(统一 16:9 铺满)。
|
||||
- **层高常量按新卡实测重算**:真机实测(212 宽画布卡、标题两行)卡高 **231.5px** → `LINEAGE_CARD_BASE_HEIGHT = 214` / `TITLE_LINE_HEIGHT = 20`(两行估算 234 ≥ 实测);每行字符数按实测换行取 `10`;紧凑卡 `210 / +20`。层间距 = 上一层最高卡 + `rowGap`,实测无重叠。
|
||||
- **大纲行(移动端列表形态)继续用 `LineageNodeContent`**:它是**列表行**不是卡片(行内保留「打开作品 / 开始共创」,是移动端的既有设计),因此该组件未被删除;若产品要求连大纲也卡化,再单独处理。
|
||||
- **层高按该层最高卡片**:布局新增输入 `cardHeights`(每个节点的卡片高度,由**纯函数** `estimateLineageCardHeight` 估算:基础高 + (标题行数−1)×行高,标题行数按字符宽度估、上限 2 行)。竖版 `第 N 层的 y = 上一层 y + 上一层最高卡片高度 + rowGap`,层内所有卡片取该层最大高度(同层等高,`min-height` 撑开),因此「同层里有一张 2 行标题的高卡」也不会被下一层压住;横版(窄屏图谱)槽位高取全局最大卡片高。**不测量 DOM**(纯函数可单测、离线复算,不会先渲染再重排抖动)。常量由真机校准(**卡片改为广场卡组件后重测**):桌面两行标题实测 231.5px → 取 214 / +20;每行字符数取 10;窄屏紧凑卡 210 / +20(估算 ≥ 实测,只多不少)。
|
||||
- **代际轴按层高画**:`LineageGenerationAxisEntry` 增加 `height`(该层层高),轴的每一行高度跟着层高走(不再拿「第一个节点的高度」凑)。
|
||||
- **角标组移到封面下方**(不再用深色药丸压在封面图上),并且**上色**——每类语义一色、**全部取自平台既有 `--platform-*` 变量,不新增色值**:代际 = 中性(neutral)|**主干 = 暖色(warm,强调)**|**当前作品 = 主色实心(accent solid)**|父代 = cool|子代 = success|▶游玩数 = 中性。组内仍是 flex + gap + 可换行(**绝不重叠**),并有 1px 边框保证在浅色卡片上有边界。
|
||||
- **卡片底部重做**:作者行独立一行、更小更淡(`--platform-text-muted`);操作区是**两个等权重按钮**(`flex: 1 1 0`、`min-height: 2rem` = 32px 触控目标、同圆角同内边距),`打开作品` = 次要(描边),`**开始共创**` = 主要(填充/着色);窄卡允许换行但不裁切。大纲行同口径(`打开作品` 描边 / `开始共创` 填充)。
|
||||
|
||||
@@ -72,10 +72,11 @@ type GameLineagePageProps = {
|
||||
};
|
||||
|
||||
/**
|
||||
* 窄屏紧凑卡片的基础高(176 宽:16:9 封面 + 角标行 + 标题 + 作者 / 操作)。
|
||||
* 由真机实测校准(2026-10-07):1 行标题 350px、2 行 373px → 取 352(+24/行)留余量。
|
||||
* 窄屏紧凑卡片的基础高(176 宽)。
|
||||
* 卡片改为广场作品卡组件后按同一套结构估算:16:9 封面(99)+ 卡内边距 + 两行标题 + meta,
|
||||
* 取 210 / +20(估算含余量,宁可略高也不重叠)。
|
||||
*/
|
||||
const LINEAGE_COMPACT_CARD_BASE_HEIGHT = 352;
|
||||
const LINEAGE_COMPACT_CARD_BASE_HEIGHT = 210;
|
||||
|
||||
/** 拖动阈值(像素):超过它才算「拖动」,否则一律当作点击,交给浏览器原生 click。 */
|
||||
const DRAG_START_THRESHOLD_PX = 4;
|
||||
|
||||
@@ -142,16 +142,21 @@ export type LineageLayoutOptions = {
|
||||
* 一旦依赖 `getBoundingClientRect` 就会引入抖动与「先渲染再重排」的死循环。
|
||||
* 估算公式 = 基础高 + (标题行数 - 1) × 行高,标题行数按**字符宽度**估(CJK 记 1、其余记 0.55),
|
||||
* 上限 2 行(与 CSS 的 `-webkit-line-clamp: 2` 一致)。
|
||||
* 常量由**真机实测校准**(2026-10-07,演示树):1 行标题的卡 376px、2 行 399px ——
|
||||
* 这里取 380 / 24 留 4~5px 余量,保证「估算 ≥ 实测」,层间只会更宽不会重叠。
|
||||
* 常量由**真机实测校准**(2026-10-07,卡片改为**广场作品卡组件**之后重测):
|
||||
* 桌面卡宽 212.4(内容坐标)、标题两行时**实测卡高 231.5**;按公式 `base + (行数-1)×行高`,
|
||||
* 取 `base = 214` / `行高 = 20`(两行 → 234 ≥ 231.5),保证「估算 ≥ 实测」,层间只会更宽不会重叠。
|
||||
*/
|
||||
export const LINEAGE_CARD_BASE_HEIGHT = 380;
|
||||
export const LINEAGE_CARD_BASE_HEIGHT = 214;
|
||||
/** 标题每多一行增加的高度(与 CSS 的标题行高一致)。 */
|
||||
export const LINEAGE_CARD_TITLE_LINE_HEIGHT = 24;
|
||||
export const LINEAGE_CARD_TITLE_LINE_HEIGHT = 20;
|
||||
/** 标题最多 2 行(CSS line-clamp 同值)。 */
|
||||
export const LINEAGE_CARD_TITLE_MAX_LINES = 2;
|
||||
/** 240 宽卡片一行大约能放下的「全角字符」数(估算用,偏小更安全)。 */
|
||||
export const LINEAGE_CARD_TITLE_CHARS_PER_LINE = 15;
|
||||
/**
|
||||
* 卡面一行大约能放下的「全角字符」数(估算用)。
|
||||
* 广场卡在 212 宽画布卡里标题是 1rem 粗体、可用宽度约 180px ⇒ 一行约 11~12 个全角字符;
|
||||
* 真机实测「共创演示·A0|星海工坊」(按视觉宽度约 11 个全角单位)**实际渲染成两行**,所以这里取 10。
|
||||
*/
|
||||
export const LINEAGE_CARD_TITLE_CHARS_PER_LINE = 10;
|
||||
|
||||
function titleVisualWidth(title: string) {
|
||||
let width = 0;
|
||||
|
||||
Reference in New Issue
Block a user