122 lines
3.1 KiB
TypeScript
122 lines
3.1 KiB
TypeScript
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();
|
|
}
|
|
}
|