225 lines
6.5 KiB
TypeScript
225 lines
6.5 KiB
TypeScript
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 });
|
||
},
|
||
};
|
||
}
|