import { PAPER_SIZE } from '../constants/colors'; import { drawBaseHeader, drawBaseMiniHeader } from './baseHeaderDraw'; /** * 基础绘制服务 * 包含Paper设置和Header绘制功能,可被所有绘制服务复用 * * 提供功能: * - Canvas 初始化和配置 * - Paper 尺寸设置(支持 A4 等标准尺寸) * - Header 绘制(支持完整 Header 和迷你 Header) * - 分割线绘制 * - 打印配置管理 */ export class BaseDrawService { headerType: PrintHeader = 'wechat'; canvas: WechatMiniprogram.Canvas; ctx: RenderingContext; options: Record; paperSize: PaperSize; currentX: number; currentY: number; canvasWidth: number; // 逻辑像素宽度 canvasHeight: number; // 逻辑像素高度 constructor( canvas: Canvas, ctx: RenderingContext, options?: Record, ) { options = options || {}; const { appName, appHint } = getApp().getPrintConfig(); 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]; 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 = 25; this.currentY = 25; await drawBaseHeader({ 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() { drawBaseMiniHeader({ ctx: this.ctx, canvasWidth: this.canvasWidth, options: { appName: this.options.appName || '涂鸦丫小程序', title: this.options.title || '看数字,涂一涂', }, onHeaderDrawn: (currentY) => { console.log('drawMiniHeader currentY', currentY); this.currentY = currentY; }, }); } /** * 绘制分割线(逻辑像素,尺寸除以3) */ drawDivider() { const { ctx, canvasWidth } = this; const dividerY = this.currentY; ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(24, dividerY); ctx.lineTo(canvasWidth - 24, dividerY); ctx.stroke(); this.currentY = dividerY + 10; // 分割线下方10px间距 } }