feat: 增加无路线颜色配置,优化颜色管理逻辑以支持暗色主题
This commit is contained in:
parent
d7e5477b5a
commit
8405d98fe0
@ -1,7 +1,8 @@
|
|||||||
import { MapAreaType, MapPointType } from '@api/map';
|
import { MapAreaType, MapPointType } from '@api/map';
|
||||||
import sTheme from '@core/theme.service';
|
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import sTheme from '../theme.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 点位类型常量 - 从枚举中提取数字类型
|
* 点位类型常量 - 从枚举中提取数字类型
|
||||||
*/
|
*/
|
||||||
@ -47,6 +48,7 @@ export interface EditorColorConfig {
|
|||||||
// 路线颜色
|
// 路线颜色
|
||||||
route: {
|
route: {
|
||||||
strokeActive: string;
|
strokeActive: string;
|
||||||
|
strokeNone: string; // 无路线颜色
|
||||||
strokeEmpty: string; // 空载路线颜色
|
strokeEmpty: string; // 空载路线颜色
|
||||||
strokeLoaded: string; // 载货路线颜色
|
strokeLoaded: string; // 载货路线颜色
|
||||||
strokeForbidden: string; // 禁行路线颜色
|
strokeForbidden: string; // 禁行路线颜色
|
||||||
@ -249,7 +251,7 @@ function generateAreaBorderColors(): Record<number, string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认颜色配置
|
* 默认颜色配置(亮色主题)
|
||||||
*/
|
*/
|
||||||
const DEFAULT_COLORS: EditorColorConfig = {
|
const DEFAULT_COLORS: EditorColorConfig = {
|
||||||
point: {
|
point: {
|
||||||
@ -279,6 +281,7 @@ const DEFAULT_COLORS: EditorColorConfig = {
|
|||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
strokeActive: '#EBB214',
|
strokeActive: '#EBB214',
|
||||||
|
strokeNone: '#8C8C8C', // 无路线 - 灰色
|
||||||
strokeEmpty: '#52C41A', // 空载路线 - 绿色
|
strokeEmpty: '#52C41A', // 空载路线 - 绿色
|
||||||
strokeLoaded: '#1982F3', // 载货路线 - 蓝色
|
strokeLoaded: '#1982F3', // 载货路线 - 蓝色
|
||||||
strokeForbidden: '#E63A3A' // 禁行路线 - 红色
|
strokeForbidden: '#E63A3A' // 禁行路线 - 红色
|
||||||
@ -331,6 +334,149 @@ const DEFAULT_COLORS: EditorColorConfig = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暗色主题默认颜色配置
|
||||||
|
*/
|
||||||
|
const DARK_THEME_COLORS: EditorColorConfig = {
|
||||||
|
point: {
|
||||||
|
small: {
|
||||||
|
stroke: '#8C8C8C',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
fill: {
|
||||||
|
1: '#14D1A5',
|
||||||
|
2: '#69C6F5',
|
||||||
|
3: '#E48B1D',
|
||||||
|
4: '#E48B1D',
|
||||||
|
5: '#a72b69'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
large: {
|
||||||
|
stroke: '#595959',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
strokeOccupied: '#ff4d4f',
|
||||||
|
strokeUnoccupied: '#52c41a',
|
||||||
|
strokeEmpty: '#1890ff',
|
||||||
|
strokeDisabled: '#bfbfbf',
|
||||||
|
strokeEnabled: '#52c41a',
|
||||||
|
strokeLocked: '#faad14',
|
||||||
|
strokeUnlocked: '#52c41a'
|
||||||
|
},
|
||||||
|
types: generatePointTypeColors()
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
strokeNone: '#8C8C8C', // 无路线 - 灰色
|
||||||
|
strokeEmpty: '#49AA19', // 空载路线 - 绿色
|
||||||
|
strokeLoaded: '#1982F3', // 载货路线 - 蓝色
|
||||||
|
strokeForbidden: '#E63A3A' // 禁行路线 - 红色
|
||||||
|
},
|
||||||
|
area: {
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
stroke: {
|
||||||
|
1: '#9ACDFF99',
|
||||||
|
11: '#FF535399',
|
||||||
|
12: '#0DBB8A99',
|
||||||
|
13: '#e61e4aad',
|
||||||
|
14: '#FFD70099'
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
1: '#9ACDFF33',
|
||||||
|
11: '#FF9A9A33',
|
||||||
|
12: '#0DBB8A33',
|
||||||
|
13: '#e61e4a33',
|
||||||
|
14: '#FFD70033'
|
||||||
|
},
|
||||||
|
// 边框配置
|
||||||
|
border: {
|
||||||
|
width: 1, // 默认边框宽度
|
||||||
|
opacity: 0.15, // 默认边框透明度 15%
|
||||||
|
colors: {
|
||||||
|
1: '#1890FF',
|
||||||
|
11: '#FF4D4F',
|
||||||
|
12: '#52C41A',
|
||||||
|
13: '#FA8C16',
|
||||||
|
14: '#722ED1'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
1: {
|
||||||
|
stroke: '#9ACDFF99',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
fill: '#9ACDFF33',
|
||||||
|
borderColor: '#1890FF',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderOpacity: 0.15
|
||||||
|
},
|
||||||
|
11: {
|
||||||
|
stroke: '#FF535399',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
fill: '#FF9A9A33',
|
||||||
|
borderColor: '#FF4D4F',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderOpacity: 0.15
|
||||||
|
},
|
||||||
|
12: {
|
||||||
|
stroke: '#0DBB8A99',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
fill: '#0DBB8A33',
|
||||||
|
borderColor: '#52C41A',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderOpacity: 0.15
|
||||||
|
},
|
||||||
|
13: {
|
||||||
|
stroke: '#e61e4aad',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
fill: '#e61e4a33',
|
||||||
|
borderColor: '#FA8C16',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderOpacity: 0.15
|
||||||
|
},
|
||||||
|
14: {
|
||||||
|
stroke: '#FFD70099',
|
||||||
|
strokeActive: '#FCC947',
|
||||||
|
fill: '#FFD70033',
|
||||||
|
borderColor: '#722ED1',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderOpacity: 0.15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
robot: {
|
||||||
|
stroke: '#01FDAF99',
|
||||||
|
fill: '#01FAAD33',
|
||||||
|
line: '#01fdaf',
|
||||||
|
strokeNormal: '#01FDAF99',
|
||||||
|
fillNormal: '#01FAAD33',
|
||||||
|
strokeWarning: '#FF851B99',
|
||||||
|
fillWarning: '#FF851B33',
|
||||||
|
strokeFault: '#FF4D4F99',
|
||||||
|
fillFault: '#FF4D4F33',
|
||||||
|
imageWidth: 42, // 机器人图片宽度 - 42像素
|
||||||
|
imageHeight: 76 // 机器人图片高度 - 76像素
|
||||||
|
},
|
||||||
|
storage: {
|
||||||
|
occupied: '#ff4d4f',
|
||||||
|
available: '#52c41a',
|
||||||
|
default: '#f5f5f5',
|
||||||
|
locked: '#faad14',
|
||||||
|
moreButton: {
|
||||||
|
background: '#e6f4ff',
|
||||||
|
border: '#1677ff',
|
||||||
|
text: '#1677ff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
autoDoor: {
|
||||||
|
strokeClosed: '#FF4D4F99',
|
||||||
|
fillClosed: '#FF4D4F33',
|
||||||
|
strokeOpen: '#1890FF99',
|
||||||
|
fillOpen: '#1890FF33'
|
||||||
|
},
|
||||||
|
common: {
|
||||||
|
color: '#BFBFBF',
|
||||||
|
background: '#2A2C2C'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 颜色配置管理服务
|
* 颜色配置管理服务
|
||||||
*/
|
*/
|
||||||
@ -372,6 +518,21 @@ class ColorConfigService {
|
|||||||
return this.config.value;
|
return this.config.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前主题的基础配置
|
||||||
|
*/
|
||||||
|
public get currentBaseConfig(): EditorColorConfig {
|
||||||
|
const isDarkTheme = sTheme.theme === 'dark';
|
||||||
|
return isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查当前是否为暗色主题
|
||||||
|
*/
|
||||||
|
public get isDarkTheme(): boolean {
|
||||||
|
return sTheme.theme === 'dark';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置编辑器服务实例
|
* 设置编辑器服务实例
|
||||||
*/
|
*/
|
||||||
@ -410,13 +571,22 @@ class ColorConfigService {
|
|||||||
const stored = localStorage.getItem(this.STORAGE_KEY);
|
const stored = localStorage.getItem(this.STORAGE_KEY);
|
||||||
if (stored) {
|
if (stored) {
|
||||||
const parsedConfig = JSON.parse(stored);
|
const parsedConfig = JSON.parse(stored);
|
||||||
this.config.value = this.mergeConfig(DEFAULT_COLORS, parsedConfig);
|
// 根据当前主题选择基础配置
|
||||||
|
const isDarkTheme = sTheme.theme === 'dark';
|
||||||
|
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||||
|
this.config.value = this.mergeConfig(baseConfig, parsedConfig);
|
||||||
} else {
|
} else {
|
||||||
this.config.value = { ...DEFAULT_COLORS };
|
// 根据当前主题选择基础配置
|
||||||
|
const isDarkTheme = sTheme.theme === 'dark';
|
||||||
|
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||||
|
this.config.value = { ...baseConfig };
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to load color config from localStorage:', error);
|
console.warn('Failed to load color config from localStorage:', error);
|
||||||
this.config.value = { ...DEFAULT_COLORS };
|
// 根据当前主题选择基础配置
|
||||||
|
const isDarkTheme = sTheme.theme === 'dark';
|
||||||
|
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||||
|
this.config.value = { ...baseConfig };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,8 +642,12 @@ class ColorConfigService {
|
|||||||
// 清除本地存储
|
// 清除本地存储
|
||||||
localStorage.removeItem(this.STORAGE_KEY);
|
localStorage.removeItem(this.STORAGE_KEY);
|
||||||
|
|
||||||
|
// 根据当前主题选择基础配置
|
||||||
|
const isDarkTheme = sTheme.theme === 'dark';
|
||||||
|
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||||
|
|
||||||
// 重置为默认配置,使用深度复制确保完全重置
|
// 重置为默认配置,使用深度复制确保完全重置
|
||||||
this.config.value = JSON.parse(JSON.stringify(DEFAULT_COLORS));
|
this.config.value = JSON.parse(JSON.stringify(baseConfig));
|
||||||
|
|
||||||
// 重置标记,允许后续自动保存
|
// 重置标记,允许后续自动保存
|
||||||
this.isResetting = false;
|
this.isResetting = false;
|
||||||
@ -598,9 +772,13 @@ class ColorConfigService {
|
|||||||
const theme = sTheme.editor as any;
|
const theme = sTheme.editor as any;
|
||||||
if (!theme) return;
|
if (!theme) return;
|
||||||
|
|
||||||
|
// 根据当前主题选择基础配置
|
||||||
|
const isDarkTheme = sTheme.theme === 'dark';
|
||||||
|
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||||
|
|
||||||
// 使用简化的主题配置映射
|
// 使用简化的主题配置映射
|
||||||
const themeConfig = this.buildThemeConfig(theme);
|
const themeConfig = this.buildThemeConfig(theme);
|
||||||
this.config.value = this.mergeConfig(DEFAULT_COLORS, themeConfig);
|
this.config.value = this.mergeConfig(baseConfig, themeConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -636,9 +814,12 @@ class ColorConfigService {
|
|||||||
if (theme.route) {
|
if (theme.route) {
|
||||||
config.route = {
|
config.route = {
|
||||||
strokeActive: theme.route.strokeActive || DEFAULT_COLORS.route.strokeActive,
|
strokeActive: theme.route.strokeActive || DEFAULT_COLORS.route.strokeActive,
|
||||||
strokeEmpty: theme.route['stroke-empty'] || DEFAULT_COLORS.route.strokeEmpty,
|
strokeNone: theme.route['stroke-0'] || DEFAULT_COLORS.route.strokeNone,
|
||||||
strokeLoaded: theme.route['stroke-loaded'] || DEFAULT_COLORS.route.strokeLoaded,
|
strokeEmpty: theme.route['stroke-1'] || theme.route['stroke-empty'] || DEFAULT_COLORS.route.strokeEmpty,
|
||||||
strokeForbidden: theme.route['stroke-forbidden'] || DEFAULT_COLORS.route.strokeForbidden,
|
strokeLoaded: theme.route['stroke-2'] || theme.route['stroke-loaded'] || DEFAULT_COLORS.route.strokeLoaded,
|
||||||
|
strokeForbidden: theme.route['stroke-10'] ||
|
||||||
|
theme.route['stroke-forbidden'] ||
|
||||||
|
DEFAULT_COLORS.route.strokeForbidden,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1875,6 +1875,9 @@ function drawLine(ctx: CanvasRenderingContext2D, pen: MapPen): void {
|
|||||||
} else {
|
} else {
|
||||||
// 根据通行类型选择颜色
|
// 根据通行类型选择颜色
|
||||||
switch (pass) {
|
switch (pass) {
|
||||||
|
case MapRoutePassType.无:
|
||||||
|
routeColor = colorConfig.getColor('route.strokeNone') || get(theme, 'route.stroke-0') || '';
|
||||||
|
break;
|
||||||
case MapRoutePassType.仅空载可通行:
|
case MapRoutePassType.仅空载可通行:
|
||||||
routeColor = colorConfig.getColor('route.strokeEmpty') || get(theme, 'route.stroke-empty') || '';
|
routeColor = colorConfig.getColor('route.strokeEmpty') || get(theme, 'route.stroke-empty') || '';
|
||||||
break;
|
break;
|
||||||
@ -1885,8 +1888,8 @@ function drawLine(ctx: CanvasRenderingContext2D, pen: MapPen): void {
|
|||||||
routeColor = colorConfig.getColor('route.strokeForbidden') || get(theme, 'route.stroke-forbidden') || '';
|
routeColor = colorConfig.getColor('route.strokeForbidden') || get(theme, 'route.stroke-forbidden') || '';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// 无限制路线使用空载路线颜色作为默认
|
// 无限制路线使用无路线颜色作为默认
|
||||||
routeColor = colorConfig.getColor('route.strokeEmpty') || get(theme, 'route.stroke-empty') || '';
|
routeColor = colorConfig.getColor('route.strokeNone') || get(theme, 'route.stroke-0') || '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user