import { BaseDrawService } from '../../../core/draw/baseDraw'; import type { LetterTracingData } from '../generators/letter-tracing-generator'; import { drawFourLineGrid } from './drawTools'; const LETTER_FACE = 'Helvetica, Arial, "Segoe UI", Roboto, sans-serif'; type OverviewData = Extract; export default class OverviewDraw extends BaseDrawService { async draw(data: OverviewData) { this.prepareDraw(); await this.drawHeaderAndDivider(); this.drawContent(data.upperRows, data.lowerRows); this.drawPrintFooter(); } private drawContent(upperRows: string[][], lowerRows: string[][]) { const ctx = this.ctx; const M = 24; let y = this.currentY + 6; const innerW = this.canvasWidth - M * 2; const drawTitle = (t: string) => { ctx.fillStyle = '#111'; ctx.font = 'bold 17px sans-serif'; ctx.textAlign = 'left'; ctx.textBaseline = 'top'; ctx.fillText(t, M, y); y += 24; }; const drawBand = (rows: string[][]) => { for (const line of rows) { const n = line.length; const gap = 4; const cellW = (innerW - (n - 1) * gap) / n; const cellH = 30; for (let i = 0; i < n; i++) { const cx = M + i * (cellW + gap); drawFourLineGrid(ctx, cx, y, cellW, cellH); this.drawCharInCell( line[i], cx, y, cellW, cellH, 0.9, true, ); } y += cellH + 8; } }; drawTitle('Uppercase Letters'); drawBand(upperRows); y += 6; this.drawDashedDivider(y, M, '#bbb'); y += 12; drawTitle('lowercase Letters'); drawBand(lowerRows); } private drawCharInCell( ch: string, x: number, y: number, w: number, h: number, opacity: number, bold: boolean, ) { const ctx = this.ctx; if (opacity <= 0) return; ctx.save(); ctx.globalAlpha = opacity; ctx.fillStyle = bold ? '#1a1a1a' : '#4a4a4a'; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic'; const baselineY = y + h * 0.72; const fontSize = Math.min(h * 0.72, w * 0.85); ctx.font = `${bold ? 'bold ' : ''}${fontSize}px ${LETTER_FACE}`; ctx.fillText(ch, x + w / 2, baselineY); ctx.restore(); } }