feat: 完成三类字母描红开发
This commit is contained in:
@@ -10,41 +10,58 @@ import {
|
||||
type LetterTracingMode,
|
||||
} from '../shared/generators/letter-tracing-generator';
|
||||
import { LETTERS_UPPER } from '../shared/data/alphabet';
|
||||
import {
|
||||
DEFAULT_LETTER_PROFILE,
|
||||
getFontProfile,
|
||||
type FontProfile,
|
||||
} from '../shared/data/fontProfiles';
|
||||
import { loadLetterFont } from '../shared/draw/drawTools';
|
||||
|
||||
/** 各 worksheetId 对应的页面标题和描述 */
|
||||
const PAGE_META: Record<string, { title: string; desc: string }> = {
|
||||
'letter-tracing-single': {
|
||||
title: '看图描红',
|
||||
desc: '配图、例句与六行描红',
|
||||
/** 练习模式定义(顺序与产品文档一致),同时用于模式选择器和页面元信息 */
|
||||
const MODES = [
|
||||
{
|
||||
id: 'letter-tracing-single',
|
||||
label: '看图识字',
|
||||
desc: '配图、例句与描红',
|
||||
},
|
||||
'letter-tracing-full': {
|
||||
title: '分栏对照',
|
||||
desc: '半组字母左大写右小写',
|
||||
},
|
||||
'letter-tracing-upper-lower': {
|
||||
title: '字母总览',
|
||||
{
|
||||
id: 'letter-tracing-upper-lower',
|
||||
label: '字母总览',
|
||||
desc: 'Uppercase / Lowercase 总览',
|
||||
},
|
||||
'letter-tracing-two-column': {
|
||||
title: '大小写配对',
|
||||
{
|
||||
id: 'letter-tracing-two-column',
|
||||
label: '大小写配对',
|
||||
desc: '左 A–M、右 N–Z 配对描红',
|
||||
},
|
||||
};
|
||||
{
|
||||
id: 'letter-tracing-full',
|
||||
label: '分栏对照',
|
||||
desc: '半组字母左大写右小写',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-triple',
|
||||
label: '三字母精练',
|
||||
desc: '每页聚焦 3 个字母深度书写',
|
||||
},
|
||||
{
|
||||
id: 'letter-tracing-single-line',
|
||||
label: '单字母逐行',
|
||||
desc: '每行一个字母,13 字母半表',
|
||||
},
|
||||
] as const;
|
||||
|
||||
const MODE_MAP = Object.fromEntries(MODES.map((m) => [m.id, m])) as Record<
|
||||
string,
|
||||
(typeof MODES)[number]
|
||||
>;
|
||||
|
||||
/** 根据 worksheetId 查找页面元信息 */
|
||||
function pageInfoLookup(id: string) {
|
||||
return PAGE_META[id];
|
||||
const m = MODE_MAP[id];
|
||||
return m ? { title: m.label, desc: m.desc } : undefined;
|
||||
}
|
||||
|
||||
/** 模式选择器的选项列表 */
|
||||
const MODE_OPTIONS = [
|
||||
{ id: 'letter-tracing-single', label: '看图描红' },
|
||||
{ id: 'letter-tracing-full', label: '分栏对照' },
|
||||
{ id: 'letter-tracing-upper-lower', label: '字母总览' },
|
||||
{ id: 'letter-tracing-two-column', label: '大小写配对' },
|
||||
] as const;
|
||||
|
||||
type PageData = CanvasDataState & {
|
||||
worksheetId: string;
|
||||
traceMode: LetterTracingMode;
|
||||
@@ -54,7 +71,7 @@ type PageData = CanvasDataState & {
|
||||
showCaseToggle: boolean;
|
||||
showNextLetter: boolean;
|
||||
letterGrid: string[];
|
||||
modeOptions: ReadonlyArray<{ id: string; label: string }>;
|
||||
modeOptions: ReadonlyArray<{ id: string; label: string; desc: string }>;
|
||||
};
|
||||
|
||||
createPage(
|
||||
@@ -64,6 +81,7 @@ createPage(
|
||||
boxHeight: 0,
|
||||
boxWidth: 0,
|
||||
drawService: null as LetterTracingDraw | null,
|
||||
fontProfile: DEFAULT_LETTER_PROFILE as FontProfile,
|
||||
|
||||
data: {
|
||||
pageTitle: '字母描红',
|
||||
@@ -78,18 +96,22 @@ createPage(
|
||||
showCaseToggle: false,
|
||||
showNextLetter: true,
|
||||
letterGrid: LETTERS_UPPER,
|
||||
modeOptions: [...MODE_OPTIONS],
|
||||
modeOptions: [...MODES],
|
||||
} as unknown as PageData,
|
||||
|
||||
/** 页面加载:从路由参数获取 worksheetId、letter、case 并应用,同时预加载字体 */
|
||||
/** 页面加载:从路由参数获取 worksheetId、letter、case、font 并应用,同时预加载字体 */
|
||||
onLoad(options: {
|
||||
id?: string;
|
||||
letter?: string;
|
||||
case?: 'upper' | 'lower';
|
||||
font?: string;
|
||||
}) {
|
||||
loadLetterFont().catch(() => {});
|
||||
if (options.font) {
|
||||
this.fontProfile = getFontProfile(options.font);
|
||||
}
|
||||
loadLetterFont(this.fontProfile).catch(() => {});
|
||||
const worksheetId =
|
||||
options.id && PAGE_META[options.id]
|
||||
options.id && MODE_MAP[options.id]
|
||||
? options.id
|
||||
: 'letter-tracing-single';
|
||||
this.applyWorksheet(worksheetId);
|
||||
@@ -149,10 +171,13 @@ createPage(
|
||||
: this.data.letterCaseLower
|
||||
? 'lower'
|
||||
: 'upper';
|
||||
const needsHalf =
|
||||
this.data.traceMode === 'column-compare' ||
|
||||
this.data.traceMode === 'single-line';
|
||||
return mergeLetterTracingConfig(base, {
|
||||
selectedLetter: this.data.selectedLetter,
|
||||
letterCase,
|
||||
...(this.data.traceMode === 'column-compare'
|
||||
...(needsHalf
|
||||
? {
|
||||
alphabetHalf: this.data.letterCaseLower
|
||||
? 'N-Z'
|
||||
@@ -166,7 +191,7 @@ createPage(
|
||||
async drawCanvas() {
|
||||
if (!this.ctx || !this.drawService) return;
|
||||
try {
|
||||
await loadLetterFont();
|
||||
await loadLetterFont(this.fontProfile);
|
||||
const config = this.buildRuntimeConfig();
|
||||
const data = generateLetterTracing(config);
|
||||
console.log('drawCanvas data', data);
|
||||
@@ -228,14 +253,16 @@ createPage(
|
||||
const merged = mergeLetterTracingConfig(base, {});
|
||||
|
||||
const traceMode = merged.mode;
|
||||
const showLetterPicker = traceMode === 'picture-tracing';
|
||||
const showCaseToggle = traceMode === 'column-compare';
|
||||
const showLetterPicker =
|
||||
traceMode === 'picture-tracing' || traceMode === 'triple-focus';
|
||||
const showCaseToggle =
|
||||
traceMode === 'column-compare' || traceMode === 'single-line';
|
||||
const showNextLetter = traceMode === 'picture-tracing';
|
||||
const selectedLetter = options?.preserveLetter
|
||||
? (this.data.selectedLetter ?? 'A')
|
||||
: normalizeLetter(merged.selectedLetter ?? '');
|
||||
const letterCaseLower =
|
||||
traceMode === 'column-compare'
|
||||
traceMode === 'column-compare' || traceMode === 'single-line'
|
||||
? merged.alphabetHalf === 'N-Z'
|
||||
: traceMode === 'picture-tracing'
|
||||
? merged.letterCase === 'lower'
|
||||
@@ -255,7 +282,7 @@ createPage(
|
||||
() => {
|
||||
this.initPageInfo(
|
||||
worksheetId,
|
||||
PAGE_META[worksheetId]?.title ?? '字母描红',
|
||||
MODE_MAP[worksheetId]?.label ?? '字母描红',
|
||||
);
|
||||
|
||||
if (this.drawService) {
|
||||
|
||||
@@ -1,20 +1,84 @@
|
||||
## 练习类型
|
||||
|
||||
1. 大小写配对 — 26 字母双栏,每组大写+小写并排
|
||||
2. 分栏对照 — 半组字母,左栏大写右栏小写
|
||||
3. 字母总览 — 上下分区展示全部大小写
|
||||
4. 看图描红 — 单字母教学配图 + 描红练习
|
||||
共 6 种练习模式,从单字母精练到全表总览逐步递进。
|
||||
|
||||
### 类型描述
|
||||
---
|
||||
|
||||
1. 一页展示 26 个字母,每个包含大小写,分左右两栏,左栏A-M,右栏N-Z,每栏的一行展示 4 组字母,每一组都是一个大写和小写字母的组合。同一行是相同的字母
|
||||
2. 一页展示 A-M 或N-Z的字母,分左右两栏,左栏每行展示 4 个大小字母,右栏展示 4 个对应的小写字母。同一行是相同的字母
|
||||
3. 一页分上下两块区域展示,上面展示大写字母,下面展示小写字母,上面是Uppercase Letters 标题加三行,前面两行展示 9 个字母,最后一行展示剩余的 8 个字母。下面区域title是 lowercase Letters,行的展示逻辑和上面一致
|
||||
4. 一页分为上下两部分,上部分有分左右两部分,左边展示超大字体的大小写字母,下面展示一段方面记忆的短句,例如:“L is for Lion”,上部分右边展示对应的Lion 的图片。下部分展示 6 行字母描红,前三行大写,后三行小写。
|
||||
### 1. 看图识字(picture-tracing)—— 单字母教学 + 配图 + 描红
|
||||
|
||||
> 每页聚焦一个字母,适合初学者逐字认读和书写。
|
||||
|
||||
页面分为上下两部分:
|
||||
|
||||
- **上部 · 教学区**:左侧展示超大字体的大小写字母及助记短句(如 "L is for Lion"),右侧展示对应单词的配图。中间包含"Highlight It"字母识别小游戏和"Trace It"笔顺演示区。
|
||||
- **下部 · 描红区**:4 行四线三格,每行重复书写该字母的大小写组合,透明度逐渐递减形成倒三角描红引导。
|
||||
|
||||
### 2. 字母总览(overview)—— 26 字母全表速览
|
||||
|
||||
> 一页纵览全部大小写字母,适合复习或张贴展示。
|
||||
|
||||
页面分上下两大区域:
|
||||
|
||||
- **上区 · Uppercase Letters**:4 行四线三格,按 7-7-6-6 排列全部大写字母。
|
||||
- **下区 · lowercase letters**:布局同上,展示对应的小写字母。
|
||||
|
||||
所有字母以浅红色描红字体呈现,可打印后用铅笔覆写练习。
|
||||
|
||||
### 3. 大小写配对(case-pairing)—— 左右分栏 · 大小写成对练习
|
||||
|
||||
> 以 Aa 为一组进行配对描红,强化大小写对应关系。
|
||||
|
||||
页面分左右两栏(左栏 A–M,右栏 N–Z),每行展示 4 组大小写配对字母。同一行的字母互相对应,每组内包含示范字母(实色)和渐淡描红格,引导从临摹到独立书写。
|
||||
|
||||
### 4. 分栏对照(column-compare)—— 半表字母 · 左大写右小写对照
|
||||
|
||||
> 半组字母(A–M 或 N–Z)逐行展开,左大写右小写一一对照。
|
||||
|
||||
四线三格横跨整页宽度,每行分为左右两半:左半栏写大写字母,右半栏写对应的小写字母。第一个字母为黑色示范,后续为浅红色描红。可切换 A–M / N–Z 两个半表。
|
||||
|
||||
### 5. 三字母精练(triple-focus)—— 每页 3 个字母 · 深度书写
|
||||
|
||||
> 每页聚焦 3 个字母,兼顾专注度和练习量,适合进阶阶段。
|
||||
|
||||
页面纵向分为 3 个等高区域,每个区域展示一个字母:
|
||||
|
||||
- 每区包含一行大写描红和一行小写描红(四线三格),每行重复书写该字母若干次,透明度逐渐递减。
|
||||
- 字母组可按 ABC/DEF/… 顺序自动分组,也可由用户自选 3 个字母。
|
||||
|
||||
### 6. 单字母逐行(single-line)—— 每行一个字母 · 13 字母半表
|
||||
|
||||
> 每页 13 个字母(A–M 或 N–Z),每个字母独占一行,专注逐字练习。
|
||||
|
||||
页面纵向排列 13 行四线三格,每行对应一个字母。行内先展示一个黑色示范字母,后接若干浅红色描红字母。可切换 A–M / N–Z 半表。布局紧凑,适合大量反复练习。
|
||||
|
||||
---
|
||||
|
||||
## 扩展思考:更多可补充的练习类型
|
||||
|
||||
以下为后续可扩展的练习模式,供产品迭代参考:
|
||||
|
||||
### 书写方向类
|
||||
|
||||
- **笔顺分步练习**:将每个字母的笔画拆解为 2–4 步,每步用不同颜色高亮当前笔画,配合箭头指示书写方向,逐步引导完成整个字母。
|
||||
- **起笔点标注**:在四线三格中标注每个字母的起笔位置(圆点)和运笔路径(虚线箭头),帮助建立正确的书写习惯。
|
||||
|
||||
### 认知强化类
|
||||
|
||||
- **大小写连线**:左列随机排列大写字母,右列随机排列对应的小写字母,练习者用线条将配对字母连起来。
|
||||
- **缺失字母填空**:展示部分字母表序列(如 A B _ D _ F),要求填入缺失字母,巩固字母顺序记忆。
|
||||
- **字母迷宫 / 字母涂色**:在迷宫或涂色图案中隐藏目标字母,通过寻找和涂色加深印象。
|
||||
|
||||
### 综合应用类
|
||||
|
||||
- **字母+单词抄写**:每行先展示一个字母及对应单词(如 A — Apple),后面是该单词的描红格,从字母过渡到单词书写。
|
||||
- **字母排序练习**:给出一组乱序字母,要求按字母表顺序重新抄写排列。
|
||||
- **听写预备格**:纯空白四线三格(无任何预设字母),配合家长/老师口述使用,适合听写测试场景。
|
||||
|
||||
---
|
||||
|
||||
## 生成要求
|
||||
|
||||
字母行统一使用 四线三格,颜色为偏黑色,其中最上边和最下边的线条为实线,中间的两个线条为虚线。
|
||||
字母行统一使用四线三格,颜色为偏黑色,其中最上边和最下边的线条为实线,中间的两个线条为虚线。
|
||||
|
||||
## 字母书写顺序资料
|
||||
|
||||
|
||||
Reference in New Issue
Block a user