Files
doodle-mini/miniprogram/pinyinPages/shared/pinyinBaseDraw.ts
T
2026-05-20 15:33:06 +08:00

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();
}
}