feat: 开发完成拼音每日一练
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { BaseDrawService } from '../../core/draw/baseDraw';
|
||||
import {
|
||||
GRID_COLORS,
|
||||
GRID_DASH,
|
||||
TRACING_COLORS,
|
||||
} from '../../core/data/tracingStyles';
|
||||
import { TONEOZ_PINYIN, fontFamilyOf } from '../../core/font/fontProfiles';
|
||||
import { PINYIN_STYLE } from './pinyinConstants';
|
||||
|
||||
export abstract class PinyinBaseDraw extends BaseDrawService {
|
||||
/**
|
||||
* 绘制一行四线三格
|
||||
*/
|
||||
protected drawFourLineRow(
|
||||
x: number,
|
||||
y: number,
|
||||
cols: number,
|
||||
cellW: number,
|
||||
cellH: number,
|
||||
) {
|
||||
const ctx = this.ctx;
|
||||
const totalW = cols * cellW;
|
||||
const yTop = y;
|
||||
const y1 = y + cellH / 3;
|
||||
const y2 = y + (cellH * 2) / 3;
|
||||
const yBot = y + cellH;
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
|
||||
// 外边框(上下)
|
||||
ctx.strokeStyle = GRID_COLORS.border;
|
||||
ctx.setLineDash([]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, yTop);
|
||||
ctx.lineTo(x + totalW, yTop);
|
||||
ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, yBot);
|
||||
ctx.lineTo(x + totalW, yBot);
|
||||
ctx.stroke();
|
||||
|
||||
// 中间虚线
|
||||
ctx.strokeStyle = GRID_COLORS.middleLine;
|
||||
ctx.setLineDash([...GRID_DASH]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y1);
|
||||
ctx.lineTo(x + totalW, y1);
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y2);
|
||||
ctx.lineTo(x + totalW, y2);
|
||||
ctx.stroke();
|
||||
|
||||
// 垂直分割线
|
||||
ctx.strokeStyle = GRID_COLORS.border;
|
||||
ctx.setLineDash([]);
|
||||
for (let i = 0; i <= cols; i++) {
|
||||
const vx = x + i * cellW;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vx, yTop);
|
||||
ctx.lineTo(vx, yBot);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制单个封闭四线三格(用于逐格绘制场景,如每日打卡)
|
||||
*/
|
||||
protected drawFourLineGrid(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
) {
|
||||
const ctx = this.ctx;
|
||||
const y1 = y + h / 3;
|
||||
const y2 = y + (h * 2) / 3;
|
||||
|
||||
ctx.save();
|
||||
|
||||
ctx.strokeStyle = GRID_COLORS.border;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.setLineDash([]);
|
||||
ctx.strokeRect(x, y, w, h);
|
||||
|
||||
ctx.strokeStyle = GRID_COLORS.middleLine;
|
||||
ctx.setLineDash([...GRID_DASH]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y1);
|
||||
ctx.lineTo(x + w, y1);
|
||||
ctx.moveTo(x, y2);
|
||||
ctx.lineTo(x + w, y2);
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在四线三格中绘制拼音文本
|
||||
*/
|
||||
protected drawPinyinText(
|
||||
pinyin: string,
|
||||
cx: number,
|
||||
gridY: number,
|
||||
gridH: number,
|
||||
fontSizeRatio: number = PINYIN_STYLE.PINYIN_FONT_SIZE_RATIO,
|
||||
) {
|
||||
const ctx = this.ctx;
|
||||
const fontSize = Math.round(gridH * fontSizeRatio);
|
||||
const baselineY = gridY + (gridH * 2) / 3;
|
||||
|
||||
ctx.save();
|
||||
ctx.font = `${fontSize}px ${fontFamilyOf(TONEOZ_PINYIN)}`;
|
||||
ctx.fillStyle = TRACING_COLORS.guide;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'alphabetic';
|
||||
ctx.fillText(pinyin, cx, baselineY);
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user