feat: 完成三类字母描红开发
This commit is contained in:
@@ -3,28 +3,32 @@ import type {
|
||||
LetterTracingData,
|
||||
TracingRow,
|
||||
} from '../generators/letter-tracing-generator';
|
||||
import { fontFamilyOf } from '../data/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
drawLetterInFourLineGrid,
|
||||
FOUR_LINE_GRID_H,
|
||||
TOY_FONT_LETTER,
|
||||
type LetterFontSizes,
|
||||
} from './drawTools';
|
||||
|
||||
const LETTER_FACE = `${TOY_FONT_LETTER}, Roboto, sans-serif`;
|
||||
const COLOR_BLACK = '#1a1a1a';
|
||||
const COLOR_LIGHT_RED = 'rgba(252, 46, 0, 0.3)';
|
||||
|
||||
type ColumnCompareData = Extract<
|
||||
LetterTracingData,
|
||||
{ mode: 'column-compare' }
|
||||
>;
|
||||
/** 左右大写/小写两栏之间的间距(相对行宽 + 下限,避免过窄屏过小) */
|
||||
const COLUMN_GUTTER_RATIO = 0.02;
|
||||
const COLUMN_GUTTER_MIN = 14;
|
||||
|
||||
/**
|
||||
* 单栏内字母排版区域占栏宽比例(<1 则同栏字母更紧凑、字间距更小)
|
||||
*/
|
||||
const INTRA_COLUMN_LETTER_BAND_RATIO = 1;
|
||||
|
||||
type ColumnCompareData = Extract<LetterTracingData, { mode: 'column-compare' }>;
|
||||
|
||||
/**
|
||||
* 分栏对照绘制:
|
||||
* 四线三格横跨整页宽度,字母分左右两侧书写——
|
||||
* 左半写大写(repetitions 个),右半写小写(repetitions 个),
|
||||
* 左栏大写、右栏小写(各 repetitions 个),中间留间距;同栏内字母略收紧。
|
||||
* 每侧第一个字母黑色,后续浅红色。
|
||||
*/
|
||||
export default class ColumnCompareDraw extends BaseDrawService {
|
||||
@@ -52,7 +56,14 @@ export default class ColumnCompareDraw extends BaseDrawService {
|
||||
);
|
||||
|
||||
const y0 = this.currentY + rowGap;
|
||||
const halfW = lineW / 2;
|
||||
|
||||
const columnGutter = Math.max(
|
||||
COLUMN_GUTTER_MIN,
|
||||
Math.round(lineW * COLUMN_GUTTER_RATIO),
|
||||
);
|
||||
const halfContentW = (lineW - columnGutter) / 2;
|
||||
const leftX = M;
|
||||
const rightX = M + halfContentW + columnGutter;
|
||||
|
||||
for (let i = 0; i < maxR; i++) {
|
||||
const y = y0 + i * (FOUR_LINE_GRID_H + rowGap);
|
||||
@@ -60,10 +71,22 @@ export default class ColumnCompareDraw extends BaseDrawService {
|
||||
drawFourLineGrid(this.ctx, M, y, lineW, FOUR_LINE_GRID_H);
|
||||
|
||||
if (i < leftRows.length) {
|
||||
this.drawLettersInHalf(leftRows[i], M, y, halfW);
|
||||
this.drawLettersInHalf(
|
||||
leftRows[i],
|
||||
leftX,
|
||||
y,
|
||||
halfContentW,
|
||||
INTRA_COLUMN_LETTER_BAND_RATIO,
|
||||
);
|
||||
}
|
||||
if (i < rightRows.length) {
|
||||
this.drawLettersInHalf(rightRows[i], M + halfW, y, halfW);
|
||||
this.drawLettersInHalf(
|
||||
rightRows[i],
|
||||
rightX,
|
||||
y,
|
||||
halfContentW,
|
||||
INTRA_COLUMN_LETTER_BAND_RATIO,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,16 +99,19 @@ export default class ColumnCompareDraw extends BaseDrawService {
|
||||
row: TracingRow,
|
||||
x: number,
|
||||
y: number,
|
||||
halfW: number,
|
||||
columnW: number,
|
||||
letterBandRatio: number,
|
||||
) {
|
||||
const n = row.cells.length;
|
||||
if (n === 0) return;
|
||||
|
||||
const slotW = halfW / n;
|
||||
const bandW = columnW * letterBandRatio;
|
||||
const inset = (columnW - bandW) / 2;
|
||||
const slotW = bandW / n;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const cell = row.cells[i];
|
||||
const color = i === 0 ? COLOR_BLACK : COLOR_LIGHT_RED;
|
||||
const cx = x + slotW * i + slotW / 2;
|
||||
const cx = x + inset + slotW * i + slotW / 2;
|
||||
|
||||
drawLetterInFourLineGrid(
|
||||
this.ctx,
|
||||
@@ -94,7 +120,7 @@ export default class ColumnCompareDraw extends BaseDrawService {
|
||||
y,
|
||||
FOUR_LINE_GRID_H,
|
||||
this.letterSizes,
|
||||
{ fontFamily: LETTER_FACE, color },
|
||||
{ fontFamily: fontFamilyOf(this.letterSizes._profile), color },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user