143 lines
4.3 KiB
TypeScript
143 lines
4.3 KiB
TypeScript
import { PAPER_SIZE } from '../../constants/colors';
|
|
import { drawMathHeader, drawMathMiniHeader } from './mathHeaderDraw';
|
|
|
|
/**
|
|
* 基础数学绘制服务
|
|
* 包含Paper设置和Header绘制功能,可被其他绘制服务复用
|
|
*/
|
|
export class BaseMathDrawService {
|
|
headerType: PrintHeader = 'wechat';
|
|
canvas: WechatMiniprogram.Canvas;
|
|
ctx: RenderingContext;
|
|
options: Record<string, any>;
|
|
paperSize: PaperSize;
|
|
currentX: number;
|
|
currentY: number;
|
|
canvasWidth: number; // 逻辑像素宽度
|
|
canvasHeight: number; // 逻辑像素高度
|
|
|
|
constructor(
|
|
canvas: Canvas,
|
|
ctx: RenderingContext,
|
|
options?: Record<string, any>,
|
|
) {
|
|
options = options || {};
|
|
this.canvas = canvas;
|
|
this.ctx = ctx;
|
|
this.paperSize = 'A4';
|
|
this.options = {
|
|
appName: '涂鸦丫小程序',
|
|
appHint: '在玩耍中学习数学',
|
|
title: '看数字,涂一涂',
|
|
subTitle: '找一找下面相同的数字,涂上颜色',
|
|
...options,
|
|
};
|
|
this.currentX = 0;
|
|
this.currentY = 0;
|
|
this.canvasWidth = 0;
|
|
this.canvasHeight = 0;
|
|
this.setPrintConfig();
|
|
}
|
|
|
|
setPrintConfig() {
|
|
const printConfig = getApp().getPrintConfig();
|
|
this.headerType = printConfig.header;
|
|
this.options.appName = printConfig.appName;
|
|
}
|
|
|
|
/**
|
|
* 设置Paper(逻辑像素,尺寸除以3)
|
|
*/
|
|
setPaper() {
|
|
const { ctx, canvas } = this;
|
|
const { pixelRatio: dpr } = wx.getWindowInfo();
|
|
let { width, height } = PAPER_SIZE[this.paperSize];
|
|
console.log('width', width);
|
|
console.log('height', height);
|
|
console.log('dpr', dpr);
|
|
|
|
this.canvasWidth = width;
|
|
this.canvasHeight = height;
|
|
|
|
// 设置 canvas 为物理像素尺寸(用于高分辨率显示)
|
|
const physicalWidth = width * dpr;
|
|
const physicalHeight = height * dpr;
|
|
canvas.width = physicalWidth;
|
|
canvas.height = physicalHeight;
|
|
|
|
// 重置 transform 并 scale 到逻辑像素
|
|
ctx.setTransform(1, 0, 0, 1, 0, 0); // 重置 transform
|
|
ctx.scale(dpr, dpr); // scale 到逻辑像素,后续绘制都使用逻辑像素
|
|
|
|
this.clear();
|
|
ctx.fillStyle = '#fff';
|
|
// 使用逻辑像素尺寸填充
|
|
ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
|
}
|
|
|
|
/**
|
|
* 清除画布
|
|
*/
|
|
clear() {
|
|
const canvas = this.canvas;
|
|
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
/**
|
|
* 绘制Header(逻辑像素,尺寸除以3)
|
|
*/
|
|
async drawHeader() {
|
|
this.currentX = 24;
|
|
this.currentY = 24;
|
|
await drawMathHeader({
|
|
canvas: this.canvas,
|
|
ctx: this.ctx,
|
|
headerType: this.headerType,
|
|
options: {
|
|
appName: this.options.appName || '涂鸦丫小程序',
|
|
appHint: this.options.appHint || '识字|识图|练字|打印',
|
|
title: this.options.title || '看数字,涂一涂',
|
|
subTitle:
|
|
this.options.subTitle || '找一找下面相同的数字,涂上颜色',
|
|
},
|
|
onHeaderDrawn: (currentY) => {
|
|
this.currentY = currentY;
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 绘制迷你Header(逻辑像素,尺寸除以3)
|
|
*/
|
|
drawMiniHeader() {
|
|
drawMathMiniHeader({
|
|
ctx: this.ctx,
|
|
canvasWidth: this.canvasWidth,
|
|
options: {
|
|
appName: this.options.appName || '涂鸦丫小程序',
|
|
title: this.options.title || '看数字,涂一涂',
|
|
},
|
|
onHeaderDrawn: (currentY) => {
|
|
this.currentY = currentY;
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 绘制分割线(逻辑像素,尺寸除以3)
|
|
*/
|
|
drawDivider() {
|
|
const { ctx, canvasWidth } = this;
|
|
const dividerY = this.currentY + 10; // 10px间距
|
|
|
|
ctx.strokeStyle = '#000';
|
|
ctx.lineWidth = 1;
|
|
ctx.beginPath();
|
|
ctx.moveTo(24, dividerY);
|
|
ctx.lineTo(canvasWidth - 24, dividerY);
|
|
ctx.stroke();
|
|
|
|
this.currentY = dividerY + 10; // 分割线下方10px间距
|
|
}
|
|
}
|