156 lines
5.2 KiB
TypeScript
156 lines
5.2 KiB
TypeScript
import ShapeSymbolDraw from '../shared/service/shapeSymbolDraw';
|
||
import { createFocusPage } from '../shared/common/focusPageMixin';
|
||
import { ShapeSymbolData } from '../shared/service/shapeSymbolDraw';
|
||
import { SHAPE_SYMBOL_SHAPES } from '../shared/shapes/shapeSymbolShapes';
|
||
import { getRandomNumberColor } from '../../constants/colors';
|
||
|
||
createFocusPage({
|
||
canvas: null as Canvas | null,
|
||
ctx: null as RenderingContext | null,
|
||
boxHeight: 0,
|
||
boxWidth: 0,
|
||
drawService: null as ShapeSymbolDraw | null,
|
||
gridData: null as ShapeSymbolData | null,
|
||
|
||
data: {
|
||
pageTitle: '图形符号配对',
|
||
functionId: '',
|
||
hasContent: false,
|
||
showShareDialog: false,
|
||
},
|
||
|
||
onLoad(options: { id?: string }) {
|
||
const functionId = options.id || 'shape-symbol';
|
||
this.setData({
|
||
functionId,
|
||
});
|
||
this.initPageInfo(functionId, '图形符号配对');
|
||
},
|
||
|
||
onReady() {
|
||
this.initCanvas({
|
||
createDrawService: (
|
||
canvas: Canvas,
|
||
ctx: RenderingContext,
|
||
options?: Record<string, any>,
|
||
) => {
|
||
return new ShapeSymbolDraw(canvas, ctx, options);
|
||
},
|
||
drawServiceOptions: {
|
||
title: this.data.pageTitle,
|
||
subTitle: '根据图形画对应的符号',
|
||
functionId: this.data.functionId,
|
||
},
|
||
onCanvasReady: () => {
|
||
// 初始随机生成
|
||
this.onRandom();
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 绘制Canvas内容
|
||
*/
|
||
async drawCanvas() {
|
||
if (!this.ctx || !this.drawService || !this.gridData) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
await this.drawService.draw(this.gridData);
|
||
this.setData({ hasContent: true });
|
||
} catch (error) {
|
||
console.error('绘制失败:', error);
|
||
this.setData({ hasContent: false });
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 随机生成
|
||
*/
|
||
onRandom() {
|
||
// 从9种图形中随机选择4个
|
||
const shuffled = [...SHAPE_SYMBOL_SHAPES].sort(
|
||
() => Math.random() - 0.5,
|
||
);
|
||
const selectedShapes = shuffled.slice(0, 4);
|
||
|
||
// 符号类型:加号、减号、乘号、对号
|
||
const symbols = ['+', '-', '×', '✓'];
|
||
// 随机打乱符号顺序
|
||
const shuffledSymbols = [...symbols].sort(() => Math.random() - 0.5);
|
||
|
||
// 创建图形和符号的映射关系(按位置对应),并为每个图形分配不同的颜色
|
||
const shapeColorMap = new Map<string, string>(); // 存储每个图形ID对应的颜色
|
||
const usedColors = new Set<string>(); // 记录已使用的颜色,确保4个图形颜色不同
|
||
const legendMapping: Array<{
|
||
shapeId: string;
|
||
symbol: string;
|
||
color: string;
|
||
}> = [];
|
||
|
||
for (let i = 0; i < 4; i++) {
|
||
const shape = selectedShapes[i];
|
||
|
||
// 为每个图形分配颜色,确保4个图形颜色都不相同
|
||
let color: string;
|
||
if (shapeColorMap.has(shape.id)) {
|
||
// 如果这个图形已经分配过颜色,使用之前的颜色
|
||
color = shapeColorMap.get(shape.id)!;
|
||
} else {
|
||
// 生成新颜色,确保不与已使用的颜色重复
|
||
do {
|
||
color = getRandomNumberColor();
|
||
} while (usedColors.has(color));
|
||
shapeColorMap.set(shape.id, color);
|
||
usedColors.add(color);
|
||
}
|
||
|
||
legendMapping.push({
|
||
shapeId: shape.id,
|
||
symbol: shuffledSymbols[i],
|
||
color: color,
|
||
});
|
||
}
|
||
|
||
// 生成练习区域的数据(6行7列,每两行一组)
|
||
const practiceRows: Array<
|
||
Array<{ shapeId: string | null; symbol: string | null }>
|
||
> = [];
|
||
for (let groupIndex = 0; groupIndex < 4; groupIndex++) {
|
||
// 每组第一行:随机展示图形
|
||
const shapeRow: Array<{
|
||
shapeId: string | null;
|
||
symbol: string | null;
|
||
}> = [];
|
||
for (let col = 0; col < 8; col++) {
|
||
// 随机选择一个图形(从选中的4个中选)
|
||
const randomShape =
|
||
selectedShapes[
|
||
Math.floor(Math.random() * selectedShapes.length)
|
||
];
|
||
shapeRow.push({ shapeId: randomShape.id, symbol: null });
|
||
}
|
||
practiceRows.push(shapeRow);
|
||
|
||
// 每组第二行:空着,让小朋友涂符号
|
||
const symbolRow: Array<{
|
||
shapeId: string | null;
|
||
symbol: string | null;
|
||
}> = [];
|
||
for (let col = 0; col < 8; col++) {
|
||
symbolRow.push({ shapeId: null, symbol: null });
|
||
}
|
||
practiceRows.push(symbolRow);
|
||
}
|
||
|
||
this.gridData = {
|
||
legendMapping,
|
||
practiceRows,
|
||
shapeColorMap: Object.fromEntries(shapeColorMap), // 转换为普通对象传递给绘制服务
|
||
};
|
||
|
||
this.drawCanvas();
|
||
},
|
||
});
|