diff --git a/public/demo.json b/public/demo.json
index c8b20d6..5923d98 100644
--- a/public/demo.json
+++ b/public/demo.json
@@ -1,8 +1,10 @@
{
"name": "demo",
"description": "luopan demo config with named color palettes",
- "background": "#fff000",
- "outerRadius": 500,
+ "background": "金",
+ "strokeWidth": 0.5,
+ "strokeColor": "冷",
+ "strokeOpacity": 0.5,
"theme": {
"name": "五行配色主题",
"colorPalettes": {
@@ -12,12 +14,12 @@
"木": "#43A047",
"火": "#E53935",
"土": "#8D6E63",
- "金": "#78909C",
+ "金": "#D4AF37",
"水": "#0288D1",
"热": "#FF8F00",
"冷": "#1976D2",
"强": "#D32F2F",
- "\u8f6f": "#FFE0B2"
+ "软": "#FFE0B2"
}
},
"layers": [
@@ -25,7 +27,7 @@
"type": "centerIcon",
"centerIcon": {
"rIcon": 50,
- "opacity": 0.8,
+ "opacity": 0.5,
"name": "centericon.svg"
}
},
@@ -89,7 +91,7 @@
},
{
"divisions": 24,
- "rInner": 210,
+ "rInner": 200,
"rOuter": 240,
"startAngle": 0,
"sectors": [
@@ -121,7 +123,7 @@
},
{
"divisions": 16,
- "rInner": 240,
+ "rInner": 250,
"rOuter": 270,
"startAngle": 0,
"sectors": [
diff --git a/public/demo.json.conf b/public/demo.json.conf
index d73c2f6..7ded500 100644
--- a/public/demo.json.conf
+++ b/public/demo.json.conf
@@ -17,7 +17,10 @@
-- ========================================
-- 全局配置
-- ========================================
- "background": "#000000", -- 全局背景色,未着色扇区使用此颜色
+ "background": "黑", -- 全局背景色,未着色扇区使用此颜色(支持 colorPalettes)
+ "strokeWidth": 0.3, -- 扇区边界线宽度(像素)
+ "strokeColor": "灰", -- 扇区边界线颜色(支持 colorPalettes)
+ "strokeOpacity": 0.15, -- 扇区边界线透明度
"outerRadius": 500, -- 罗盘外半径,单位:像素
-- ========================================
diff --git a/refactor-plan.md b/refactor-plan.md
index 3b9cc57..f6acdac 100644
--- a/refactor-plan.md
+++ b/refactor-plan.md
@@ -188,7 +188,10 @@ function splitMultiTextUnits(
export interface LuopanConfig {
name: string;
description?: string;
- background: string; // 全局背景色
+ background: string; // 全局背景色(支持主题色)
+ strokeWidth?: number; // 扇区边界线宽度
+ strokeColor?: string; // 扇区边界线颜色(支持主题色)
+ strokeOpacity?: number; // 扇区边界线透明度
theme: ThemeConfig;
layers: LayerConfig[]; // 扇区层 + 中心图标层 + 刻度环层
}
diff --git a/src/Luopan.vue b/src/Luopan.vue
index a8f8e25..7fd4b04 100644
--- a/src/Luopan.vue
+++ b/src/Luopan.vue
@@ -46,11 +46,8 @@
}"
>
-
@@ -62,9 +59,6 @@
:key="s.key"
:d="s.path"
:fill="s.fill"
- stroke="#1f2937"
- :stroke-opacity="s.groupSplitVisible === false ? 0 : 0.15"
- :stroke-width="SECTOR_STROKE_WIDTH"
/>
@@ -168,6 +162,30 @@
+
+
+
+
+
+
+
+
{
const viewBoxMin = computed(() => -viewBoxSize.value / 2);
+const strokeWidth = computed(() =>
+ typeof config.value?.strokeWidth === 'number'
+ ? config.value.strokeWidth
+ : SECTOR_STROKE_WIDTH
+);
+const strokeColor = computed(() => config.value?.strokeColor ?? '#1f2937');
+const strokeOpacity = computed(() =>
+ typeof config.value?.strokeOpacity === 'number' ? config.value.strokeOpacity : 0.15
+);
+const boundaryRings = computed(() => {
+ const set = new Set();
+ sectors.value.forEach((sector) => {
+ if (sector.rInner > 0) set.add(sector.rInner);
+ set.add(sector.rOuter);
+ });
+ return Array.from(set);
+});
+
// 使用 rAF 合并缩放/拖拽更新,减少渲染频率
const scheduleTransform = () => {
if (rafId !== null) return;
@@ -529,7 +565,7 @@ button.active {
}
.svg {
- background: #fff;
+ background: transparent;
transition: transform 0.1s ease-out;
user-select: none;
}
diff --git a/src/composables/useLuopan.ts b/src/composables/useLuopan.ts
index 2fe0598..0e9a951 100644
--- a/src/composables/useLuopan.ts
+++ b/src/composables/useLuopan.ts
@@ -22,6 +22,18 @@ import { loadCenterIcon } from '../centerIcon';
const isSectorLayer = (layer: LayerConfig): layer is SectorLayerConfig =>
layer.type !== 'centerIcon' && layer.type !== 'degreeRing';
+const HEX_COLOR_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
+
+const resolveThemeColor = (
+ theme: LuopanConfig['theme'],
+ value: string | undefined,
+ fallback: string
+) => {
+ if (!value) return fallback;
+ if (HEX_COLOR_RE.test(value)) return value;
+ return theme.colorPalettes[value] ?? fallback;
+};
+
const findDegreeRingLayer = (layers: LayerConfig[]) =>
layers.find((layer) => layer.type === 'degreeRing');
@@ -71,15 +83,38 @@ export function useLuopan(
configObj = configPathOrObject;
}
- config.value = configObj;
- sectors.value = buildSectors(configObj);
+ const resolvedBackground = resolveThemeColor(
+ configObj.theme,
+ configObj.background,
+ '#000000'
+ );
+ const resolvedStrokeColor = resolveThemeColor(
+ configObj.theme,
+ configObj.strokeColor,
+ '#1f2937'
+ );
- const degreeRingLayer = findDegreeRingLayer(configObj.layers);
+ const resolvedConfig: LuopanConfig = {
+ ...configObj,
+ background: resolvedBackground,
+ strokeColor: resolvedStrokeColor,
+ strokeWidth: typeof configObj.strokeWidth === 'number'
+ ? configObj.strokeWidth
+ : undefined,
+ strokeOpacity: typeof configObj.strokeOpacity === 'number'
+ ? configObj.strokeOpacity
+ : undefined,
+ };
+
+ config.value = resolvedConfig;
+ sectors.value = buildSectors(resolvedConfig);
+
+ const degreeRingLayer = findDegreeRingLayer(resolvedConfig.layers);
degreeRing.value = degreeRingLayer
? buildDegreeRing(degreeRingLayer.degreeRing)
: null;
- const centerIconLayer = findCenterIconLayer(configObj.layers);
+ const centerIconLayer = findCenterIconLayer(resolvedConfig.layers);
centerIcon.value = centerIconLayer
? await loadCenterIcon(centerIconLayer.centerIcon)
: null;
@@ -116,14 +151,17 @@ export function useLuopan(
const outerMost = computed(() => {
if (!config.value) return 0;
- if (typeof config.value.outerRadius === 'number') return config.value.outerRadius;
const radii = sectorLayers.value.map((layer) => layer.rOuter);
const degreeRingLayer = findDegreeRingLayer(config.value.layers);
if (degreeRingLayer) {
radii.push(degreeRingLayer.degreeRing.rOuter);
}
- return radii.length > 0 ? Math.max(...radii) : 0;
+
+ const maxRadius = radii.length > 0 ? Math.max(...radii) : 0;
+ if (maxRadius > 0) return maxRadius;
+
+ return typeof config.value.outerRadius === 'number' ? config.value.outerRadius : 0;
});
return {
diff --git a/src/configParser.ts b/src/configParser.ts
index 9d6bc8a..468e195 100644
--- a/src/configParser.ts
+++ b/src/configParser.ts
@@ -76,6 +76,9 @@ export const parseConfig = (jsonText: string): LuopanConfig => {
name: config.name,
description: typeof config.description === 'string' ? config.description : undefined,
background: config.background,
+ strokeWidth: typeof config.strokeWidth === 'number' ? config.strokeWidth : undefined,
+ strokeColor: typeof config.strokeColor === 'string' ? config.strokeColor : undefined,
+ strokeOpacity: typeof config.strokeOpacity === 'number' ? config.strokeOpacity : undefined,
outerRadius: typeof config.outerRadius === 'number' ? config.outerRadius : undefined,
theme: normalizeTheme(config.theme),
layers: config.layers as LuopanConfig['layers'],
diff --git a/src/types.ts b/src/types.ts
index c423cea..07d49fa 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -26,6 +26,9 @@ export interface LuopanConfig {
name: string;
description?: string;
background: string;
+ strokeWidth?: number;
+ strokeColor?: string;
+ strokeOpacity?: number;
outerRadius?: number;
theme: ThemeConfig;
layers: LayerConfig[];
diff --git a/todolist.md b/todolist.md
index f44aeac..805ff5c 100644
--- a/todolist.md
+++ b/todolist.md
@@ -12,7 +12,8 @@
字体大小和位置通过工具函数自动计算。单个扇区内的多文本单元之间无分割线。
4. 废弃目前颜色生成规则。使用在Json中严格配置。详见《Json文件配置》。总体规则是:优先级低到高分别是,全局背景色 - layer着色 - sectors着色。
5. Json中不用关注是第几层,按配置的rinner,router等参数绘制即可。
-
+6. 在json中增加全局中定义strokeWidth,strokeColor,strokeOpacity, 如在json中定义,覆盖constants中SECTOR_STROKE_WIDTH,和stroke,如json每定义,使用代码中默认。颜色可以使用colorPalettes中定义的颜色,background也可以使用colorPalettes定义的颜色。
+7. 需求:json中配置的背景色,只对罗盘区域着色
## Json文件配置
### json字段配置说明
@@ -21,7 +22,10 @@
|--------|------|------|------|------|
| name | string | 是 | 罗盘配置名称 | "demo" |
| description | string | 否 | 罗盘配置描述 | "luopan demo config" |
- | background | string | 是 | 全局背景色(十六进制颜色值),未着色扇区使用此颜色 | "#000000" |
+ | background | string | 是 | 全局背景色(支持十六进制或 colorPalettes 名称),未着色扇区使用此颜色 | "#000000" |
+ | strokeWidth | number | 否 | 扇区边界线宽度(像素),覆盖默认值 | 0.3 |
+ | strokeColor | string | 否 | 扇区边界线颜色(支持十六进制或 colorPalettes 名称) | "#1f2937" |
+ | strokeOpacity | number | 否 | 扇区边界线透明度(0.0-1.0) | 0.15 |
| outerRadius | number | 是 | 罗盘外半径,单位:像素(去掉该参数,自动计算最大半径) | 500 |
| theme | object | 是 | 主题配置对象,包含colorPalettes命名配色方案 | 见下方theme说明 |
| centerIcon | object | 否 | 中心图标配置 | 见下方centerIcon说明 |
@@ -209,4 +213,3 @@
"tickColor": "#000000",-- 刻度线颜色
"ringColor": "#000000" -- 圆环颜色
}
-