Files
doodle-mini/miniprogram/mathPages/shared/service/numberFindDraw.ts
T
2026-04-09 17:43:22 +08:00

136 lines
4.6 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 { BaseDrawService } from '../../../core/draw/baseDraw';
import { drawNumberPreview } from './numberPreviewDraw';
import { drawNumberWriteContent } from './numberWriteDraw';
/**
* 数字涂色绘制服务
* 组合使用基础绘制服务、预览区域绘制服务和内容区域绘制服务
*/
class NumberFindDraw extends BaseDrawService {
selectedNumber: number;
functionId: string; // 功能ID,用于判断绘制类型
constructor(
canvas: Canvas,
ctx: RenderingContext,
options?: Record<string, any>,
) {
super(canvas, ctx, options);
this.selectedNumber = 0;
this.functionId = options?.functionId || 'number-find';
}
async draw(selectedNumber: number) {
if (selectedNumber <= 0 || selectedNumber > 10) {
return;
}
this.selectedNumber = selectedNumber;
this.prepareDraw();
await this.drawHeaderAndDivider();
// 绘制预览区域
await drawNumberPreview({
canvas: this.canvas,
ctx: this.ctx,
selectedNumber: this.selectedNumber,
canvasWidth: this.canvasWidth,
startY: this.currentY,
onDrawn: (currentY) => {
this.currentY = currentY;
},
});
// 绘制内容区域(根据 functionId 选择不同的绘制方法)
this.drawDivider();
if (this.functionId === 'number-write') {
// 书写类型:绘制书写行
drawNumberWriteContent({
ctx: this.ctx,
selectedNumber: this.selectedNumber,
canvasWidth: this.canvasWidth,
startY: this.currentY,
});
} else {
// 默认类型(number-find):绘制数字涂色内容
this.drawNumberContent({
ctx: this.ctx,
selectedNumber: this.selectedNumber,
canvasWidth: this.canvasWidth,
startY: this.currentY,
});
}
}
/**
* 绘制数字涂色内容区域
*/
private drawNumberContent(params: {
ctx: RenderingContext;
selectedNumber: number;
canvasWidth: number;
startY: number;
}): void {
const { ctx, selectedNumber, canvasWidth, startY } = params;
const rows = 6;
const radius = 26; // 约26.67
const fontSize = 24; // 24
const startYPos = startY + 10 + radius; // 约47.33
const startX1 = 100 + radius; // 约112.22
const startX2 = 60 + radius; // 约75.56
const spaceWidthFirst = (canvasWidth - startX1 * 2) / (5 - 1);
const spaceWidthSecond = (canvasWidth - startX2 * 2) / (6 - 1);
const spaceHeight = 18; // 18
ctx.moveTo(startX1, startYPos);
for (let i = 0; i < rows; i++) {
const cols = i % 2 === 0 ? 5 : 6;
for (let j = 0; j < cols; j++) {
const y = startYPos + i * (spaceHeight + radius * 2);
const x =
i % 2 === 0
? startX1 + j * spaceWidthFirst
: startX2 + j * spaceWidthSecond;
// 随机生成1-10的数字,但确保包含选中的数字
let number: number;
if (i === 0 && j === 0) {
// 第一个位置固定为选中的数字
number = selectedNumber;
} else {
// 其他位置随机,但增加选中数字出现的概率
const random = Math.random();
if (random < 0.3) {
// 30%概率是选中的数字
number = selectedNumber;
} else {
// 70%概率是其他随机数字
number = Math.floor(Math.random() * 10) + 1;
}
}
// 绘制圆形背景(线宽除以3
ctx.fillStyle = '#fff';
ctx.strokeStyle = '#000';
ctx.lineWidth = 1; // 约1.33
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
// 绘制数字(字体大小除以3
ctx.fillStyle = '#333';
ctx.font = `bold ${fontSize}px "Microsoft Yahei"`;
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText(String(number), x, y, radius * 2);
}
}
}
}
export default NumberFindDraw;