update at 2026-01-23 23:20:39
This commit is contained in:
128
refactor-plan.md
128
refactor-plan.md
@@ -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 最大 rOuter,outerRadius 仅作为无层配置时的兜底
|
||||
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 最大 rOuter,outerRadius 仅作为无层配置时的兜底
|
||||
|
||||
### 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('完整渲染流程', () => {
|
||||
---
|
||||
|
||||
**本重构方案完全基于现有代码和需求文档制定,确保可行性和可执行性。建议按阶段逐步实施,每个阶段完成后进行验收,确保质量和进度。**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user