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

@@ -17,15 +17,91 @@
**核心变化:**
1. **配置驱动**:从 JSON 配置文件完全定义罗盘结构
2. **新增罗盘零改码**:新增罗盘只需在 `public/` 下增加 JSON 配置文件,无需修改代码
3. **复杂着色规则**:支持三级着色优先级(全局 → 层级规律填色 → 扇区独立)
4. **多文本单元**:扇区内容支持 `|` 分隔的多个文本单元,角度智能分配
5. **SVG 图标支持**:扇区内容可以是 SVG 文件
6. **中心图标**作为 layer 类型,支持可旋转的中心 SVG 图标
7. **360度刻度环**:作为 layer 类型,支持多种刻度模式的度数环
8. **命名配色方案**:通过 theme.colorPalettes 定义可复用颜色
9. **规律填色机制**:通过 num + interval 实现周期性着色
10. **同组分割线控制**groupSplit 参数控制组内分割线显示
11. **外半径兜底**:默认使用 layers 最大 rOuterouterRadius 仅作为无层配置时的兜底
3. **配置下拉切换**:下拉菜单可选择 `public/` 下的配置(如 `demo.json``demo2.json`)切换罗盘
4. **复杂着色规则**:支持三级着色优先级(全局 → 层级规律填色 → 扇区独立)
5. **多文本单元**:扇区内容支持 `|` 分隔的多个文本单元,角度智能分配
6. **多文本比例可配**在每个 layer 中可配置多文本比例(用于 `|` 分隔内容的角度分配)
7. **SVG 图标支持**:扇区内容可以是 SVG 文件
8. **中心图标**:作为 layer 类型,支持可旋转的中心 SVG 图标
9. **360度刻度环**:作为 layer 类型,支持多种刻度模式的度数环
10. **命名配色方案**:通过 theme.colorPalettes 定义可复用颜色
11. **规律填色机制**:通过 num + interval 实现周期性着色
12. **同组分割线控制**groupSplit 参数控制组内分割线显示
13. **外半径兜底**:默认使用 layers 最大 rOuterouterRadius 仅作为无层配置时的兜底
### 1.3 配置清单与切换机制(新增)
**问题:** 运行时无法直接读取 `public/` 目录文件列表,因此下拉菜单需要“配置清单”或“构建期生成清单”。
**推荐方案(满足“新增罗盘只需增加 JSON 文件”):**
1. **清单文件:** 构建期生成 `public/luopan-configs.json`,包含可选配置列表与默认项。
2. **生成逻辑:** 扫描 `public/` 下的 `*.json`,排除 `*.json.conf``luopan-configs.json` 本身。
3. **示例格式:**
```json
{
"default": "demo.json",
"items": [
{ "name": "示例罗盘一", "path": "/demo.json" },
{ "name": "示例罗盘二", "path": "/demo2.json" }
]
}
```
4. **前端加载:** `Luopan.vue` 启动时拉取该清单,渲染下拉选项。
5. **切换逻辑:** 选择项变化时更新 `configPath` 并触发重新加载;同步更新 URL `?config=xxx.json` 便于分享。
6. **新增配置:** 仅需在 `public/` 放入新的 `*.json`,清单会在构建/开发启动时自动更新。
**备用方案(不启用生成脚本):** 手动维护 `public/luopan-configs.json`,仍然无需改代码,但需追加清单条目。
### 1.4 主题抽离与引用(新增)
**目标:** 罗盘配置通过 `themeRef` 引用统一的 `themes.json`,不再内嵌 theme。
**主题文件结构public/themes.json**
```json
{
"default": "五行",
"items": [
{
"name": "五行",
"colorPalettes": {
"黑": "#000000",
"灰": "#757575"
}
}
]
}
```
**罗盘 JSON 使用方式:**
```json
{
"name": "demo",
"background": "白",
"themeRef": "五行",
"layers": []
}
```
**解析规则:**
1. 如果配置包含 `themeRef`,优先使用对应主题。
2. 若未指定 `themeRef`,使用 `themes.json.default`。
3. 若 `themeRef` 或 `default` 不存在:抛出配置错误(或回退到空主题,需在实现中约定)。
**实现改动点:**
1. `types.ts`
- `LuopanConfig.theme` 变为可选
- 新增 `themeRef?: string`
2. `configParser.ts`
- 支持解析 `themeRef`
- 当 `theme` 缺失时暂不报错,由上层注入主题
3. `useLuopan.ts`
- 读取 `public/themes.json`
- 根据 `themeRef/default` 注入主题到配置
- 处理错误与回退
4. 示例与文档:
- `public/demo*.json` 替换为 `themeRef`
- 新增 `public/themes.json`
- 更新 `demo.json.conf` 说明
---
@@ -148,15 +224,17 @@ function applyPatternColoring(
}
```
**多文本单元角度分配:**
**多文本单元角度分配(支持 unitRatios**
```typescript
function splitMultiTextUnits(
content: string,
aStart: number,
aEnd: number
aEnd: number,
unitRatios?: number[]
): TextUnit[] {
const units = content.split('|');
const ratios = getLayoutRatio(units.length); // 从 constants.ts
const ratios = normalizeRatios(unitRatios, units.length)
?? getLayoutRatio(units.length); // 从 constants.ts
const totalAngle = aEnd - aStart;
const textUnits: TextUnit[] = [];
@@ -174,6 +252,27 @@ function splitMultiTextUnits(
return textUnits;
}
function normalizeRatios(
ratios: number[] | undefined,
count: number
): number[] | null {
if (!ratios || ratios.length !== count) return null;
if (ratios.some((value) => typeof value !== 'number' || value <= 0)) return null;
const sum = ratios.reduce((acc, value) => acc + value, 0);
if (sum <= 0) return null;
return ratios.map((value) => value / sum);
}
```
**示例layer 级别配置比例):**
```json
{
"divisions": 24,
"rInner": 200,
"rOuter": 240,
"unitRatios": [0.25, 0.5, 0.25]
}
```
---
@@ -243,6 +342,7 @@ export interface SectorLayerConfig {
startAngle?: number;
colorRef?: string;
innerFill?: 0 | 1;
unitRatios?: number[]; // 多文本单元比例(对应 content 用 "|" 分隔)
num?: number;
interval?: number;
groupSplit?: boolean;
@@ -429,6 +529,7 @@ export class ColorResolver {
- splitMultiTextUnits() 函数
- 角度分配逻辑
- SVG 文件检测
- 支持 layer.unitRatios 覆盖默认比例
2. ✅ 更新 `utils.ts`
- 适配多文本单元的路径生成
- 字体大小计算调整
@@ -674,7 +775,7 @@ export function buildDegreeRing(config: DegreeRingConfig): {
- 调用各个解析器和构建器
- 返回完整渲染数据
2. ✅ 更新 `Luopan.vue`
- 移除示例选择器
- 使用配置下拉替换示例选择器(可切换 `public/*.json`
- 添加配置加载界面
- 渲染多文本单元
- 渲染刻度环
@@ -1179,4 +1280,3 @@ describe('完整渲染流程', () => {
---
**本重构方案完全基于现有代码和需求文档制定,确保可行性和可执行性。建议按阶段逐步实施,每个阶段完成后进行验收,确保质量和进度。**