Files
doodle-mini/miniprogram/focusPages/shapeSymbol/shapeSymbol.ts
T
2025-12-17 10:45:09 +08:00

156 lines
5.2 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 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();
},
});