133 lines
3.5 KiB
TypeScript
133 lines
3.5 KiB
TypeScript
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);
|
||
}
|
||
}
|