Files
doodle-mini/miniprogram/mathPages/numberDecompose/numberDecompose.ts
T
2025-12-08 13:01:16 +08:00

212 lines
7.1 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 NumberDecomposeDraw from '../service/numberDecomposeDraw';
import {
getMathPageCommonMethods,
CanvasDataState,
} from '../common/mathPageMixin';
// 获取公共方法
const commonMethods = getMathPageCommonMethods({
pagePath: 'numberDecompose/numberDecompose',
});
type DecomposeMode = 'with-image' | 'decompose' | 'compose';
Page({
canvas: null as Canvas | null,
ctx: null as RenderingContext | null,
boxHeight: 0,
boxWidth: 0,
drawService: null as NumberDecomposeDraw | null,
decomposeData: null as {
problems: Array<{
whole: number | null; // 总数(null表示组合模式需要填写)
part1: number | null; // 第一个部分(null表示需要填写)
part2: number | null; // 第二个部分(null表示需要填写)
imageIndex?: number; // 图片索引(有图片模式需要)
imageType?: 'fruits' | 'twelve-animals'; // 图片类型
}>;
mode: DecomposeMode;
} | null,
data: {
pageTitle: '10以内数的分与合',
subTitle: '学习数的分解与组合',
functionId: '',
hasContent: false,
showShareDialog: false,
showTypeSelector: true,
currentType: 'with-image',
currentTypeName: '有图片模式',
typeActions: [
{ name: '有图片模式', value: 'with-image' },
{ name: '分模式', value: 'decompose' },
{ name: '组合模式', value: 'compose' },
],
} as CanvasDataState & {
showTypeSelector: boolean;
currentType: DecomposeMode;
currentTypeName: string;
typeActions: Array<{ name: string; value: DecomposeMode }>;
},
onLoad(options: { id?: string; mode?: DecomposeMode }) {
const functionId = options.id || 'number-decompose';
const mode = options.mode || 'with-image';
const currentTypeName =
mode === 'with-image'
? '有图片模式'
: mode === 'decompose'
? '分模式'
: '组合模式';
this.setData({
currentType: mode,
currentTypeName,
});
this.initPageInfo(functionId, '10以内数的分与合');
},
onReady() {
this.initCanvas({
createDrawService: (canvas, ctx, options) => {
return new NumberDecomposeDraw(canvas, ctx, options);
},
drawServiceOptions: {
subTitle: this.data.subTitle,
},
onCanvasReady: () => {
// Canvas 初始化完成后,生成初始数据
this.onRandom();
},
});
},
/**
* 绘制Canvas内容
*/
async drawCanvas() {
if (!this.ctx || !this.drawService || !this.decomposeData) {
return;
}
try {
await this.drawService.draw(this.decomposeData);
this.setData({ hasContent: true });
} catch (error) {
console.error('绘制失败:', error);
this.setData({ hasContent: false });
}
},
/**
* 随机生成
*/
onRandom() {
this.generateDecomposeData();
this.drawCanvas();
},
/**
* 生成分解数据
*/
generateDecomposeData() {
const mode = this.data.currentType;
const problems: Array<{
whole: number;
part1: number | null;
part2: number | null;
imageIndex?: number;
imageType?: 'fruits' | 'twelve-animals';
}> = [];
if (mode === 'with-image') {
// 有图片模式:6个题目,一行两列,总共三行
const problemCount = 6;
for (let i = 0; i < problemCount; i++) {
// 生成总数(2-10
const whole = Math.floor(Math.random() * 9) + 2;
// 随机选择一个部分(1 到 whole-1)
const part1 = Math.floor(Math.random() * (whole - 1)) + 1;
const part2 = whole - part1;
// 随机决定显示 part1 还是 part2(另一个为 null
const showPart1 = Math.random() < 0.5;
const problem = {
whole,
part1: showPart1 ? part1 : null,
part2: showPart1 ? null : part2,
};
// 随机选择图片类型和索引
const imageType: 'fruits' | 'twelve-animals' =
Math.random() < 0.5 ? 'fruits' : 'twelve-animals';
const maxImageIndex = imageType === 'fruits' ? 22 : 12;
const imageIndex =
Math.floor(Math.random() * maxImageIndex) + 1;
problems.push({
...problem,
imageIndex,
imageType,
});
}
} else if (mode === 'decompose') {
// 分模式:12个题目,一行3个,总共4行
const problemCount = 15;
for (let i = 0; i < problemCount; i++) {
// 生成总数(2-10
const whole = Math.floor(Math.random() * 9) + 2;
// 随机选择一个部分(1 到 whole-1)
const part1 = Math.floor(Math.random() * (whole - 1)) + 1;
const part2 = whole - part1;
// 随机决定显示 part1 还是 part2(另一个为 null
const showPart1 = Math.random() < 0.5;
problems.push({
whole,
part1: showPart1 ? part1 : null,
part2: showPart1 ? null : part2,
});
}
} else if (mode === 'compose') {
// 组合模式:12个题目,一行3个,总共4行
const problemCount = 15;
for (let i = 0; i < problemCount; i++) {
// 生成总数(2-10
const whole = Math.floor(Math.random() * 9) + 2;
// 随机选择一个部分(1 到 whole-1)
const part1 = Math.floor(Math.random() * (whole - 1)) + 1;
const part2 = whole - part1;
// 组合模式:两个部分都显示,根节点为 null
problems.push({
whole: null, // 根节点需要填写
part1,
part2,
});
}
}
this.decomposeData = { problems, mode };
},
// ========== 使用公共方法 ==========
initCanvas: commonMethods.initCanvas,
exportToPrint: commonMethods.exportToPrint,
onShareAppMessage: commonMethods.onShareAppMessage,
onShareTimeline: commonMethods.onShareTimeline,
onCloseShareDialog: commonMethods.onCloseShareDialog,
onShareSuccess: commonMethods.onShareSuccess,
initPageInfo: commonMethods.initPageInfo,
/** 选择类型 */
onSelectType(event: any) {
const { name, value } = event.detail;
this.setData({
currentType: value,
currentTypeName: name,
});
// 重新生成数据
this.onRandom();
},
});