Files
doodle-mini/miniprogram/service/headerDrawService.ts
T
2025-11-26 18:03:29 +08:00

133 lines
3.5 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 { getMiniCodeImage, getImage } from '../utils/index';
/**
* 绘制页眉的参数接口
*/
interface DrawHeaderParams {
canvas: WechatMiniprogram.Canvas;
ctx: RenderingContext;
headerType: PrintHeader;
options: {
appName: string;
appHint: string;
title: string;
subTitle: string;
};
onHeaderDrawn?: (currentY: number) => void; // 绘制完成后的回调,用于设置 currentY 和绘制分割线
}
/**
* 绘制完整页眉(包含 Logo、应用名称、提示、标题、副标题)
*/
export async function drawHeader({
canvas,
ctx,
headerType,
options,
onHeaderDrawn,
}: DrawHeaderParams): Promise<void> {
const { appName, appHint, title, subTitle } = options;
let titleX = 80 + 200 + 48; // currentX + logoWidth + spacing
const titleY = 80;
const logoX = 80;
const logoY = 60;
const logoWidth = 200;
const logoHeight = 200;
// 根据 headerType 绘制 Logo 或调整标题位置
switch (headerType) {
case 'LogoImage': {
const image = await getImage(
canvas,
'/assets/imgs/doodle-logo.png',
);
ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight);
break;
}
case 'noLogoImage': {
titleX = 120;
break;
}
case 'minimal': {
titleX = 120;
break;
}
default: {
const image = await getMiniCodeImage(canvas);
ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight);
break;
}
}
// 绘制应用名称
ctx.font = 'bold 64px "Microsoft Yahei"';
ctx.fillStyle = '#000';
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.fillText(appName, titleX, titleY);
// 绘制应用提示
ctx.font = '48px "Microsoft Yahei"';
ctx.fillStyle = '#666';
ctx.fillText(appHint, titleX, 186);
// 绘制标题
ctx.font = 'bold 64px "Microsoft Yahei"';
ctx.fillStyle = '#000';
ctx.fillText(title, 1015, titleY);
// 绘制副标题
ctx.font = '48px "Microsoft Yahei"';
ctx.fillStyle = '#666';
ctx.fillText(subTitle, 1015, 186);
// 调用回调函数,让调用者设置 currentY 并绘制分割线
if (onHeaderDrawn) {
onHeaderDrawn(304);
}
}
/**
* 绘制迷你页眉的参数接口
*/
interface DrawMiniHeaderParams {
canvas: WechatMiniprogram.Canvas;
ctx: RenderingContext;
options: {
appName: string;
title: string;
};
canvasWidth?: number; // 逻辑像素宽度(可选,如果提供则使用,否则从 canvas.width 计算)
onHeaderDrawn?: (currentY: number) => void; // 绘制完成后的回调,用于设置 currentY 和绘制分割线
}
/**
* 绘制迷你页眉(仅包含应用名称和标题,居中显示)
*/
export function drawMiniHeader({
canvas,
ctx,
options,
canvasWidth,
onHeaderDrawn,
}: DrawMiniHeaderParams): void {
const { appName, title } = options;
const titleY = 120;
// 如果提供了逻辑宽度,使用它;否则使用 canvas.width(假设 ctx 未 scale
const centerX =
canvasWidth !== undefined ? canvasWidth / 2 : canvas.width / 2;
ctx.font = 'bold 64px "Microsoft Yahei"';
ctx.fillStyle = '#000';
ctx.textAlign = 'center';
ctx.fillText(appName + ' ' + title, centerX, titleY);
// 调用回调函数,让调用者设置 currentY 并绘制分割线
if (onHeaderDrawn) {
onHeaderDrawn(200);
}
}