import CountMatchDraw from '../service/countMatchDraw'; import NumberColorDraw from '../service/numberColorDraw'; 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 CountMatchDraw | NumberColorDraw | null, matchData: null as { leftNumbers: number[]; rightNumbers: number[]; } | null, colorData: null as { numbers: number[]; } | null, data: { pageTitle: '数一数,连一连', functionId: '', hasContent: false, showShareDialog: false, showTypeSelector: true, // 控制是否显示类型选择器 currentType: 'twelve-animals', // 'twelve-animals' 或 'fruits' 或 'circle' 或 'caterpillar' currentTypeName: '十二生肖', typeActions: [ { name: '十二生肖', value: 'twelve-animals' }, { name: '水果', value: 'fruits' }, ], } as CanvasDataState & { showTypeSelector: boolean; currentType: string; currentTypeName: string; typeActions: Array<{ name: string; value: string }>; }, onLoad(options: { id?: string }) { const functionId = options.id || 'counting-matching'; this.setData({ functionId }); const functionItem = require('../../constants/mathFunctions').MATH_FUNCTION_TYPES.find( (item: any) => item.id === functionId, ); const pageTitle = functionItem?.title || '数一数,连一连'; this.setData({ pageTitle }); this.initPageInfo(functionId, pageTitle); // 根据 functionId 设置不同的类型选择器 if (functionId === 'number-coloring') { this.setData({ currentType: 'caterpillar', currentTypeName: '毛毛虫', typeActions: [ { name: '毛毛虫', value: 'caterpillar' }, { name: '圆圈', value: 'circle' }, ], }); } }, onReady() { this.initCanvas({ createDrawService: ( canvas: Canvas, ctx: RenderingContext, options?: Record, ) => { // 根据 functionId 创建不同的绘制服务 if (this.data.functionId === 'number-coloring') { return new NumberColorDraw(canvas, ctx, options); } else { return new CountMatchDraw(canvas, ctx, options); } }, drawServiceOptions: { subTitle: this.data.functionId === 'number-coloring' ? '按数字给相应的圆圈涂上颜色' : '通过连线配对数字和对应的数量图形', }, onCanvasReady: () => { // 初始随机生成 this.onRandom(); }, }); }, /** * 绘制Canvas内容 */ async drawCanvas() { if (!this.ctx || !this.drawService) { return; } try { if (this.data.functionId === 'number-coloring') { if (!this.colorData) { return; } await (this.drawService as NumberColorDraw).draw( this.colorData, this.data.currentType, ); } else { if (!this.matchData) { return; } await (this.drawService as CountMatchDraw).draw( this.matchData, this.data.currentType, ); } this.setData({ hasContent: true }); } catch (error) { console.error('绘制失败:', error); this.setData({ hasContent: false }); } }, /** * 随机生成 */ onRandom() { if (this.data.functionId === 'number-coloring') { // 按数字涂颜色模式:生成6个随机数字(1-10) const availableNumbers = Array.from( { length: 10 }, (_, i) => i + 1, ); const numbers: number[] = []; for (let i = 0; i < 6; i++) { const randomIndex = Math.floor( Math.random() * availableNumbers.length, ); const number = availableNumbers.splice( randomIndex, 1, )[0]; numbers.push(number); } this.colorData = { numbers }; } else { // 数一数连一连模式:生成5个不同的数字(1-10) const availableNumbers = Array.from( { length: 10 }, (_, i) => i + 1, ); const leftNumbers: number[] = []; for (let i = 0; i < 5; i++) { const randomIndex = Math.floor( Math.random() * availableNumbers.length, ); const number = availableNumbers.splice( randomIndex, 1, )[0]; leftNumbers.push(number); } // 复制数字数组并打乱顺序,作为右侧显示的数字 const rightNumbers = [...leftNumbers]; for (let i = rightNumbers.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [rightNumbers[i], rightNumbers[j]] = [ rightNumbers[j], rightNumbers[i], ]; } this.matchData = { leftNumbers, rightNumbers }; } this.drawCanvas(); }, /** 选择类型 */ onSelectType(event: any) { const { name, value } = event.detail; this.setData({ currentType: value, currentTypeName: name, }); // 重新生成数据 this.onRandom(); }, }, { pagePath: 'countMatch/countMatch', }, ), );