import { PAPER_SIZE } from '../../constants/colors'; import { checkAndSaveImage } from '../../utils/saveImage'; import { shouldShowShareGuide } from '../../utils/shareGuide'; import { BaseMathDrawService } from '../service/baseMathDraw'; import { MATH_FUNCTION_TYPES, MathFunctionType, } from '../../constants/mathFunctions'; /** * Canvas 相关的页面实例属性 */ export interface MathPageCanvasInstance { canvas: Canvas | null; ctx: RenderingContext | null; boxHeight: number; boxWidth: number; drawService: BaseMathDrawService | null; } /** * Canvas 数据状态接口 */ export interface CanvasDataState { hasContent: boolean; showShareDialog: boolean; boxWidth: number; boxHeight: number; functionId: string; pageTitle: string; subTitle?: string; } /** * Canvas 初始化选项 */ export interface InitCanvasOptions { /** * 创建绘制服务的工厂函数 */ createDrawService: ( canvas: Canvas, ctx: RenderingContext, options?: Record, ) => BaseMathDrawService; /** * 绘制服务的选项 */ drawServiceOptions?: Record; /** * Canvas 初始化完成后回调 */ onCanvasReady?: () => void; } /** * 分享配置选项 */ export interface ShareOptions { /** * 页面路径(相对于 mathPages 目录,例如:'missingNumber/missingNumber') */ pagePath: string; } /** * 获取数学页面的公共方法 * 这些方法可以在所有数学页面中复用 */ export function getMathPageCommonMethods(shareOptions: ShareOptions) { return { /** * 初始化 Canvas */ initCanvas( this: MathPageCanvasInstance & { data: CanvasDataState }, options: InitCanvasOptions, ) { const query = wx.createSelectorQuery(); query .select('#canvasWrapper') .boundingClientRect((rect) => { if (!rect) return; const { width, height } = PAPER_SIZE['A4']; const boxWidth = rect.width; const boxHeight = boxWidth / (width / height); this.boxHeight = boxHeight; this.boxWidth = boxWidth; this.setData({ boxWidth, boxHeight }); const canvas = wx .createSelectorQuery() .select('#canvasContent'); canvas.fields({ node: true, size: true }).exec((res) => { if (res[0]) { const canvasNode = res[0].node; const ctx = canvasNode.getContext('2d'); const dpr = wx.getSystemInfoSync().pixelRatio; canvasNode.width = boxWidth * dpr; canvasNode.height = boxHeight * dpr; ctx.scale(dpr, dpr); this.canvas = canvasNode; this.ctx = ctx; // 创建绘制服务 const drawServiceOptions = { title: this.data.pageTitle, subTitle: this.data.subTitle || '', ...options.drawServiceOptions, }; this.drawService = options.createDrawService( canvasNode, ctx, drawServiceOptions, ); // 执行初始化完成回调 if (options.onCanvasReady) { options.onCanvasReady.call(this); } } }); }) .exec(); }, /** * 导出打印 */ exportToPrint( this: MathPageCanvasInstance & { data: CanvasDataState }, ) { if (!this.canvas || !this.data.hasContent) { return; } if (shouldShowShareGuide()) { this.setData({ showShareDialog: true }); return; } checkAndSaveImage(this.canvas); }, /** * 分享小程序 */ onShareAppMessage( this: MathPageCanvasInstance & { data: CanvasDataState }, ) { return { title: '涂鸦丫-数学学习涂鸦卡', path: `/mathPages/${shareOptions.pagePath}?id=${this.data.functionId}`, imageUrl: 'https://cdn.joeyone.cn/doodle/share-img/index-share-v2.png', }; }, /** * 分享到朋友圈 */ onShareTimeline( this: MathPageCanvasInstance & { data: CanvasDataState }, ) { return { title: '涂鸦丫-数学学习涂鸦卡', query: `id=${this.data.functionId}`, imageUrl: 'https://cdn.joeyone.cn/doodle/share-img/index-share-v2.png', }; }, /** * 关闭分享引导弹窗 */ onCloseShareDialog( this: MathPageCanvasInstance & { data: CanvasDataState }, ) { this.setData({ showShareDialog: false }); }, /** * 分享成功回调 */ onShareSuccess( this: MathPageCanvasInstance & { data: CanvasDataState }, ) { this.setData({ showShareDialog: false }); if (this.canvas) { checkAndSaveImage(this.canvas); } }, /** * 初始化页面信息(从 functionId 获取标题等信息) */ initPageInfo( this: MathPageCanvasInstance & { data: CanvasDataState }, functionId: string, defaultTitle?: string, ) { const functionItem = MATH_FUNCTION_TYPES.find( (item: MathFunctionType) => item.id === functionId, ); const title = functionItem?.title || defaultTitle || ''; const desc = functionItem?.desc || ''; this.setData({ pageTitle: title, subTitle: desc, functionId, }); wx.setNavigationBarTitle({ title }); }, }; }