feat: 拼音字母选择
This commit is contained in:
@@ -3,7 +3,7 @@ import type {
|
||||
LetterTracingData,
|
||||
TracingRow,
|
||||
} from '../generators/letter-tracing-generator';
|
||||
import { fontFamilyOf } from '../../shared/data/fontProfiles';
|
||||
import { fontFamilyOf } from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
@@ -11,8 +11,10 @@ import {
|
||||
FOUR_LINE_GRID_H,
|
||||
type LetterFontSizes,
|
||||
} from '../../shared/draw/drawTools';
|
||||
const COLOR_BLACK = '#1a1a1a';
|
||||
const COLOR_LIGHT_RED = '#FF8E8E';
|
||||
import { TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
|
||||
const COLOR_BLACK = TRACING_COLORS.strong;
|
||||
const COLOR_LIGHT_RED = TRACING_COLORS.guide;
|
||||
|
||||
/** 左右大写/小写两栏之间的间距(相对行宽 + 下限,避免过窄屏过小) */
|
||||
const COLUMN_GUTTER_RATIO = 0.02;
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
PRINT_CLEARLY_DASHED,
|
||||
PRINT_CLEARLY_REGULAR,
|
||||
fontFamilyOf,
|
||||
} from '../../shared/data/fontProfiles';
|
||||
} from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawClosedFourLineGrid,
|
||||
@@ -53,15 +53,13 @@ const GRID_COL_GAP = 6;
|
||||
// 格子行间距(px)
|
||||
const GRID_ROW_GAP = 8;
|
||||
|
||||
// 网格描边主色
|
||||
const GRID_BORDER = '#9AA9A2';
|
||||
// 网格中间线虚线颜色
|
||||
const GRID_MIDDLE = 'rgba(154, 169, 162, 0.65)';
|
||||
import { GRID_COLORS, TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
|
||||
// 黑色文本主色
|
||||
const COLOR_BLACK = '#1a1a1a';
|
||||
// 数据红色(例:未签到状态)
|
||||
const COLOR_LIGHT_RED = '#FF8E8E';
|
||||
const GRID_BORDER = GRID_COLORS.border;
|
||||
const GRID_MIDDLE = GRID_COLORS.middleLine;
|
||||
|
||||
const COLOR_BLACK = TRACING_COLORS.strong;
|
||||
const COLOR_LIGHT_RED = TRACING_COLORS.guide;
|
||||
|
||||
export default class DailyCheckinDraw extends BaseDrawService {
|
||||
async draw(data: DailyCheckinData) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
import {
|
||||
fontFamilyOf,
|
||||
PRINT_CLEARLY_DASHED,
|
||||
} from '../../shared/data/fontProfiles';
|
||||
} from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
fontFamilyOf,
|
||||
PRINT_CLEARLY_BOLD,
|
||||
PRINT_CLEARLY_DASHED,
|
||||
} from '../../shared/data/fontProfiles';
|
||||
} from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
@@ -18,8 +18,9 @@ import {
|
||||
loadLetterFont,
|
||||
type LetterFontSizes,
|
||||
} from '../../shared/draw/drawTools';
|
||||
import { GRID_COLORS, TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
|
||||
const LINE_INK_ALPHA = 'rgba(50, 46, 37, 1)';
|
||||
const LINE_INK_ALPHA = GRID_COLORS.border;
|
||||
const ACCENT_RED = 'rgba(252, 46, 0, 1)';
|
||||
const TITLE_TEXT_FONT = '14px sans-serif';
|
||||
const TITLE_ICON_GAP = 4;
|
||||
@@ -167,10 +168,10 @@ export default class SingleLetterDraw extends BaseDrawService {
|
||||
const groupsPerLine = [8, 6, 3, 1];
|
||||
const slotW = lineW / groupsPerLine[0]; // 以第一行的 8 组为基准
|
||||
const lineStyles = [
|
||||
{ color: 'rgba(26, 26, 26, 1)', alpha: 1, dashed: false },
|
||||
{ color: '#FF8E8E', alpha: 1, dashed: false },
|
||||
{ color: '#FF8E8E', alpha: 0.5, dashed: false },
|
||||
{ color: '#FF8E8E', alpha: 0.5, dashed: true },
|
||||
{ color: TRACING_COLORS.strong, alpha: 1, dashed: false },
|
||||
{ color: TRACING_COLORS.guide, alpha: 1, dashed: false },
|
||||
{ color: TRACING_COLORS.guide, alpha: 0.5, dashed: false },
|
||||
{ color: TRACING_COLORS.guide, alpha: 0.5, dashed: true },
|
||||
] as const;
|
||||
|
||||
for (let r = 0; r < lineTops.length; r++) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {
|
||||
import {
|
||||
fontFamilyOf,
|
||||
PRINT_CLEARLY_DASHED,
|
||||
} from '../../shared/data/fontProfiles';
|
||||
} from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
|
||||
@@ -3,7 +3,7 @@ import type {
|
||||
LetterTracingData,
|
||||
TracingRow,
|
||||
} from '../generators/letter-tracing-generator';
|
||||
import { fontFamilyOf } from '../../shared/data/fontProfiles';
|
||||
import { fontFamilyOf } from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
@@ -12,8 +12,10 @@ import {
|
||||
type LetterFontSizes,
|
||||
} from '../../shared/draw/drawTools';
|
||||
|
||||
const COLOR_BLACK = '#1a1a1a';
|
||||
const COLOR_LIGHT_RED = '#FF8E8E';
|
||||
import { TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
|
||||
const COLOR_BLACK = TRACING_COLORS.strong;
|
||||
const COLOR_LIGHT_RED = TRACING_COLORS.guide;
|
||||
const COLUMN_GUTTER = 18;
|
||||
|
||||
type TwoColumnData = Extract<
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
PRINT_CLEARLY_BOLD,
|
||||
PRINT_CLEARLY_DASHED,
|
||||
fontFamilyOf,
|
||||
} from '../../shared/data/fontProfiles';
|
||||
} from '../../../core/font/fontProfiles';
|
||||
import {
|
||||
calcLetterFontSizes,
|
||||
drawFourLineGrid,
|
||||
@@ -13,26 +13,21 @@ import {
|
||||
loadLetterFont,
|
||||
type LetterFontSizes,
|
||||
} from '../../shared/draw/drawTools';
|
||||
import { TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
|
||||
type UpperLowerData = Extract<
|
||||
LetterTracingData,
|
||||
{ mode: 'letter-tracing-upper-lower' }
|
||||
>;
|
||||
|
||||
/** 页面左右边距(margin,px),用于排版时留白 */
|
||||
const M = 24;
|
||||
/** 上下两大区(Uppercase / lowercase)之间的间距 */
|
||||
const SECTION_GAP = 25;
|
||||
/** 标题字号 */
|
||||
const TITLE_SIZE = 28;
|
||||
/** 标题与第一行四线三格的间距 */
|
||||
const TITLE_GAP = 25;
|
||||
/** 同一区域内相邻四线三格行之间的间距 */
|
||||
const ROW_GAP = 24;
|
||||
const TITLE_COLOR = '#000';
|
||||
|
||||
/** 浅红色描红(不透明 hex,避免打印时半透明发灰) */
|
||||
const TRACE_LIGHT_RED = '#FF8E8E';
|
||||
const TRACE_LIGHT_RED = TRACING_COLORS.guide;
|
||||
|
||||
const DASHED_PROFILE = PRINT_CLEARLY_DASHED;
|
||||
const TITLE_PROFILE = PRINT_CLEARLY_BOLD;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ALPHABET_BY_LETTER, LETTERS_UPPER } from '../../shared/data/alphabet';
|
||||
import { TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
|
||||
/** 字母描红的布局模式(与产品文档六类练习一致) */
|
||||
export type LetterTracingMode =
|
||||
@@ -227,8 +228,8 @@ function overviewRowsFrom(letters: string[]): string[][] {
|
||||
];
|
||||
}
|
||||
|
||||
const _COLOR_BLACK = '#1a1a1a';
|
||||
const _COLOR_LIGHT_RED = '#FF8E8E';
|
||||
const _COLOR_BLACK = TRACING_COLORS.strong;
|
||||
const _COLOR_LIGHT_RED = TRACING_COLORS.guide;
|
||||
|
||||
/** 构建 6 slot 的单行字母数据:前 4 格有字母(颜色递进),后 2 格空白 */
|
||||
function buildSingleLineCells(L: string): (SingleLineCell | null)[] {
|
||||
|
||||
@@ -19,10 +19,14 @@ import {
|
||||
DEFAULT_LETTER_PROFILE,
|
||||
getFontProfile,
|
||||
type FontProfile,
|
||||
} from '../shared/data/fontProfiles';
|
||||
} from '../../core/font/fontProfiles';
|
||||
import { loadLetterFont } from '../shared/draw/drawTools';
|
||||
import type { DebugPublishMeta } from '../../utils/debugPublish';
|
||||
import { addFavorite, removeFavorite, batchCheckFavorited } from '../../utils/favorites';
|
||||
import {
|
||||
addFavorite,
|
||||
removeFavorite,
|
||||
batchCheckFavorited,
|
||||
} from '../../utils/favorites';
|
||||
|
||||
/** 三字母精练分组:26 字母每 3 个一组 */
|
||||
const TRIPLE_GROUPS: { title: string; letters: string[] }[] = [];
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
/**
|
||||
* 字体渲染配置(Font Profile)
|
||||
*
|
||||
* 不同手写字体的字形设计差异很大,同一 fontSize 下各字母的视觉高度、
|
||||
* 基线位置各不相同。为每种字体维护一份 profile,按字母分类配置
|
||||
* 缩放因子和 Y 轴偏移,保证字母在四线三格中视觉准确。
|
||||
*
|
||||
* 设计思路(参考 Excalidraw 的 hardcoded font metrics):
|
||||
* - 缩放和偏移均为相对值(基于 gridH),换字体只需新增/调整 profile
|
||||
* - 按字母分类给出默认值,可通过 letterOverrides 对单个字母做精细微调
|
||||
*/
|
||||
|
||||
/** 字母分类 */
|
||||
export type LetterCategory =
|
||||
| 'uppercase'
|
||||
| 'tallLower'
|
||||
| 'descender'
|
||||
| 'lowercase';
|
||||
|
||||
/** 单个分类的渲染参数 */
|
||||
export interface CategoryMetrics {
|
||||
/** fontSize = gridH * scale */
|
||||
scale: number;
|
||||
/** 基线 Y 偏移修正(相对于 gridH,正值=下移) */
|
||||
baselineOffset: number;
|
||||
}
|
||||
|
||||
/** 单个字母的渲染微调(覆盖所属分类的默认值) */
|
||||
export interface LetterOverride {
|
||||
scale?: number;
|
||||
baselineOffset?: number;
|
||||
}
|
||||
|
||||
/** 一套完整的字体渲染配置 */
|
||||
export interface FontProfile {
|
||||
/** 唯一标识,同时用作 wx.loadFontFace 的 family 和按名称查找的 key */
|
||||
name: string;
|
||||
/** 字体 URL */
|
||||
url: string;
|
||||
/** 各分类的默认渲染参数 */
|
||||
categories: Record<LetterCategory, CategoryMetrics>;
|
||||
/** 按字母精细微调(优先级高于分类默认值) */
|
||||
letterOverrides?: Record<string, LetterOverride>;
|
||||
}
|
||||
|
||||
/** 构建 CSS font-family 串(含回退字体) */
|
||||
export function fontFamilyOf(profile: FontProfile): string {
|
||||
return `${profile.name}, Roboto, sans-serif`;
|
||||
}
|
||||
|
||||
// ── 字母分类集合 ──
|
||||
const TALL_LOWERCASE = new Set(['b', 'd', 'h', 'k', 'l']);
|
||||
const DESCENDERS = new Set(['g', 'p', 'q', 'y']);
|
||||
|
||||
export { TALL_LOWERCASE, DESCENDERS };
|
||||
|
||||
/** 判断字母所属分类 */
|
||||
export function getLetterCategory(letter: string): LetterCategory {
|
||||
if (letter >= 'A' && letter <= 'Z') return 'uppercase';
|
||||
if (TALL_LOWERCASE.has(letter)) return 'tallLower';
|
||||
if (DESCENDERS.has(letter)) return 'descender';
|
||||
return 'lowercase';
|
||||
}
|
||||
|
||||
/** 获取某个字母的最终渲染参数(分类默认 + 单字母微调合并) */
|
||||
export function getLetterMetrics(
|
||||
letter: string,
|
||||
profile: FontProfile,
|
||||
): CategoryMetrics {
|
||||
const cat = getLetterCategory(letter);
|
||||
const base = profile.categories[cat];
|
||||
const override = profile.letterOverrides?.[letter];
|
||||
if (!override) return base;
|
||||
return {
|
||||
scale: override.scale ?? base.scale,
|
||||
baselineOffset: override.baselineOffset ?? base.baselineOffset,
|
||||
};
|
||||
}
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// 字体配置表
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
/**
|
||||
* 四线三格字母分类目标占位(所有字体通用):
|
||||
* 顶线 ─── 第一格 ─── 中线 ─── 第二格 ─── 基线 ─── 第三格 ─── 底线
|
||||
*
|
||||
* uppercase / tallLower : 第一格 + 第二格(顶线 → 基线)
|
||||
* descender (g,p,q,y) : 第二格 + 第三格(中线 → 底线)
|
||||
* lowercase : 第二格(中线 → 基线)
|
||||
*
|
||||
* f / t / j 等需跨格占位的字母不在分类里单独建模,统一走 lowercase,
|
||||
* 在 letterOverrides 里按字体微调(与 i 相同方式)。
|
||||
*/
|
||||
|
||||
/** ZhiyongWrite 手写字体 */
|
||||
export const ZHIYONG_WRITE: FontProfile = {
|
||||
name: 'ZhiyongWrite',
|
||||
url: 'https://cdn.joeyone.cn/doodle/fonts/ZhiyongWrite.ttf',
|
||||
// categories: {
|
||||
// uppercase: { scale: 0.93, baselineOffset: 0 },
|
||||
// tallLower: { scale: 0.95, baselineOffset: 0 },
|
||||
// descender: { scale: 1.12, baselineOffset: 0.18 },
|
||||
// lowercase: { scale: 0.83, baselineOffset: 0.03 },
|
||||
// },
|
||||
// letterOverrides: {
|
||||
// i: { scale: 0.78, baselineOffset: 0.02 },
|
||||
// f: { scale: 1.37, baselineOffset: 0.34 },
|
||||
// t: { scale: 0.85, baselineOffset: 0 },
|
||||
// j: { scale: 1, baselineOffset: 0.15 },
|
||||
// },
|
||||
categories: {
|
||||
uppercase: { scale: 0.95, baselineOffset: 0 },
|
||||
tallLower: { scale: 0.85, baselineOffset: 0 },
|
||||
descender: { scale: 1, baselineOffset: 0.12 },
|
||||
lowercase: { scale: 0.75, baselineOffset: 0 },
|
||||
},
|
||||
letterOverrides: {
|
||||
i: { scale: 0.8, baselineOffset: 0 },
|
||||
f: { scale: 1, baselineOffset: 0.05 },
|
||||
t: { scale: 0.85, baselineOffset: 0 },
|
||||
j: { scale: 0.85, baselineOffset: 0.1 },
|
||||
},
|
||||
};
|
||||
|
||||
/** Handlee Regular — Google 手写风格 */
|
||||
export const HANDLEE_REGULAR: FontProfile = {
|
||||
name: 'HandleeRegular',
|
||||
url: 'https://cdn.joeyone.cn/doodle/fonts/Handlee-Regular.ttf',
|
||||
// categories: {
|
||||
// uppercase: { scale: 0.9, baselineOffset: 0 },
|
||||
// tallLower: { scale: 0.73, baselineOffset: 0.03 },
|
||||
// descender: { scale: 0.8, baselineOffset: 0.05 },
|
||||
// lowercase: { scale: 0.73, baselineOffset: 0.02 },
|
||||
// },
|
||||
// letterOverrides: {
|
||||
// i: { scale: 0.78, baselineOffset: 0.02 },
|
||||
// f: { scale: 0.82, baselineOffset: 0 },
|
||||
// t: { scale: 0.77, baselineOffset: 0.04 },
|
||||
// j: { scale: 0.85, baselineOffset: 0.08 },
|
||||
// },
|
||||
categories: {
|
||||
uppercase: { scale: 0.9, baselineOffset: 0 },
|
||||
tallLower: { scale: 0.68, baselineOffset: 0 },
|
||||
descender: { scale: 0.68, baselineOffset: 0 },
|
||||
lowercase: { scale: 0.68, baselineOffset: 0 },
|
||||
},
|
||||
letterOverrides: {
|
||||
i: { scale: 0.68, baselineOffset: 0 },
|
||||
f: { scale: 0.68, baselineOffset: 0 },
|
||||
t: { scale: 0.68, baselineOffset: 0 },
|
||||
j: { scale: 0.68, baselineOffset: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
/** Print Clearly Regular */
|
||||
export const PRINT_CLEARLY_REGULAR: FontProfile = {
|
||||
name: 'PrintClearlyRegular',
|
||||
url: 'https://cdn.joeyone.cn/doodle/fonts/print_clearly_regular_tt.ttf',
|
||||
categories: {
|
||||
uppercase: { scale: 1, baselineOffset: 0 },
|
||||
tallLower: { scale: 1, baselineOffset: 0 },
|
||||
descender: { scale: 1, baselineOffset: 0 },
|
||||
lowercase: { scale: 1, baselineOffset: 0 },
|
||||
},
|
||||
letterOverrides: {
|
||||
i: { scale: 1, baselineOffset: 0 },
|
||||
f: { scale: 1, baselineOffset: 0 },
|
||||
t: { scale: 1, baselineOffset: 0 },
|
||||
j: { scale: 1, baselineOffset: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
/** Print Clearly Bold */
|
||||
export const PRINT_CLEARLY_BOLD: FontProfile = {
|
||||
name: 'PrintClearlyBold',
|
||||
url: 'https://cdn.joeyone.cn/doodle/fonts/print_clearly_bold_tt.ttf',
|
||||
categories: {
|
||||
uppercase: { scale: 1, baselineOffset: 0 },
|
||||
tallLower: { scale: 1, baselineOffset: 0 },
|
||||
descender: { scale: 1, baselineOffset: 0 },
|
||||
lowercase: { scale: 1, baselineOffset: 0 },
|
||||
},
|
||||
letterOverrides: {
|
||||
i: { scale: 1, baselineOffset: 0 },
|
||||
f: { scale: 1, baselineOffset: 0 },
|
||||
t: { scale: 1, baselineOffset: 0 },
|
||||
j: { scale: 1, baselineOffset: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
/** Print Clearly Dashed — 虚线描红字体 */
|
||||
export const PRINT_CLEARLY_DASHED: FontProfile = {
|
||||
name: 'PrintClearlyDashed',
|
||||
url: 'https://cdn.joeyone.cn/doodle/fonts/print_clearly_dashed_tt.ttf',
|
||||
categories: {
|
||||
uppercase: { scale: 1, baselineOffset: 0 },
|
||||
tallLower: { scale: 1, baselineOffset: 0 },
|
||||
descender: { scale: 1, baselineOffset: 0 },
|
||||
lowercase: { scale: 1, baselineOffset: 0 },
|
||||
},
|
||||
letterOverrides: {
|
||||
i: { scale: 1, baselineOffset: 0 },
|
||||
f: { scale: 1, baselineOffset: 0 },
|
||||
t: { scale: 1, baselineOffset: 0 },
|
||||
j: { scale: 1, baselineOffset: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
/** Num 数字字体 */
|
||||
export const NUM_FONT: FontProfile = {
|
||||
name: 'NumFont',
|
||||
url: 'https://cdn.joeyone.cn/doodle/fonts/num.woff2',
|
||||
categories: {
|
||||
uppercase: { scale: 0.95, baselineOffset: 0 },
|
||||
tallLower: { scale: 0.95, baselineOffset: 0 },
|
||||
descender: { scale: 1.05, baselineOffset: 0 },
|
||||
lowercase: { scale: 0.85, baselineOffset: 0 },
|
||||
},
|
||||
letterOverrides: {
|
||||
f: { scale: 1.35, baselineOffset: 0 },
|
||||
t: { scale: 0.85, baselineOffset: 0 },
|
||||
j: { scale: 1.15, baselineOffset: 0 },
|
||||
},
|
||||
};
|
||||
|
||||
// ── 字体注册表:按 name 索引所有可用字体 ──
|
||||
|
||||
const FONT_PROFILES: ReadonlyArray<FontProfile> = [
|
||||
ZHIYONG_WRITE,
|
||||
HANDLEE_REGULAR,
|
||||
PRINT_CLEARLY_REGULAR,
|
||||
PRINT_CLEARLY_BOLD,
|
||||
PRINT_CLEARLY_DASHED,
|
||||
NUM_FONT,
|
||||
];
|
||||
|
||||
const _profileByName = new Map<string, FontProfile>(
|
||||
FONT_PROFILES.map((p) => [p.name, p]),
|
||||
);
|
||||
|
||||
/** 默认字母字体 */
|
||||
export const DEFAULT_LETTER_PROFILE = PRINT_CLEARLY_REGULAR;
|
||||
|
||||
/** 按名称查找字体配置,找不到返回默认 */
|
||||
export function getFontProfile(name: string): FontProfile {
|
||||
return _profileByName.get(name) ?? DEFAULT_LETTER_PROFILE;
|
||||
}
|
||||
@@ -7,14 +7,14 @@ import {
|
||||
fontFamilyOf,
|
||||
getLetterMetrics,
|
||||
type FontProfile,
|
||||
} from '../data/fontProfiles';
|
||||
} from '../../../core/font/fontProfiles';
|
||||
import { GRID_COLORS, GRID_DASH } from '../../../core/data/tracingStyles';
|
||||
import { loadFontFace } from '../../../core/font/fontLoader';
|
||||
|
||||
// ── 四线三格统一高度(所有页面共用) ──
|
||||
export const FOUR_LINE_GRID_H = 43;
|
||||
|
||||
// ── 字体加载(支持多字体,按 URL 去重) ──
|
||||
|
||||
const _loadedUrls = new Set<string>();
|
||||
// ── 字体加载(委托到 core/font/fontLoader) ──
|
||||
|
||||
/**
|
||||
* 加载字体到 Canvas native 渲染管线。
|
||||
@@ -23,22 +23,7 @@ const _loadedUrls = new Set<string>();
|
||||
export function loadLetterFont(
|
||||
profile: FontProfile = DEFAULT_LETTER_PROFILE,
|
||||
): Promise<void> {
|
||||
if (_loadedUrls.has(profile.url)) return Promise.resolve();
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.loadFontFace({
|
||||
family: profile.name,
|
||||
source: `url("${profile.url}")`,
|
||||
scopes: ['native'],
|
||||
success: () => {
|
||||
_loadedUrls.add(profile.url);
|
||||
resolve();
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(`loadLetterFont [${profile.name}] failed`, err);
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
return loadFontFace(profile);
|
||||
}
|
||||
|
||||
// ── LetterFontSizes:持有 FontProfile 引用,运行时按字母查表 ──
|
||||
@@ -74,7 +59,7 @@ function getLetterBaselineOffset(
|
||||
}
|
||||
|
||||
// ── 向后兼容:导出 DESCENDERS 集合 ──
|
||||
export { DESCENDERS } from '../data/fontProfiles';
|
||||
export { DESCENDERS } from '../../../core/font/fontProfiles';
|
||||
|
||||
/**
|
||||
* 在四线三格中绘制单个字母(基线固定在 y + 2h/3 + baselineOffset)。
|
||||
@@ -138,10 +123,10 @@ export function drawFourLineGrid(
|
||||
h: number,
|
||||
style?: FourLineGridStyle,
|
||||
) {
|
||||
const ink = style?.ink ?? '#322E25';
|
||||
const middleInk = style?.middleInk ?? 'rgba(50, 46, 37, 0.3)';
|
||||
const ink = style?.ink ?? GRID_COLORS.border;
|
||||
const middleInk = style?.middleInk ?? GRID_COLORS.middleLine;
|
||||
const lineWidth = style?.lineWidth ?? 1;
|
||||
const dash = style?.dash ?? [4, 4];
|
||||
const dash = style?.dash ?? [...GRID_DASH];
|
||||
|
||||
const yTop = y;
|
||||
const y1 = y + h / 3;
|
||||
@@ -188,10 +173,10 @@ export function drawClosedFourLineGrid(
|
||||
h: number,
|
||||
style?: FourLineGridStyle,
|
||||
) {
|
||||
const ink = style?.ink ?? '#9AA9A2';
|
||||
const middleInk = style?.middleInk ?? 'rgba(154, 169, 162, 0.65)';
|
||||
const ink = style?.ink ?? GRID_COLORS.border;
|
||||
const middleInk = style?.middleInk ?? GRID_COLORS.middleLine;
|
||||
const lineWidth = style?.lineWidth ?? 1;
|
||||
const dash = style?.dash ?? [3, 3];
|
||||
const dash = style?.dash ?? [...GRID_DASH];
|
||||
|
||||
const y1 = y + h / 3;
|
||||
const y2 = y + (h * 2) / 3;
|
||||
|
||||
Reference in New Issue
Block a user