Files
doodle-mini/miniprogram/mathPages/common/mathPageMixin.ts
T
2025-12-05 14:53:40 +08:00

225 lines
6.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 { 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<string, any>,
) => BaseMathDrawService;
/**
* 绘制服务的选项
*/
drawServiceOptions?: Record<string, any>;
/**
* 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 });
},
};
}