204 lines
5.7 KiB
TypeScript
204 lines
5.7 KiB
TypeScript
import { getRandomNumberColor } from '../../constants/colors';
|
|
import MissingNumberDraw from '../service/missingNumberDraw';
|
|
import {
|
|
getMathPageCommonMethods,
|
|
CanvasDataState,
|
|
} from '../common/mathPageMixin';
|
|
|
|
// 获取公共方法
|
|
const commonMethods = getMathPageCommonMethods({
|
|
pagePath: 'missingNumber/missingNumber',
|
|
});
|
|
|
|
Page({
|
|
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,
|
|
currentType: 10,
|
|
currentTypeName: '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;
|
|
currentType: number;
|
|
currentTypeName: string;
|
|
typeActions: Array<{ name: string; value: number }>;
|
|
},
|
|
|
|
onLoad(options: { id?: string }) {
|
|
const functionId = options.id || 'missing-number';
|
|
this.initPageInfo(functionId, '填上缺少的数字');
|
|
},
|
|
|
|
onReady() {
|
|
this.initCanvas({
|
|
createDrawService: (canvas, ctx, options) => {
|
|
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.currentType),
|
|
);
|
|
this.setData({ hasContent: true });
|
|
} catch (error) {
|
|
console.error('绘制失败:', error);
|
|
this.setData({ hasContent: false });
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 随机生成
|
|
*/
|
|
onRandom() {
|
|
const maxNumber = this.data.currentType;
|
|
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();
|
|
},
|
|
|
|
// ========== 使用公共方法 ==========
|
|
initCanvas: commonMethods.initCanvas,
|
|
exportToPrint: commonMethods.exportToPrint,
|
|
onShareAppMessage: commonMethods.onShareAppMessage,
|
|
onShareTimeline: commonMethods.onShareTimeline,
|
|
onCloseShareDialog: commonMethods.onCloseShareDialog,
|
|
onShareSuccess: commonMethods.onShareSuccess,
|
|
initPageInfo: commonMethods.initPageInfo,
|
|
|
|
/** 选择类型 */
|
|
onSelectType(event: any) {
|
|
const { name, value } = event.detail;
|
|
this.setData({
|
|
currentType: value,
|
|
currentTypeName: name,
|
|
});
|
|
// 重新生成数据
|
|
this.onRandom();
|
|
},
|
|
});
|