Files
doodle-mini/miniprogram/mathPages/countingSelect/countingSelect.ts
T
2025-12-09 17:33:58 +08:00

169 lines
6.2 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 CountingSelectDraw from '../service/countingSelectDraw';
import { applyMathPageMixin, CanvasDataState } from '../common/mathPageMixin';
Page(
applyMathPageMixin(
{
canvas: null as Canvas | null,
ctx: null as RenderingContext | null,
boxHeight: 0,
boxWidth: 0,
drawService: null as CountingSelectDraw | null,
countingSelectData: null as {
problems: Array<{
count: number; // 图片数量(正确答案)
imageIndex: number; // 图片索引
imageType: 'fruits' | 'twelve-animals'; // 图片类型
options?: number[]; // 三个数字选项(选一选模式需要)
correctIndex?: number; // 正确答案在options中的索引(选一选模式需要)
}>;
} | null,
data: {
pageTitle: '数一数,选一选',
subTitle: '数出物品数量,从多个选项中选择正确答案',
functionId: '',
hasContent: false,
showShareDialog: false,
} as CanvasDataState & {
showTypeSelector?: boolean;
currentType?: string;
currentTypeName?: string;
typeActions?: Array<{ name: string; value: any }>;
},
onLoad(options: { id?: string }) {
const functionId = options.id || 'counting-select';
// 初始化页面信息(会从 mathFunctions.ts 读取 title 和 desc
this.initPageInfo(functionId, '数一数,选一选');
},
onReady() {
this.initCanvas({
createDrawService: (
canvas: Canvas,
ctx: RenderingContext,
options?: Record<string, any>,
) => {
return new CountingSelectDraw(canvas, ctx, options);
},
drawServiceOptions: {
subTitle: this.data.subTitle,
},
onCanvasReady: () => {
// Canvas 初始化完成后,生成初始数据
this.onRandom();
},
});
},
/**
* 绘制Canvas内容
*/
async drawCanvas() {
if (
!this.ctx ||
!this.drawService ||
!this.countingSelectData
) {
return;
}
try {
// 判断是选一选还是填一填模式
const mode =
this.data.functionId === 'counting-fill'
? 'fill'
: 'select';
await this.drawService.draw(this.countingSelectData, mode);
this.setData({ hasContent: true });
} catch (error) {
console.error('绘制失败:', error);
this.setData({ hasContent: false });
}
},
/**
* 随机生成
*/
onRandom() {
this.generateCountingSelectData();
this.drawCanvas();
},
/**
* 生成数一数选一选/填一填数据
*/
generateCountingSelectData() {
const isFillMode = this.data.functionId === 'counting-fill';
const problems: Array<{
count: number;
imageIndex: number;
imageType: 'fruits' | 'twelve-animals';
options?: number[];
correctIndex?: number;
}> = [];
// 生成9道题目
for (let i = 0; i < 9; i++) {
// 随机选择图片类型
const imageType: 'fruits' | 'twelve-animals' =
Math.random() < 0.5 ? 'fruits' : 'twelve-animals';
// 根据图片类型确定最大索引
const maxImageIndex = imageType === 'fruits' ? 22 : 12;
// 生成图片数量(1-10
const count = Math.floor(Math.random() * 10) + 1;
// 随机选择图片索引
const imageIndex =
Math.floor(Math.random() * maxImageIndex) + 1;
const problem: {
count: number;
imageIndex: number;
imageType: 'fruits' | 'twelve-animals';
options?: number[];
correctIndex?: number;
} = {
count,
imageIndex,
imageType,
};
// 选一选模式:生成三个选项
if (!isFillMode) {
const options: number[] = [];
const correctIndex = Math.floor(Math.random() * 3);
for (let j = 0; j < 3; j++) {
if (j === correctIndex) {
options.push(count); // 正确答案
} else {
// 生成错误答案(与正确答案不同)
let wrongAnswer: number;
do {
wrongAnswer =
Math.floor(Math.random() * 10) + 1;
} while (wrongAnswer === count);
options.push(wrongAnswer);
}
}
problem.options = options;
problem.correctIndex = correctIndex;
}
problems.push(problem);
}
this.countingSelectData = { problems };
},
},
{
pagePath: 'countingSelect/countingSelect',
},
),
);