64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import { BaseDrawService } from '../../../core/draw/baseDraw';
|
|
import type { ClockProblem, ClockReadingData } from '../generators/clock-generator';
|
|
import { drawAnalogClock, drawTimeInputBox } from './drawAnalogClock';
|
|
|
|
const ROWS = 4;
|
|
const COLS = 3;
|
|
const MARGIN_X = 28;
|
|
const CLOCK_RADIUS = 52; // 原 58 的 90%
|
|
const CLOCK_TO_BOX_GAP = 13; // 原 20 缩小三分之一
|
|
const INPUT_BOX_W = 88;
|
|
const INPUT_BOX_H = 30;
|
|
const ROW_GAP = 28; // 原 14 的两倍
|
|
const CONTENT_BOTTOM_PADDING = 28;
|
|
|
|
/**
|
|
* 认识钟表绘制服务:4×3 网格,每组钟表 + 填写框
|
|
*/
|
|
export default class ClockReadingDraw extends BaseDrawService {
|
|
async draw(data: ClockReadingData) {
|
|
if (!data?.problems?.length) return;
|
|
|
|
this.prepareDraw();
|
|
await this.drawHeaderAndDivider();
|
|
this.drawGrid(data.problems);
|
|
this.drawPrintFooter({ mode: 'A' });
|
|
}
|
|
|
|
private drawGrid(problems: ClockProblem[]) {
|
|
const { ctx, canvasWidth, canvasHeight } = this;
|
|
const contentTop = this.currentY;
|
|
const availableH = canvasHeight - contentTop - CONTENT_BOTTOM_PADDING;
|
|
const clockBlockH =
|
|
CLOCK_RADIUS * 2 + CLOCK_TO_BOX_GAP + INPUT_BOX_H;
|
|
const totalGridH = ROWS * clockBlockH + (ROWS - 1) * ROW_GAP;
|
|
const startY = contentTop + Math.max(12, (availableH - totalGridH) / 2);
|
|
const availableW = canvasWidth - MARGIN_X * 2;
|
|
const colW = availableW / COLS;
|
|
const rowH = clockBlockH + ROW_GAP;
|
|
|
|
for (let i = 0; i < problems.length; i++) {
|
|
const row = Math.floor(i / COLS);
|
|
const col = i % COLS;
|
|
if (row >= ROWS) break;
|
|
|
|
const problem = problems[i];
|
|
const cellCenterX = MARGIN_X + col * colW + colW / 2;
|
|
const cellTopY = startY + row * rowH;
|
|
const clockCy = cellTopY + CLOCK_RADIUS;
|
|
|
|
drawAnalogClock(ctx, {
|
|
cx: cellCenterX,
|
|
cy: clockCy,
|
|
radius: CLOCK_RADIUS,
|
|
hour: problem.hour,
|
|
minute: problem.minute,
|
|
});
|
|
|
|
const boxX = cellCenterX - INPUT_BOX_W / 2;
|
|
const boxY = cellTopY + CLOCK_RADIUS * 2 + CLOCK_TO_BOX_GAP;
|
|
drawTimeInputBox(ctx, boxX, boxY, INPUT_BOX_W, INPUT_BOX_H);
|
|
}
|
|
}
|
|
}
|