Files
doodle-mini/miniprogram/mathPages/numberObjectMatch/numberObjectMatch.ts
T

146 lines
4.5 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 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<string, any>,
) => {
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<string, number>();
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();
},
});