refactor: 收口 BangDream 标题条规格

This commit is contained in:
sunlei 2026-06-07 05:48:47 +08:00
parent 8bc529b50f
commit 1aca165bbc
4 changed files with 140 additions and 20 deletions

View File

@ -395,6 +395,7 @@ export interface TsuguHook {
- 已新增 `render-blocks/list-card-sd-character-spec.ts`,收口卡牌详情演出缩略图的 SD 角色 sprite 裁切网格、列表缩放行高、字号和间距;`list-card-sd-character.ts` 改为消费 spec素材加载、四帧裁切和列表绘制顺序保持不变`list-card-sd-character-spec.spec.ts` 覆盖四帧裁切坐标、单帧裁切计算和列表规格,本地 `/查卡 472` 图片 smoke 输出非空。
- 已新增 `render-blocks/list-card-prefix-spec.ts`,收口卡牌详情顶部标题块的画布、背景、乐队 Logo 等比缩放、卡牌标题和角色名文字布局;`list-card-prefix.ts` 改为消费 spec乐队/角色/服务器优先级读取和绘制顺序保持不变;`list-card-prefix-spec.spec.ts` 覆盖标题块尺寸、背景、文字坐标和 Logo 缩放,本地 `/查卡 472` 图片 smoke 输出非空。
- 已新增 `render-blocks/list-stat-spec.ts`,收口卡牌/玩家综合力列表的间隔、数值行画布、文字规格、进度条布局和条宽算法;`list-stat.ts` 改为消费 spec综合力计算、突破加成和绘制顺序保持不变`list-stat-spec.spec.ts` 覆盖间隔/画布/文字/进度条规格、文本生成和条宽布局,本地 `/查卡 472` 图片 smoke 输出非空。
- 已新增 `render-blocks/title-spec.ts`,收口通用标题条的背景偏移、两行文字字号/行高/颜色/字体/坐标;`title.ts` 改为消费 spec标题底图加载、标题文案和绘制顺序保持不变`title-spec.spec.ts` 覆盖背景偏移、两行文字布局、绘制参数和坐标,本地 `/查卡 472` 图片 smoke 输出非空。
- smoke/Jenkins/远程调试卡点继续按已固化规则处理同一卡点第二次尝试前必须改变可验证变量Jenkins 查询 URL 含方括号时用 `curl -g` 或改查 Jenkins home线上图片 smoke 必须查询 `commandId`、拉回图片、展示图片、查日志并清理本轮临时目录PowerShell 双引号 here-string 中不要写 JS `${...}` 模板字面量,避免被 PowerShell 提前插值smoke 没有真实图片落盘时必须失败。
### Phase 6策略 policy 和时间/档线规则

View File

@ -0,0 +1,66 @@
import { BANGDREAM_RENDER_THEME } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/theme';
export const BANGDREAM_TITLE_SPEC = {
background: {
x: 0,
y: 0,
},
text: {
first: {
color: BANGDREAM_RENDER_THEME.color.surface,
font: BANGDREAM_RENDER_THEME.font.body,
lineHeight: 50,
maxWidth: 900,
textSize: 30,
x: 74,
y: 0,
},
second: {
color: BANGDREAM_RENDER_THEME.color.labelBackground,
font: BANGDREAM_RENDER_THEME.font.body,
lineHeight: 68,
maxWidth: 900,
textSize: 40,
x: 74,
y: 42,
},
},
} as const;
export type BangDreamTitleTextSlot = keyof typeof BANGDREAM_TITLE_SPEC.text;
/**
*
*
* @param text -
* @param slot -
*/
export function createTitleTextDrawOptions(
text: string,
slot: BangDreamTitleTextSlot,
) {
const spec = BANGDREAM_TITLE_SPEC.text[slot];
return {
color: spec.color,
font: spec.font,
lineHeight: spec.lineHeight,
maxWidth: spec.maxWidth,
text,
textSize: spec.textSize,
};
}
/**
*
*
* @param slot -
*/
export function getTitleTextPosition(slot: BangDreamTitleTextSlot) {
const spec = BANGDREAM_TITLE_SPEC.text[slot];
return {
x: spec.x,
y: spec.y,
};
}

View File

@ -2,7 +2,11 @@ import { Canvas, Image } from 'skia-canvas';
import { drawText } from '@/qqbot/plugins/bangDream/tsugu/canvas/text';
import { loadImageFromPath } from '@/qqbot/plugins/bangDream/tsugu/canvas/image-utils';
import { getBangDreamAssetPath } from '@/qqbot/plugins/bangDream/tsugu/runtime/asset-manifest';
import { BANGDREAM_RENDER_THEME } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/theme';
import {
BANGDREAM_TITLE_SPEC,
createTitleTextDrawOptions,
getTitleTextPosition,
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/title-spec';
let titleImage: Image;
/**
@ -23,24 +27,16 @@ loadImageOnce();
export function drawTitle(title1: string, title2: string): Canvas {
const canvas = new Canvas(titleImage.width, titleImage.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(titleImage, 0, 0);
const text1 = drawText({
text: title1,
maxWidth: 900,
lineHeight: 50,
textSize: 30,
color: BANGDREAM_RENDER_THEME.color.surface,
font: BANGDREAM_RENDER_THEME.font.body,
});
const text2 = drawText({
text: title2,
maxWidth: 900,
lineHeight: 68,
textSize: 40,
color: BANGDREAM_RENDER_THEME.color.labelBackground,
font: BANGDREAM_RENDER_THEME.font.body,
});
ctx.drawImage(text1, 74, 0);
ctx.drawImage(text2, 74, 42);
ctx.drawImage(
titleImage,
BANGDREAM_TITLE_SPEC.background.x,
BANGDREAM_TITLE_SPEC.background.y,
);
const text1 = drawText(createTitleTextDrawOptions(title1, 'first'));
const text2 = drawText(createTitleTextDrawOptions(title2, 'second'));
const firstPosition = getTitleTextPosition('first');
const secondPosition = getTitleTextPosition('second');
ctx.drawImage(text1, firstPosition.x, firstPosition.y);
ctx.drawImage(text2, secondPosition.x, secondPosition.y);
return canvas;
}

View File

@ -0,0 +1,57 @@
import {
BANGDREAM_TITLE_SPEC,
createTitleTextDrawOptions,
getTitleTextPosition,
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/title-spec';
import { BANGDREAM_RENDER_THEME } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/theme';
describe('BangDream title spec', () => {
it('keeps the historical title background offset stable', () => {
expect(BANGDREAM_TITLE_SPEC.background).toEqual({
x: 0,
y: 0,
});
});
it('keeps the historical first and second title text layout stable', () => {
expect(BANGDREAM_TITLE_SPEC.text.first).toEqual({
color: BANGDREAM_RENDER_THEME.color.surface,
font: BANGDREAM_RENDER_THEME.font.body,
lineHeight: 50,
maxWidth: 900,
textSize: 30,
x: 74,
y: 0,
});
expect(BANGDREAM_TITLE_SPEC.text.second).toEqual({
color: BANGDREAM_RENDER_THEME.color.labelBackground,
font: BANGDREAM_RENDER_THEME.font.body,
lineHeight: 68,
maxWidth: 900,
textSize: 40,
x: 74,
y: 42,
});
});
it('creates title text draw options and positions from the shared spec', () => {
expect(createTitleTextDrawOptions('查询', 'first')).toEqual({
color: BANGDREAM_RENDER_THEME.color.surface,
font: BANGDREAM_RENDER_THEME.font.body,
lineHeight: 50,
maxWidth: 900,
text: '查询',
textSize: 30,
});
expect(createTitleTextDrawOptions('卡牌', 'second')).toEqual({
color: BANGDREAM_RENDER_THEME.color.labelBackground,
font: BANGDREAM_RENDER_THEME.font.body,
lineHeight: 68,
maxWidth: 900,
text: '卡牌',
textSize: 40,
});
expect(getTitleTextPosition('first')).toEqual({ x: 74, y: 0 });
expect(getTitleTextPosition('second')).toEqual({ x: 74, y: 42 });
});
});