kt-template-online-api/src/modules/qqbot/plugins/bangDream/card/card-stat.renderer.ts

137 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Canvas } from 'skia-canvas';
import { drawText } from '@/modules/qqbot/plugins/bangDream/theme/canvas-text';
import { drawList } from '@/modules/qqbot/plugins/bangDream/shared/list-frame.renderer';
import { stackImage } from '@/modules/qqbot/plugins/bangDream/shared/image-stack';
import { drawRoundedRect } from '@/modules/qqbot/plugins/bangDream/theme/canvas-rect';
import {
Card,
Stat,
limitBreakRankStat,
} from '@/modules/qqbot/plugins/bangDream/card/card.model';
import { BANGDREAM_STAT_CONFIG } from '@/modules/qqbot/plugins/bangDream/shared/bangdream-constants';
import {
BANGDREAM_STAT_LIST_SPEC,
createStatLineText,
getStatLineBarLayout,
} from '@/modules/qqbot/plugins/bangDream/card/card-stat.layout';
export const statConfig: Record<string, { color: string; name: string }> =
BANGDREAM_STAT_CONFIG;
/**
* 在图片布局层中绘制卡牌数值In列表。
*
* @param card - 卡牌参数。
*/
export async function drawCardStatInList(card: Card) {
const stat = await card.calcStat();
const limitBreakstat = limitBreakRankStat(card.rarity);
const limitBreakstatTotal =
limitBreakstat.performance +
limitBreakstat.technique +
limitBreakstat.visual;
const statTotal = stat.performance + stat.technique + stat.visual;
const statImage = await drawCardStatDivided(stat, statTotal, limitBreakstat);
const list = [];
list.push(
drawList({
key: '综合力',
content: [`综合力: ${statTotal} + (${limitBreakstatTotal * 4})`],
}),
);
list.push(
new Canvas(
BANGDREAM_STAT_LIST_SPEC.spacer.width,
BANGDREAM_STAT_LIST_SPEC.spacer.height,
),
);
list.push(statImage);
return stackImage(list);
}
/**
* 在图片布局层中绘制数值In列表。
*
* @param stat - 数值参数。
*/
export async function drawStatInList(stat: Stat) {
const statTotal = Math.floor(stat.performance + stat.technique + stat.visual);
const statImage = await drawCardStatDivided(stat, statTotal);
const list = [];
list.push(
drawList({
key: '综合力',
content: [`综合力: ${statTotal}`],
}),
);
list.push(
new Canvas(
BANGDREAM_STAT_LIST_SPEC.spacer.width,
BANGDREAM_STAT_LIST_SPEC.spacer.height,
),
);
list.push(statImage);
return stackImage(list);
}
/**
* 在图片布局层中绘制卡牌数值Divided。
*
* @param stat - 数值参数。
* @param statTotal - 数值Total参数。
* @param limitBreakstat - limitBreakstat参数未传入时使用默认值。
* @returns 异步处理结果。
*/
async function drawCardStatDivided(
stat: Stat,
statTotal: number,
limitBreakstat?: Stat,
): Promise<Canvas> {
/**
* 在图片布局层中绘制数值线条。
*
* @param key - 当前字段键名。
* @param value - 当前处理的值。
* @param total - total参数。
* @returns 渲染或资源结果。
*/
function drawStatLine(key: string, value: number, total: number): Canvas {
const canvas = new Canvas(
BANGDREAM_STAT_LIST_SPEC.line.canvas.width,
BANGDREAM_STAT_LIST_SPEC.line.canvas.height,
);
const ctx = canvas.getContext('2d');
const text = createStatLineText({
label: statConfig[key].name,
limitBreakValue: limitBreakstat?.[key],
value,
});
const textSpec = BANGDREAM_STAT_LIST_SPEC.line.text;
const textImage = drawText({
text,
maxWidth: textSpec.maxWidth,
textSize: textSpec.textSize,
lineHeight: textSpec.lineHeight,
});
const barLayout = getStatLineBarLayout(value, total);
const roundedRect = drawRoundedRect({
width: barLayout.width,
height: barLayout.height,
radius: barLayout.radius,
color: statConfig[key].color,
strokeWidth: barLayout.strokeWidth,
});
ctx.drawImage(textImage, textSpec.x, textSpec.y);
ctx.drawImage(roundedRect, barLayout.x, barLayout.y);
return canvas;
}
const list = [];
for (const key in stat) {
if (Object.prototype.hasOwnProperty.call(stat, key)) {
const element = stat[key];
list.push(drawStatLine(key, element, statTotal));
}
}
return stackImage(list);
}