199 lines
5.5 KiB
TypeScript
199 lines
5.5 KiB
TypeScript
import { getRandomNumberColor } from '../../constants/mathFunctions';
|
|
import MissingNumberDraw from '../shared/service/missingNumberDraw';
|
|
import {
|
|
createMathPage,
|
|
CanvasDataState,
|
|
} from '../shared/common/mathPageMixin';
|
|
|
|
createMathPage({
|
|
canvas: null as Canvas | null,
|
|
ctx: null as RenderingContext | null,
|
|
boxHeight: 0,
|
|
boxWidth: 0,
|
|
drawService: null as MissingNumberDraw | null,
|
|
missingNumberData: null as {
|
|
grids: Array<{
|
|
numbers: (number | null)[];
|
|
colors: (string | null)[];
|
|
}>;
|
|
maxNumber: number;
|
|
} | null,
|
|
|
|
data: {
|
|
pageTitle: '填上缺少的数字',
|
|
subTitle: '在数字序列中找出并填写缺失的数字',
|
|
functionId: '',
|
|
hasContent: false,
|
|
showShareDialog: false,
|
|
showTypeSelector: true,
|
|
currentMode: 10,
|
|
currentModeName: '10以内',
|
|
typeActions: [
|
|
{ name: '10以内', value: 10 },
|
|
{ name: '20以内', value: 20 },
|
|
{ name: '40以内', value: 40 },
|
|
{ name: '50以内', value: 50 },
|
|
{ name: '80以内', value: 80 },
|
|
{ name: '100以内', value: 100 },
|
|
{ name: '120以内', value: 120 },
|
|
],
|
|
} as CanvasDataState & {
|
|
showTypeSelector: boolean;
|
|
currentMode: number;
|
|
currentModeName: string;
|
|
typeActions: Array<{ name: string; value: number }>;
|
|
},
|
|
|
|
onLoad(options: { id?: string; mode?: number }) {
|
|
const functionId = options.id || 'missing-number';
|
|
this.initPageInfo(functionId, '填上缺少的数字');
|
|
|
|
this.setData({
|
|
currentMode: options.mode || 10,
|
|
currentModeName: options.mode ? `${options.mode}以内` : '10以内',
|
|
});
|
|
},
|
|
|
|
onReady() {
|
|
this.initCanvas({
|
|
createDrawService: (
|
|
canvas: Canvas,
|
|
ctx: RenderingContext,
|
|
options?: Record<string, any>,
|
|
) => {
|
|
return new MissingNumberDraw(canvas, ctx, options);
|
|
},
|
|
drawServiceOptions: {
|
|
subTitle: this.data.subTitle,
|
|
},
|
|
onCanvasReady: () => {
|
|
// Canvas 初始化完成后,生成初始数据
|
|
this.onRandom();
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 绘制Canvas内容
|
|
*/
|
|
async drawCanvas() {
|
|
if (!this.ctx || !this.drawService || !this.missingNumberData) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await this.drawService.draw(
|
|
this.missingNumberData,
|
|
String(this.data.currentMode),
|
|
);
|
|
this.setData({ hasContent: true });
|
|
} catch (error) {
|
|
console.error('绘制失败:', error);
|
|
this.setData({ hasContent: false });
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 随机生成
|
|
*/
|
|
onRandom() {
|
|
const maxNumber = this.data.currentMode;
|
|
this.generateMissingNumberData(maxNumber);
|
|
this.drawCanvas();
|
|
},
|
|
|
|
/**
|
|
* 生成缺失数字数据
|
|
*/
|
|
generateMissingNumberData(maxNumber: number) {
|
|
const grids: Array<{
|
|
numbers: (number | null)[];
|
|
colors: (string | null)[];
|
|
}> = [];
|
|
const gridMap = {
|
|
10: {
|
|
gridCount: 3,
|
|
},
|
|
20: {
|
|
gridCount: 2,
|
|
},
|
|
40: {
|
|
gridCount: 2,
|
|
},
|
|
50: {
|
|
gridCount: 2,
|
|
},
|
|
80: {
|
|
gridCount: 1,
|
|
},
|
|
100: {
|
|
gridCount: 1,
|
|
},
|
|
120: {
|
|
gridCount: 1,
|
|
},
|
|
};
|
|
const { gridCount } = gridMap[maxNumber as keyof typeof gridMap];
|
|
|
|
// 生成多个网格
|
|
for (let gridIndex = 0; gridIndex < gridCount; gridIndex++) {
|
|
let startNumber = 1;
|
|
let endNumber = maxNumber;
|
|
|
|
const actualNumbersPerGrid = endNumber - startNumber + 1;
|
|
|
|
const numbers: number[] = Array.from(
|
|
{ length: actualNumbersPerGrid },
|
|
(_, i) => startNumber + i,
|
|
);
|
|
|
|
// 随机隐藏一部分数字(隐藏40-60%)
|
|
const hideCount = Math.floor(
|
|
actualNumbersPerGrid * (0.4 + Math.random() * 0.2),
|
|
);
|
|
const hiddenIndices = new Set<number>();
|
|
|
|
while (hiddenIndices.size < hideCount) {
|
|
const randomIndex = Math.floor(
|
|
Math.random() * actualNumbersPerGrid,
|
|
);
|
|
hiddenIndices.add(randomIndex);
|
|
}
|
|
|
|
const gridNumbers: (number | null)[] = numbers.map((num, index) =>
|
|
hiddenIndices.has(index) ? null : num,
|
|
);
|
|
|
|
// 为每个数字分配颜色(包括null位置)
|
|
const gridColors: (string | null)[] = gridNumbers.map((num) =>
|
|
num ? this.getRandomNumberColor() : null,
|
|
);
|
|
|
|
grids.push({ numbers: gridNumbers, colors: gridColors });
|
|
}
|
|
|
|
this.missingNumberData = {
|
|
grids,
|
|
maxNumber,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* 获取随机数字颜色
|
|
*/
|
|
getRandomNumberColor(): string {
|
|
return getRandomNumberColor();
|
|
},
|
|
|
|
/** 选择类型 */
|
|
onSelectType(event: any) {
|
|
const { name, value } = event.detail;
|
|
this.setData({
|
|
currentMode: value,
|
|
currentModeName: name,
|
|
});
|
|
// 重新生成数据
|
|
this.onRandom();
|
|
},
|
|
});
|