update at 2026-01-23 23:20:39

This commit is contained in:
douboer@gmail.com
2026-01-23 23:20:39 +08:00
parent dc45937623
commit d6312fcd16
24 changed files with 982 additions and 143 deletions

View File

@@ -260,7 +260,7 @@ export function generateTextPath(
}
// 不调整半径,保持在中线位置
// 使用 dominant-baseline 属性控制文字垂直对齐
// 使用 `dominant-baseline` 属性控制文字垂直对齐
const adjustedRMid = rMid;
const a1 = normalizeDeg(aStartDeg);
@@ -275,8 +275,8 @@ export function generateTextPath(
const largeArc = delta > 180 ? 1 : 0;
// 保持路径完整,不在这里应用 padding
// padding 通过字体大小计算textPath 的 startOffset/text-anchor 实现
// 保持路径完整,不在这里应用内边距(`padding`
// 内边距(`padding`通过字体大小计算以及 `textPath``startOffset`/`text-anchor` 实现
if (needReverse) {
// 反向路径(从结束点到起始点),保持文字头朝外
@@ -384,14 +384,14 @@ export function generateVerticalTextPath(
const requiredPathLength =
effectiveTextLength * TEXT_LAYOUT_CONFIG.CHAR_SPACING_RATIO * effectiveFontSize;
// 确保路径不超出扇区边界(考虑径向 padding
// 确保路径不超出扇区边界(考虑径向内边距 `padding`
const maxPathLength = radialHeight * TEXT_LAYOUT_CONFIG.RADIAL_PADDING_RATIO;
const actualPathLength = Math.min(requiredPathLength, maxPathLength);
let finalStartR: number;
let finalEndR: number;
// 对于从圆心开始的扇区(rInner=0),形心会偏向外侧
// 对于从圆心开始的扇区`rInner`=0,形心会偏向外侧
// 需要特殊处理以防止溢出
if (rInner === 0) {
// 计算路径应该在哪里结束(从外圆向内)
@@ -409,7 +409,7 @@ export function generateVerticalTextPath(
finalEndR = rMid - halfPath;
}
} else {
// 普通扇区:以 rMid 为中心
// 普通扇区:以 `rMid` 为中心
const halfPathLength = actualPathLength / 2;
// 确保不超出边界
@@ -492,13 +492,13 @@ export function calculateSectorFontSize(
const maxByHeight = availableHeight / (textLength * TEXT_LAYOUT_CONFIG.CHAR_SPACING_RATIO);
// 约束2最内侧字符的弧长宽度这是最严格的宽度限制
// 最内侧字符的中心位置大约在 rInner + fontSize/2 处
// 最内侧字符的中心位置大约在 `rInner` + `fontSize`/2 处
// 保守估计:假设字体大小约为径向宽度的一半
const estimatedFontSize = radialWidth * 0.5;
const innerMostRadius = rInner + estimatedFontSize / 2;
const innerArcLength = (innerMostRadius * deltaDeg * Math.PI) / 180;
// 字符宽度约为 fontSize × 1.0(方块字)
// 字符宽度约为 `fontSize` × 1.0(方块字)
const availableArcLength = innerArcLength * TEXT_LAYOUT_CONFIG.TANGENT_PADDING_RATIO;
const maxByWidth = availableArcLength / 1.0; // 单个字符宽度
@@ -515,11 +515,11 @@ export function calculateSectorFontSize(
const maxByHeight = radialWidth * TEXT_LAYOUT_CONFIG.RADIAL_PADDING_RATIO;
// 2. 宽度约束:根据文字总宽度计算
// 中文字符宽度 = fontSize方块字
// 字符间距:约 0.1 * fontSize总占用约 1.1 * fontSize
// 中文字符宽度 = `fontSize`(方块字)
// 字符间距:约 0.1 * `fontSize`,总占用约 1.1 * `fontSize`
const availableArcLength = arcLength * TEXT_LAYOUT_CONFIG.TANGENT_PADDING_RATIO;
// 反推字体大小fontSize = 可用弧长 / (字符数 × 1.1)
// 反推字体大小:`fontSize` = 可用弧长 / (字符数 × 1.1)
const maxByWidth = availableArcLength / (textLength * 1.1);
// 3. 取宽度和高度约束中较小的那个(更严格的限制)
@@ -561,13 +561,13 @@ function calculateVerticalTextLength(
// 计算径向可用高度
const radialHeight = rOuter - rInner;
// 考虑上下padding可用高度约为总高度的配置比例
// 考虑上下内边距(`padding`,可用高度约为总高度的配置比例
const availableHeight = radialHeight * TEXT_LAYOUT_CONFIG.RADIAL_PADDING_RATIO;
// 计算可以容纳的字符数
const maxFittableChars = Math.floor(availableHeight / (fontSize * TEXT_LAYOUT_CONFIG.CHAR_SPACING_RATIO));
// 限制在 [MIN_CHARS, MAX_CHARS] 范围内
// 限制在 [`MIN_CHARS`, `MAX_CHARS`] 范围内
const charCount = Math.max(MIN_CHARS, Math.min(MAX_CHARS, maxFittableChars));
return charCount;