feat:2.6.1增加 数物对应 和 根据颜色画图形

This commit is contained in:
R524809
2025-12-23 13:35:19 +08:00
parent 9b6a0a26cc
commit 20496c3cc8
28 changed files with 940 additions and 277 deletions
@@ -0,0 +1,145 @@
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();
},
});