import CountingSelectDraw from '../shared/service/countingSelectDraw'; import { createMathPage, CanvasDataState, } from '../shared/common/mathPageMixin'; createMathPage({ 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, 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, ) => { 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 }; }, });