feat: 开发完成拼音每日一练
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
// 每个分区内容区顶部内边距(px)
|
||||
export const SECTION_PADDING_TOP = 12;
|
||||
// 每个分区内容区底部内边距(px)
|
||||
export const SECTION_PADDING_BOTTOM = 10;
|
||||
|
||||
// 标题与上一元素的垂直间距(px)
|
||||
export const HEADER_TITLE_GAP = 32;
|
||||
// 标题与元信息(如日期、学号等)的间距(px)
|
||||
export const HEADER_META_GAP = 22;
|
||||
// 正文内容距标题/元信息顶部的间距(px)
|
||||
export const CONTENT_TOP_GAP = 14;
|
||||
|
||||
// 页脚短语与内容之间的间距(px)
|
||||
export const FOOTER_PHRASE_GAP = 26;
|
||||
// 页脚索引与短语之间的间距(px)
|
||||
export const FOOTER_INDEX_GAP = 22;
|
||||
|
||||
// 20 条鼓励语词库
|
||||
export const ENCOURAGEMENT_PHRASES: ReadonlyArray<string> = [
|
||||
'书山有路勤为径',
|
||||
'日拱一卒 不期而至',
|
||||
'宝剑锋从磨砺出',
|
||||
'梅花香自苦寒来',
|
||||
'业精于勤荒于嬉',
|
||||
'行百里者半九十',
|
||||
'锲而不舍金石可镂',
|
||||
'读万卷书行万里路',
|
||||
'滴水穿石非一日之功',
|
||||
'天下无难事只怕有心人',
|
||||
'熟能生巧功到自然成',
|
||||
'敏而好学不耻下问',
|
||||
'学而不思则罔',
|
||||
'思而不学则殆',
|
||||
'欲速则不达',
|
||||
'不积跬步无以至千里',
|
||||
'不积小流无以成江海',
|
||||
'温故而知新',
|
||||
'读书破万卷下笔如有神',
|
||||
'千里之行始于足下',
|
||||
];
|
||||
|
||||
/**
|
||||
* 随机获取一条鼓励语
|
||||
*/
|
||||
export function getRandomEncouragementPhrase(): string {
|
||||
const idx = Math.floor(Math.random() * ENCOURAGEMENT_PHRASES.length);
|
||||
return ENCOURAGEMENT_PHRASES[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制统一的每日练习每个 Section 中的 Header
|
||||
* @param ctx 微信小程序 Canvas 绘制上下文
|
||||
* @param rect 目标 Section 的位置与宽高信息
|
||||
* @param title 标题文本,如 “每日打卡” 或 “拼音每日一练”
|
||||
*/
|
||||
export function drawSectionHeader(
|
||||
ctx: RenderingContext,
|
||||
rect: { x: number; y: number; w: number; h: number },
|
||||
title: string,
|
||||
): void {
|
||||
const cx = rect.x + rect.w / 2;
|
||||
const titleY = rect.y + SECTION_PADDING_TOP + 12;
|
||||
const metaY = titleY + HEADER_TITLE_GAP;
|
||||
const metaUnderlineY = metaY + 5;
|
||||
|
||||
const canvasCtx = ctx as any;
|
||||
|
||||
canvasCtx.save();
|
||||
canvasCtx.fillStyle = '#322E25';
|
||||
canvasCtx.textAlign = 'center';
|
||||
canvasCtx.textBaseline = 'middle';
|
||||
|
||||
// 字体样式与 dailyCheckinDraw.ts 保持一致
|
||||
canvasCtx.font = '20px serif';
|
||||
canvasCtx.fillText(title, cx, titleY);
|
||||
|
||||
canvasCtx.font = '12px serif';
|
||||
canvasCtx.fillText('月', rect.x + 76, metaY);
|
||||
canvasCtx.fillText('日', rect.x + 122, metaY);
|
||||
canvasCtx.fillText('姓名:', rect.x + 176, metaY);
|
||||
|
||||
canvasCtx.strokeStyle = '#8E897E';
|
||||
canvasCtx.lineWidth = 1;
|
||||
canvasCtx.setLineDash([]);
|
||||
canvasCtx.beginPath();
|
||||
canvasCtx.moveTo(rect.x + 40, metaUnderlineY);
|
||||
canvasCtx.lineTo(rect.x + 68, metaUnderlineY);
|
||||
canvasCtx.moveTo(rect.x + 85, metaUnderlineY);
|
||||
canvasCtx.lineTo(rect.x + 113, metaUnderlineY);
|
||||
canvasCtx.moveTo(rect.x + 195, metaUnderlineY);
|
||||
canvasCtx.lineTo(rect.x + 248, metaUnderlineY);
|
||||
canvasCtx.stroke();
|
||||
|
||||
canvasCtx.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制统一的每日练习每个 Section 中的 Footer
|
||||
* @param ctx 微信小程序 Canvas 绘制上下文
|
||||
* @param rect 目标 Section 的位置与宽高信息
|
||||
* @param phrase 鼓励语文本
|
||||
* @param labelText 页面/天数索引文本,如 “- 1 -” 或 “第 1 天”
|
||||
*/
|
||||
export function drawSectionFooter(
|
||||
ctx: RenderingContext,
|
||||
rect: { x: number; y: number; w: number; h: number },
|
||||
phrase: string,
|
||||
labelText: string,
|
||||
): void {
|
||||
const cx = rect.x + rect.w / 2;
|
||||
const phraseY =
|
||||
rect.y + rect.h - SECTION_PADDING_BOTTOM - FOOTER_PHRASE_GAP;
|
||||
const indexY = rect.y + rect.h - SECTION_PADDING_BOTTOM - 6;
|
||||
|
||||
const canvasCtx = ctx as any;
|
||||
|
||||
canvasCtx.save();
|
||||
canvasCtx.fillStyle = '#3E3A33';
|
||||
canvasCtx.textAlign = 'center';
|
||||
canvasCtx.textBaseline = 'middle';
|
||||
|
||||
// 字体样式与 dailyCheckinDraw.ts 保持一致
|
||||
canvasCtx.font = '14px serif';
|
||||
canvasCtx.fillText(phrase, cx, phraseY);
|
||||
|
||||
canvasCtx.font = '12px serif';
|
||||
canvasCtx.fillText(labelText, cx, indexY);
|
||||
|
||||
canvasCtx.restore();
|
||||
}
|
||||
Reference in New Issue
Block a user