feat: 汉字每日打卡优化
This commit is contained in:
@@ -144,7 +144,7 @@ export default class WordDailyCheckinDraw extends BaseDrawService {
|
||||
sectionIndex: number,
|
||||
) {
|
||||
const phrase = getRandomEncouragementPhrase();
|
||||
drawSectionHeader(this.ctx, rect, '汉字每日打卡');
|
||||
drawSectionHeader(this.ctx, rect, '汉字每日打卡', { centerMeta: true });
|
||||
drawSectionFooter(this.ctx, rect, phrase, `- ${sectionIndex} -`);
|
||||
this.drawSectionContent(rect, items);
|
||||
}
|
||||
@@ -241,6 +241,7 @@ export default class WordDailyCheckinDraw extends BaseDrawService {
|
||||
ctx.lineTo(startX + cellW, y2);
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.strokeStyle = GRID_COLORS.border;
|
||||
ctx.setLineDash([]);
|
||||
const vx = startX + cellW;
|
||||
ctx.moveTo(vx, startY);
|
||||
@@ -248,37 +249,56 @@ export default class WordDailyCheckinDraw extends BaseDrawService {
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
|
||||
// 列分隔线
|
||||
// ctx.strokeStyle = GRID_COLORS.border;
|
||||
// ctx.setLineDash([]);
|
||||
// for (let c = 1; c < COLUMNS; c++) {
|
||||
// const vx = startX + c * cellW;
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(vx, startY);
|
||||
// ctx.lineTo(vx, yBot);
|
||||
// ctx.stroke();
|
||||
// }
|
||||
|
||||
// 第一格:绘制拼音
|
||||
if (item.pinyin) {
|
||||
const cx = startX + cellW / 2;
|
||||
const fontSize = Math.round(rowH * 0.65);
|
||||
const baseFontSize = Math.round(rowH * 0.65);
|
||||
ctx.save();
|
||||
ctx.font = `${fontSize}px ${fontFamilyOf(TONEOZ_PINYIN)}`;
|
||||
ctx.fillStyle = TRACING_COLORS.strong;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'alphabetic';
|
||||
|
||||
// 拼音超过 4 个字母时按需缩字,避免超出单元格宽度
|
||||
let fontSize = baseFontSize;
|
||||
if (item.pinyin.length > 4) {
|
||||
ctx.font = `${baseFontSize}px ${fontFamilyOf(TONEOZ_PINYIN)}`;
|
||||
const maxWidth = cellW * 0.9;
|
||||
const measured = (ctx as any).measureText(item.pinyin).width;
|
||||
if (measured > maxWidth) {
|
||||
fontSize = Math.max(
|
||||
8,
|
||||
Math.floor(baseFontSize * (maxWidth / measured)),
|
||||
);
|
||||
}
|
||||
}
|
||||
ctx.font = `${fontSize}px ${fontFamilyOf(TONEOZ_PINYIN)}`;
|
||||
ctx.fillText(item.pinyin, cx, y2);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// 笔画格:第 2 格起,按笔画顺序展示当前进度
|
||||
// 每一格绘制整个字:已绘制的笔画为黑色,当前笔画为红色,未绘制的为浅灰色
|
||||
const strokeCount = item.strokes.length;
|
||||
for (let k = 1; k <= strokeCount && k < COLUMNS; k++) {
|
||||
const cellX = startX + cellW / 2 + k * 15;
|
||||
const cellX = startX + cellW / 2 + k * 20;
|
||||
const currentIdx = k - 1;
|
||||
const lastIdx = strokeCount - 1;
|
||||
|
||||
// 已绘制的历史笔画:浅灰
|
||||
// 未绘制的笔画(当前之后):浅灰
|
||||
if (currentIdx < lastIdx) {
|
||||
drawStrokesRange({
|
||||
ctx,
|
||||
strokes: item.strokes,
|
||||
offsetX: cellX,
|
||||
offsetY: startY,
|
||||
width: cellW,
|
||||
height: rowH,
|
||||
fromIndex: currentIdx + 1,
|
||||
toIndex: lastIdx,
|
||||
fillStyle: TRACING_COLORS.guide,
|
||||
});
|
||||
}
|
||||
// 已绘制的历史笔画:黑色
|
||||
if (currentIdx > 0) {
|
||||
drawStrokesRange({
|
||||
ctx,
|
||||
@@ -289,7 +309,7 @@ export default class WordDailyCheckinDraw extends BaseDrawService {
|
||||
height: rowH,
|
||||
fromIndex: 0,
|
||||
toIndex: currentIdx - 1,
|
||||
fillStyle: TRACING_COLORS.guide,
|
||||
fillStyle: TRACING_COLORS.strong,
|
||||
});
|
||||
}
|
||||
// 当前笔画:红色高亮
|
||||
@@ -302,7 +322,7 @@ export default class WordDailyCheckinDraw extends BaseDrawService {
|
||||
height: rowH,
|
||||
fromIndex: currentIdx,
|
||||
toIndex: currentIdx,
|
||||
fillStyle: '#D94B4B',
|
||||
fillStyle: TRACING_COLORS.active,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user