feat: 样式修改、13 字母半表、三字母精练开发

This commit is contained in:
R524809
2026-04-20 16:23:47 +08:00
parent 9febf7da4f
commit 21b515746b
12 changed files with 916 additions and 163 deletions
@@ -10,7 +10,7 @@ export type LetterTracingMode =
| 'letter-tracing-case-pairing'
/** 4 分栏对照:半组字母,左栏大写、右栏小写,每行 4 个 */
| 'letter-tracing-two-column'
/** 5 三字母精练:每页聚焦 3 个字母,各含大写行 + 小写行 */
/** 5 三字母精练:每页聚焦 3 个字母,每字母 4 行(2 行示范 + 2 行简练) */
| 'letter-tracing-triple'
/** 6 单字母逐行:每行一个字母,13 字母半表(A–M 或 N–Z) */
| 'letter-tracing-single-line';
@@ -31,7 +31,7 @@ export interface LetterTracingGeneratorConfig {
/** 分栏对照 / 单字母逐行:练习 A–M 或 N–Z */
alphabetHalf?: AlphabetHalf;
/** 三字母精练:当前页聚焦的 3 个字母(如 ['A','B','C'] */
tripleLetters?: [string, string, string];
tripleLetters?: string[];
}
/** 单个描红格子的数据 */
@@ -49,6 +49,28 @@ export interface TracingRow {
cells: TracingCell[];
}
/** 单字母逐行:一行中一个大小写配对的展示格子 */
export interface SingleLineCell {
upper: string;
lower: string;
/** 'solid' 正常渲染 | 'dashed' 使用虚线字体 */
style: 'solid' | 'dashed';
color: string;
alpha: number;
}
/** 单字母逐行:一行数据(6 个位置,前 4 个有字母,后 2 个空) */
export interface SingleLineRow {
letter: string;
cells: (SingleLineCell | null)[];
}
/** 三字母精练:一个字母区域(4 行),前两行完整示范,后两行简练(黑+浅红) */
export interface TripleSection {
letter: string;
rows: SingleLineRow[];
}
/** Highlight It 格子数据(3×6 网格,混入目标字母) */
export interface HighlightGrid {
rows: string[][];
@@ -88,6 +110,14 @@ export type LetterTracingData =
leftRows: TracingRow[];
rightRows: TracingRow[];
}
| {
mode: 'letter-tracing-single-line';
rows: SingleLineRow[];
}
| {
mode: 'letter-tracing-triple';
sections: TripleSection[];
}
| {
mode: 'letter-tracing-upper-lower';
upperRows: string[][];
@@ -200,6 +230,35 @@ function overviewRowsFrom(letters: string[]): string[][] {
];
}
const _COLOR_BLACK = '#1a1a1a';
const _COLOR_LIGHT_RED = '#FF8E8E';
/** 构建 6 slot 的单行字母数据:前 4 格有字母(颜色递进),后 2 格空白 */
function buildSingleLineCells(L: string): (SingleLineCell | null)[] {
const lower = L.toLowerCase();
return [
{ upper: L, lower, style: 'solid', color: _COLOR_BLACK, alpha: 1 },
{ upper: L, lower, style: 'solid', color: _COLOR_LIGHT_RED, alpha: 1 },
{ upper: L, lower, style: 'solid', color: _COLOR_LIGHT_RED, alpha: 0.5 },
{ upper: L, lower, style: 'dashed', color: _COLOR_LIGHT_RED, alpha: 0.5 },
null,
null,
];
}
/** 构建 6 slot 的简练行数据:前 2 格有字母(黑色+浅红色),后 4 格空白 */
function buildSimpleCells(L: string): (SingleLineCell | null)[] {
const lower = L.toLowerCase();
return [
{ upper: L, lower, style: 'solid', color: _COLOR_BLACK, alpha: 1 },
{ upper: L, lower, style: 'solid', color: _COLOR_LIGHT_RED, alpha: 1 },
null,
null,
null,
null,
];
}
/**
* 根据配置生成字母描红数据
* - picture-tracing:教学区 + 6 行描红
@@ -273,6 +332,39 @@ export function generateLetterTracing(
};
}
if (mode === 'letter-tracing-triple') {
const letters = config.tripleLetters ?? ['A', 'B', 'C'];
const sections: TripleSection[] = letters.map((L) => {
const filledRow: SingleLineRow = {
letter: L,
cells: buildSingleLineCells(L),
};
const simpleRow: SingleLineRow = {
letter: L,
cells: buildSimpleCells(L),
};
return {
letter: L,
rows: [filledRow, filledRow, simpleRow, simpleRow],
};
});
return { mode: 'letter-tracing-triple', sections };
}
if (mode === 'letter-tracing-single-line') {
const half =
config.alphabetHalf === 'N-Z'
? LETTERS_UPPER.slice(13)
: LETTERS_UPPER.slice(0, 13);
const rows: SingleLineRow[] = half.map((L) => ({
letter: L,
cells: buildSingleLineCells(L),
}));
return { mode: 'letter-tracing-single-line', rows };
}
// letter-tracing-upper-lower
return {
mode: 'letter-tracing-upper-lower',