import NumberObjectMatchDraw from '../shared/service/numberObjectMatchDraw'; import { createMathPage, CanvasDataState, } from '../shared/common/mathPageMixin'; import { NumberObjectMatchData } from '../shared/service/numberObjectMatchDraw'; createMathPage({ canvas: null as Canvas | null, ctx: null as RenderingContext | null, boxHeight: 0, boxWidth: 0, drawService: null as NumberObjectMatchDraw | null, matchData: null as NumberObjectMatchData | null, data: { pageTitle: '数物对应', functionId: '', hasContent: false, showShareDialog: false, } as CanvasDataState, onLoad(options: { id?: string }) { const functionId = options.id || 'number-object-match'; this.initPageInfo(functionId, '数物对应'); }, onReady() { this.initCanvas({ createDrawService: ( canvas: Canvas, ctx: RenderingContext, options?: Record, ) => { return new NumberObjectMatchDraw(canvas, ctx, options); }, drawServiceOptions: {}, onCanvasReady: () => { // 初始随机生成 this.onRandom(); }, }); }, /** * 绘制Canvas内容 */ async drawCanvas() { if (!this.ctx || !this.drawService || !this.matchData) { return; } try { await this.drawService.draw(this.matchData); this.setData({ hasContent: true }); } catch (error) { console.error('绘制失败:', error); this.setData({ hasContent: false }); } }, /** * 随机生成 */ onRandom() { // 从两个目录中随机选择4张不重复的图片 // fruits: 1-22, twelve-animals: 1-12 const fruitsIndices = Array.from({ length: 22 }, (_, i) => i + 1); const animalsIndices = Array.from({ length: 12 }, (_, i) => i + 1); // 合并所有可用的图片索引 const allImages: Array<{ imageIndex: number; folder: 'fruits' | 'twelve-animals'; }> = [ ...fruitsIndices.map((idx) => ({ imageIndex: idx, folder: 'fruits' as const, })), ...animalsIndices.map((idx) => ({ imageIndex: idx, folder: 'twelve-animals' as const, })), ]; // 随机打乱并选择4张不重复的图片 const shuffled = [...allImages].sort(() => Math.random() - 0.5); const selectedImages = shuffled.slice(0, 4); // 生成上面区域的16张图片(4行4列) // 每张图片随机出现,并添加随机偏移 const gridImages: Array<{ imageIndex: number; folder: 'fruits' | 'twelve-animals'; offsetX: number; offsetY: number; }> = []; const maxOffset = 15; // 最大偏移量 for (let i = 0; i < 20; i++) { // 从选中的4张图片中随机选择一张 const randomImage = selectedImages[ Math.floor(Math.random() * selectedImages.length) ]; // 生成随机偏移(-maxOffset 到 maxOffset) const offsetX = (Math.random() - 0.5) * 2 * maxOffset; const offsetY = (Math.random() - 0.5) * 2 * maxOffset; gridImages.push({ ...randomImage, offsetX, offsetY, }); } // 下面区域第一行的4张图片(使用选中的4张图片) const bottomImages = [...selectedImages]; // 计算每个图片在上面区域出现的次数 const imageCountMap = new Map(); gridImages.forEach((item) => { const key = `${item.folder}-${item.imageIndex}`; imageCountMap.set(key, (imageCountMap.get(key) || 0) + 1); }); // 获取每个图片的数量(按 selectedImages 的顺序) const imageCounts = selectedImages.map((img) => { const key = `${img.folder}-${img.imageIndex}`; return imageCountMap.get(key) || 0; }); // 将数量乱序排列 const bottomNumbers = [...imageCounts].sort(() => Math.random() - 0.5); this.matchData = { gridImages, bottomImages, bottomNumbers, }; this.drawCanvas(); }, });