feat: 统一颜色变量
This commit is contained in:
parent
bb5a972111
commit
6ff7945336
@ -24,7 +24,7 @@ export const conf = {
|
|||||||
text: '进度条信息提示...', // hover的时候展示文案,可以为空
|
text: '进度条信息提示...', // hover的时候展示文案,可以为空
|
||||||
duration: 1, // 展示时间跨度,单位为s
|
duration: 1, // 展示时间跨度,单位为s
|
||||||
style: { // 指定样式
|
style: { // 指定样式
|
||||||
backgroundColor: 'white'
|
backgroundColor: 'var(--color-player-marker)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -41,9 +41,9 @@ export const conf = {
|
|||||||
i18n: [], // 使用默认的中文
|
i18n: [], // 使用默认的中文
|
||||||
// 自定义一些颜色
|
// 自定义一些颜色
|
||||||
commonStyle: {
|
commonStyle: {
|
||||||
progressColor: 'green', // 整个进度条颜色
|
progressColor: 'var(--color-player-progress)', // 整个进度条颜色
|
||||||
playedColor: 'chocolate', // 已播放的进度条颜色
|
playedColor: 'var(--color-player-played-progress)', // 已播放的进度条颜色
|
||||||
volumeColor: 'pink', // 音量大小竖向滑块颜色
|
volumeColor: 'var(--color-player-volume)', // 音量大小竖向滑块颜色
|
||||||
},
|
},
|
||||||
controls: true, // 是否使用底部控制栏,默认使用
|
controls: true, // 是否使用底部控制栏,默认使用
|
||||||
miniprogress: true, // 是否使用mini进度条(当底部控制栏隐藏时生效)
|
miniprogress: true, // 是否使用mini进度条(当底部控制栏隐藏时生效)
|
||||||
|
|||||||
@ -53,6 +53,7 @@ const init = () => {
|
|||||||
.player_container {
|
.player_container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: $color-background-base;
|
||||||
|
|
||||||
.xgplayer {
|
.xgplayer {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import './style.css'
|
import './style.scss'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
* {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,body, #app {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
39
src/style.scss
Normal file
39
src/style.scss
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
:root {
|
||||||
|
--color-background-base: #{$color-background-base};
|
||||||
|
--color-connection-card: #{$color-connection-card};
|
||||||
|
--color-canvas-grid-line: #{$color-canvas-grid-line};
|
||||||
|
--color-canvas-area-fill: #{$color-canvas-area-fill};
|
||||||
|
--color-canvas-area-border: #{$color-canvas-area-border};
|
||||||
|
--color-canvas-line-default: #{$color-canvas-line-default};
|
||||||
|
--color-canvas-line-forbidden: #{$color-canvas-line-forbidden};
|
||||||
|
--color-canvas-line-virtual: #{$color-canvas-line-virtual};
|
||||||
|
--color-canvas-route: #{$color-canvas-route};
|
||||||
|
--color-canvas-route-arrow: #{$color-canvas-route-arrow};
|
||||||
|
--color-canvas-curve: #{$color-canvas-curve};
|
||||||
|
--color-canvas-curve-arrow: #{$color-canvas-curve-arrow};
|
||||||
|
--color-canvas-curve-marker: #{$color-canvas-curve-marker};
|
||||||
|
--color-canvas-landmark: #{$color-canvas-landmark};
|
||||||
|
--color-canvas-charging-point: #{$color-canvas-charging-point};
|
||||||
|
--color-canvas-loading-point: #{$color-canvas-loading-point};
|
||||||
|
--color-canvas-workstation: #{$color-canvas-workstation};
|
||||||
|
--color-canvas-tooltip-title: #{$color-canvas-tooltip-title};
|
||||||
|
--color-canvas-boundary: #{$color-canvas-boundary};
|
||||||
|
--color-canvas-robot: #{$color-canvas-robot};
|
||||||
|
--color-canvas-robot-label: #{$color-canvas-robot-label};
|
||||||
|
--color-player-marker: #{$color-player-marker};
|
||||||
|
--color-player-progress: #{$color-player-progress};
|
||||||
|
--color-player-played-progress: #{$color-player-played-progress};
|
||||||
|
--color-player-volume: #{$color-player-volume};
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#app {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
@ -1,42 +1,96 @@
|
|||||||
// 全局自定义变量
|
// Dark application theme
|
||||||
$primary: #409eff;
|
$color-background-base: #070c11;
|
||||||
|
$color-background-panel: #0b1218;
|
||||||
|
$color-background-card: #101a21;
|
||||||
|
$color-background-card-hover: #16252d;
|
||||||
|
$color-background-header-translucent: rgba(11, 18, 24, 0.92);
|
||||||
|
$color-background-tooltip-translucent: rgba(11, 18, 24, 0.96);
|
||||||
|
|
||||||
$text: #c0cfdf;
|
$color-text-primary: #c8d9e2;
|
||||||
$text-dim: #475a72;
|
$color-text-secondary: #86a7b5;
|
||||||
$text-bright:#e8f0f8;
|
$color-text-bright: #edf9fc;
|
||||||
$text-gray: #666;
|
$color-text-accent-soft: #b4eaf4;
|
||||||
|
$color-text-accent-bright: #d2f4fa;
|
||||||
|
$color-text-navigation: #a8cbd5;
|
||||||
|
$color-text-navigation-active: #effcff;
|
||||||
|
$color-text-tooltip: #9db9c3;
|
||||||
|
|
||||||
$bg-deep: #060a12;
|
$color-accent-primary: #66d9f7;
|
||||||
$bg-body: #0a0f1a;
|
$color-accent-secondary: #8ee7f9;
|
||||||
$bg-card: #0f1628;
|
$color-accent-border: rgba(102, 217, 247, 0.14);
|
||||||
$bg-card-hi: #141d32;
|
$color-accent-border-strong: rgba(102, 217, 247, 0.34);
|
||||||
$border: rgba(0,195,255,0.08);
|
$color-accent-glow: rgba(102, 217, 247, 0.18);
|
||||||
$border-hi: rgba(0,195,255,0.22);
|
$color-accent-subtle: rgba(102, 217, 247, 0.07);
|
||||||
$accent: #00c3ff;
|
$color-accent-soft: rgba(102, 217, 247, 0.10);
|
||||||
$accent-dim: rgba(0,195,255,0.14);
|
$color-accent-medium: rgba(102, 217, 247, 0.12);
|
||||||
$danger: #ff2d55;
|
$color-accent-selected: rgba(102, 217, 247, 0.16);
|
||||||
$success: #00e676;
|
$color-accent-border-muted: rgba(102, 217, 247, 0.20);
|
||||||
|
$color-accent-border-header: rgba(102, 217, 247, 0.30);
|
||||||
|
$color-accent-border-hover: rgba(102, 217, 247, 0.42);
|
||||||
|
$color-accent-border-active: rgba(142, 231, 249, 0.72);
|
||||||
|
$color-accent-text-muted: rgba(142, 231, 249, 0.42);
|
||||||
|
$color-accent-radial-glow: rgba(102, 217, 247, 0.09);
|
||||||
|
$color-accent-inset-glow: rgba(102, 217, 247, 0.06);
|
||||||
|
$color-accent-tag-background: rgba(102, 217, 247, 0.08);
|
||||||
|
$color-accent-core-background: rgba(102, 217, 247, 0.03);
|
||||||
|
$color-accent-slider-glow: rgba(102, 217, 247, 0.35);
|
||||||
|
|
||||||
$font-h: 'Rajdhani', sans-serif;
|
$color-danger: #ff2d55;
|
||||||
$font-b: 'Noto Sans SC', 'PingFang SC', sans-serif;
|
$color-danger-background: rgba(255, 45, 85, 0.06);
|
||||||
$font-m: 'JetBrains Mono', monospace;
|
$color-danger-background-hover: rgba(255, 45, 85, 0.14);
|
||||||
$radius: 10px;
|
$color-success: #00e676;
|
||||||
$topbar-bg: #1e2a3a;
|
$color-axis-x: #f87171;
|
||||||
$topbar-text: #a8b2c7;
|
$color-axis-x-background: rgba(248, 113, 113, 0.15);
|
||||||
$transition: 0.25s ease;
|
$color-axis-x-border: rgba(248, 113, 113, 0.30);
|
||||||
$shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
$color-axis-y: #34d399;
|
||||||
$text-secondary: #606266;
|
$color-axis-y-background: rgba(52, 211, 153, 0.15);
|
||||||
$border-light: #f0f2f5;
|
$color-axis-y-border: rgba(52, 211, 153, 0.30);
|
||||||
$text-primary: #2c3e50;
|
$color-axis-z: #38bdf8;
|
||||||
$text-muted: #909399;
|
$color-axis-z-background: rgba(56, 189, 248, 0.15);
|
||||||
$radius-sm: 6px;
|
$color-axis-z-border: rgba(56, 189, 248, 0.30);
|
||||||
$primary-dark: #337ecc;
|
|
||||||
$border-color: #e4e7ed;
|
|
||||||
|
|
||||||
|
$color-white-subtle: rgba(255, 255, 255, 0.02);
|
||||||
|
$color-white-muted: rgba(255, 255, 255, 0.05);
|
||||||
|
$color-shadow-soft: rgba(0, 0, 0, 0.06);
|
||||||
|
$color-shadow-header: rgba(0, 0, 0, 0.22);
|
||||||
|
$color-shadow-tooltip: rgba(0, 0, 0, 0.50);
|
||||||
|
|
||||||
// 自定义混合
|
// Connection page
|
||||||
@mixin flex-center {
|
$color-connection-card: #ffffff;
|
||||||
display: flex;
|
$color-connection-title: #000000;
|
||||||
align-items: center;
|
$color-connection-text-muted: #8f8f8f;
|
||||||
justify-content: center;
|
$color-connection-primary: #003af7;
|
||||||
}
|
$color-connection-tip-background: #b7c5f3;
|
||||||
|
|
||||||
|
// Canvas and 3D visualization
|
||||||
|
$color-canvas-grid-line: rgba(30, 50, 80, 0.25);
|
||||||
|
$color-canvas-area-fill: rgba(224, 64, 251, 0.12);
|
||||||
|
$color-canvas-area-border: rgba(224, 64, 251, 0.50);
|
||||||
|
$color-canvas-line-default: #ff6e40;
|
||||||
|
$color-canvas-line-forbidden: #ff1744;
|
||||||
|
$color-canvas-line-virtual: #ffab40;
|
||||||
|
$color-canvas-route: #00e5ff;
|
||||||
|
$color-canvas-route-arrow: rgba(0, 229, 255, 0.60);
|
||||||
|
$color-canvas-curve: #76ff03;
|
||||||
|
$color-canvas-curve-arrow: rgba(118, 255, 3, 0.70);
|
||||||
|
$color-canvas-curve-marker: rgba(118, 255, 3, 0.25);
|
||||||
|
$color-canvas-landmark: #ffd600;
|
||||||
|
$color-canvas-charging-point: #22c55e;
|
||||||
|
$color-canvas-loading-point: #3b82f6;
|
||||||
|
$color-canvas-workstation: #a855f7;
|
||||||
|
$color-canvas-tooltip-title: #00e5a0;
|
||||||
|
$color-canvas-boundary: rgba(0, 229, 160, 0.10);
|
||||||
|
$color-canvas-robot: #00d4ff;
|
||||||
|
$color-canvas-robot-label: #a0c0f0;
|
||||||
|
|
||||||
|
// Video player controls
|
||||||
|
$color-player-marker: #ffffff;
|
||||||
|
$color-player-progress: #008000;
|
||||||
|
$color-player-played-progress: #d2691e;
|
||||||
|
$color-player-volume: #ffc0cb;
|
||||||
|
|
||||||
|
$font-family-heading: 'Rajdhani', sans-serif;
|
||||||
|
$font-family-body: 'Noto Sans SC', 'PingFang SC', sans-serif;
|
||||||
|
$font-family-monospace: 'JetBrains Mono', monospace;
|
||||||
|
|
||||||
|
$shadow-input: 0 2px 12px $color-shadow-soft;
|
||||||
|
|||||||
2
src/utils/themeColors.js
Normal file
2
src/utils/themeColors.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const getThemeColor = (propertyName) =>
|
||||||
|
getComputedStyle(document.documentElement).getPropertyValue(propertyName).trim()
|
||||||
@ -99,20 +99,20 @@ const testConnect = async () => {
|
|||||||
.card {
|
.card {
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: #fff;
|
background: $color-connection-card;
|
||||||
width: 600px;
|
width: 600px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #000;
|
color: $color-connection-title;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondaryTitle {
|
.secondaryTitle {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: #8f8f8f;
|
color: $color-connection-text-muted;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +120,8 @@ const testConnect = async () => {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
color: #003af7;
|
color: $color-connection-primary;
|
||||||
background: #b7c5f3;
|
background: $color-connection-tip-background;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
@ -135,8 +135,8 @@ const testConnect = async () => {
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 20px;
|
padding: 4px 20px;
|
||||||
color: #fff;
|
color: $color-connection-card;
|
||||||
background: #003af7;
|
background: $color-connection-primary;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
@ -144,9 +144,9 @@ const testConnect = async () => {
|
|||||||
.error-tips {
|
.error-tips {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #8f8f8f;
|
color: $color-connection-text-muted;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -96,14 +96,18 @@ onUnmounted(() => {
|
|||||||
.common-layout {
|
.common-layout {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: $color-background-base;
|
||||||
|
color: $color-text-primary;
|
||||||
|
|
||||||
.el-container {
|
.el-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #000d2e;
|
background: radial-gradient(circle at 50% -20%, $color-accent-radial-glow, transparent 38%), $color-background-base;
|
||||||
|
|
||||||
.el-header {
|
.el-header {
|
||||||
border-bottom: 1px solid #00c2ff4d;
|
background: $color-background-header-translucent;
|
||||||
|
border-bottom: 1px solid $color-accent-border-header;
|
||||||
|
box-shadow: 0 6px 24px $color-shadow-header;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-container {
|
.header-container {
|
||||||
@ -116,7 +120,7 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: #00c2ff;
|
color: $color-accent-secondary;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +134,7 @@ onUnmounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
color: #00c2ff;
|
color: $color-text-accent-soft;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
@ -149,7 +153,8 @@ onUnmounted(() => {
|
|||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #00c2ff;
|
color: $color-text-accent-bright;
|
||||||
|
text-shadow: 0 0 18px $color-accent-border-strong;
|
||||||
letter-spacing: 4px;
|
letter-spacing: 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -166,22 +171,28 @@ onUnmounted(() => {
|
|||||||
gap: 12px ;
|
gap: 12px ;
|
||||||
|
|
||||||
.nav-btn {
|
.nav-btn {
|
||||||
background: #003c8c80;
|
background: $color-accent-subtle;
|
||||||
border: 1px solid rgba(0, 194, 255, 0.35);
|
border: 1px solid $color-accent-border-muted;
|
||||||
color: #a0d8f0;
|
color: $color-text-navigation;
|
||||||
padding: 6px 20px;
|
padding: 6px 20px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: $color-accent-border-hover;
|
||||||
|
color: $color-text-accent-bright;
|
||||||
|
background: $color-accent-medium;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
background: rgba(0, 120, 220, 0.7);
|
background: $color-accent-selected;
|
||||||
border-color: #00c2ff;
|
border-color: $color-accent-border-active;
|
||||||
color: #fff;
|
color: $color-text-navigation-active;
|
||||||
box-shadow: 0 0 10px rgba(0, 194, 255, 0.5);
|
box-shadow: 0 0 14px $color-accent-glow, inset 0 0 12px $color-accent-inset-glow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +203,7 @@ onUnmounted(() => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-family: 'Orbitron', monospace;
|
font-family: 'Orbitron', monospace;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #00c2ff4d;
|
color: $color-accent-text-muted;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -205,4 +216,4 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -437,9 +437,9 @@ onUnmounted(() => {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.robot-teach-container {
|
.robot-teach-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: $bg-deep;
|
background: $color-background-base;
|
||||||
color: $text;
|
color: $color-text-primary;
|
||||||
font-family: $font-b;
|
font-family: $font-family-body;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
@ -455,9 +455,8 @@ onUnmounted(() => {
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// background: #030729;
|
background: $color-background-panel;
|
||||||
background: $bg-body;
|
border-right: 1px solid $color-accent-border;
|
||||||
border-right: 1px solid rgba(0, 195, 255, 0.08);
|
|
||||||
|
|
||||||
.panel-card {
|
.panel-card {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
@ -471,17 +470,16 @@ onUnmounted(() => {
|
|||||||
width: 180px;
|
width: 180px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
background: #2d323e;
|
background: $color-background-card;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.joint-list {
|
.joint-list {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
// background: #161933;
|
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: #ccc;
|
color: $color-text-primary;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@ -496,13 +494,13 @@ onUnmounted(() => {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid rgba(0, 195, 255, 0.08);
|
border: 1px solid $color-accent-border;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: #0a0b10;
|
background: $color-background-base;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #2a3f7a;
|
border-color: $color-accent-border-strong;
|
||||||
background: rgba(59, 130, 246, 0.031372549);
|
background: $color-background-card-hover;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@ -521,20 +519,20 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-input-group__prepend) {
|
:deep(.el-input-group__prepend) {
|
||||||
background: #080b10;
|
background: $color-background-base;
|
||||||
border-right: 0px;
|
border-right: 0px;
|
||||||
box-shadow: 0 0 0 1px #272727 inset;
|
box-shadow: 0 0 0 1px $color-accent-border inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-input-group__append) {
|
:deep(.el-input-group__append) {
|
||||||
background: #080b10;
|
background: $color-background-base;
|
||||||
border-left: 0px;
|
border-left: 0px;
|
||||||
box-shadow: 0 0 0 1px #272727 inset;
|
box-shadow: 0 0 0 1px $color-accent-border inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-input__wrapper) {
|
:deep(.el-input__wrapper) {
|
||||||
background-color: #0e0e0e;
|
background-color: $color-background-base;
|
||||||
box-shadow: 0 0 0 1px #272727 inset;
|
box-shadow: 0 0 0 1px $color-accent-border inset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,9 +550,8 @@ onUnmounted(() => {
|
|||||||
.right-panel {
|
.right-panel {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
// background: #030729;
|
background: $color-background-panel;
|
||||||
background: $bg-body;
|
border-left: 1px solid $color-accent-border;
|
||||||
border-left: 1px solid rgba(0, 195, 255, 0.08);
|
|
||||||
|
|
||||||
.controller {
|
.controller {
|
||||||
margin-bottom: 60px;
|
margin-bottom: 60px;
|
||||||
@ -576,14 +573,14 @@ onUnmounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 10px 14px;
|
padding: 10px 14px;
|
||||||
background: #0a0b10;
|
background: $color-background-base;
|
||||||
border: 1px solid #1c2a52;
|
border: 1px solid $color-accent-border;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #2a3f7a;
|
border-color: $color-accent-border-strong;
|
||||||
background: #3b82f608;
|
background: $color-background-card-hover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.axis-label {
|
.axis-label {
|
||||||
@ -599,21 +596,21 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.x {
|
.x {
|
||||||
background: #f8717126;
|
background: $color-axis-x-background;
|
||||||
color: #f87171;
|
color: $color-axis-x;
|
||||||
border: 1px solid #f871714d;
|
border: 1px solid $color-axis-x-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.y {
|
.y {
|
||||||
background: #34d39926;
|
background: $color-axis-y-background;
|
||||||
color: #34d399;
|
color: $color-axis-y;
|
||||||
border: 1px solid #34d3994d;
|
border: 1px solid $color-axis-y-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.z {
|
.z {
|
||||||
background: #38bdf826;
|
background: $color-axis-z-background;
|
||||||
color: #38bdf8;
|
color: $color-axis-z;
|
||||||
border: 1px solid #38bdf84d;
|
border: 1px solid $color-axis-z-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -645,15 +642,15 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
// element-plus深色输入框覆盖
|
// element-plus深色输入框覆盖
|
||||||
:deep(.el-input__wrapper) {
|
:deep(.el-input__wrapper) {
|
||||||
background-color: #2d323e;
|
background-color: $color-background-card;
|
||||||
box-shadow: $shadow;
|
box-shadow: $shadow-input;
|
||||||
|
|
||||||
.el-input__inner {
|
.el-input__inner {
|
||||||
color: #fff;
|
color: $color-text-bright;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-slider__runway) {
|
:deep(.el-slider__runway) {
|
||||||
background: #333842;
|
background: $color-accent-medium;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
|
|||||||
|
|
||||||
import { XacroAdapter } from '@/adapters/XacroAdapter.js'
|
import { XacroAdapter } from '@/adapters/XacroAdapter.js'
|
||||||
import { fileNameMap } from './config'
|
import { fileNameMap } from './config'
|
||||||
|
import { getThemeColor } from '@/utils/themeColors.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
filePath: {
|
filePath: {
|
||||||
@ -40,7 +41,7 @@ const initScene = () => {
|
|||||||
const height = container.clientHeight || 600;
|
const height = container.clientHeight || 600;
|
||||||
|
|
||||||
scene = new THREE.Scene();
|
scene = new THREE.Scene();
|
||||||
scene.background = new THREE.Color('#060a12');
|
scene.background = new THREE.Color(getThemeColor('--color-background-base'));
|
||||||
|
|
||||||
camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 1000);
|
camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 1000);
|
||||||
camera.position.set(0, 0, 4);
|
camera.position.set(0, 0, 4);
|
||||||
@ -210,7 +211,7 @@ defineExpose({ updateJoint, resetJoints, jointControls });
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #0d0d1a;
|
background: $color-background-base;
|
||||||
|
|
||||||
.viewer-container {
|
.viewer-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -227,4 +228,4 @@ defineExpose({ updateJoint, resetJoints, jointControls });
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -10,5 +10,6 @@ import IPlayer from '@/components/IPlayer/index.vue'
|
|||||||
.page-container {
|
.page-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: $color-background-base;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -13,14 +13,14 @@
|
|||||||
</span>
|
</span>
|
||||||
<div class="map-controller">
|
<div class="map-controller">
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<el-icon :size="16" color="#00D4FF" @click="zoomCanvas(true)"><zoom-out /></el-icon>
|
<el-icon :size="16" class="map-action-icon" @click="zoomCanvas(true)"><zoom-out /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<el-icon :size="16" color="#00D4FF" @click="zoomCanvas(false)"><zoom-in /></el-icon>
|
<el-icon :size="16" class="map-action-icon" @click="zoomCanvas(false)"><zoom-in /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<!-- @click="centerCanvasView" -->
|
<!-- @click="centerCanvasView" -->
|
||||||
<el-icon :size="16" color="#00D4FF" ><Location /></el-icon>
|
<el-icon :size="16" class="map-action-icon"><Location /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -207,9 +207,9 @@ function onRelease() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: #030729;
|
background: $color-background-base;
|
||||||
color: $text;
|
color: $color-text-primary;
|
||||||
font-family: $font-b;
|
font-family: $font-family-body;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ function onRelease() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-right: 1px solid $border;
|
border-right: 1px solid $color-accent-border;
|
||||||
|
|
||||||
.area-bar {
|
.area-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -232,19 +232,19 @@ function onRelease() {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
background: #030729;
|
background: $color-background-panel;
|
||||||
border-bottom: 1px solid $border;
|
border-bottom: 1px solid $color-accent-border;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
font-family: $font-h;
|
font-family: $font-family-heading;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 1.5px;
|
letter-spacing: 1.5px;
|
||||||
color: $text-dim;
|
color: $color-text-secondary;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,14 +267,14 @@ function onRelease() {
|
|||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #1E3A5F;
|
background: $color-accent-soft;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #00D4FF;
|
border-color: $color-accent-primary;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,13 +282,13 @@ function onRelease() {
|
|||||||
|
|
||||||
:deep(.el-button) {
|
:deep(.el-button) {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: $text-dim;
|
color: $color-text-secondary;
|
||||||
border-color: $border;
|
border-color: $color-accent-border;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $accent;
|
color: $color-accent-primary;
|
||||||
border-color: $border-hi;
|
border-color: $color-accent-border-strong;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ function onRelease() {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: $bg-deep;
|
background: $color-background-base;
|
||||||
|
|
||||||
// canvas {
|
// canvas {
|
||||||
// position: absolute;
|
// position: absolute;
|
||||||
@ -313,11 +313,11 @@ function onRelease() {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
background: $bg-body;
|
background: $color-background-panel;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
padding: 18px 20px;
|
padding: 18px 20px;
|
||||||
border-bottom: 1px solid $border;
|
border-bottom: 1px solid $color-accent-border;
|
||||||
|
|
||||||
&__head {
|
&__head {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -326,11 +326,11 @@ function onRelease() {
|
|||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-family: $font-h;
|
font-family: $font-family-heading;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 1.2px;
|
letter-spacing: 1.2px;
|
||||||
color: $text-dim;
|
color: $color-text-secondary;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
@ -339,9 +339,9 @@ function onRelease() {
|
|||||||
:deep(.el-tag) {
|
:deep(.el-tag) {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
background: rgba(0,195,255,0.08);
|
background: $color-accent-tag-background;
|
||||||
border-color: $border;
|
border-color: $color-accent-border;
|
||||||
color: $accent;
|
color: $color-accent-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dpad {
|
.dpad {
|
||||||
@ -358,10 +358,10 @@ function onRelease() {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
border: 1px solid $border;
|
border: 1px solid $color-accent-border;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: $bg-card;
|
background: $color-background-card;
|
||||||
color: $text;
|
color: $color-text-primary;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all .15s ease;
|
transition: all .15s ease;
|
||||||
|
|
||||||
@ -373,24 +373,24 @@ function onRelease() {
|
|||||||
small {
|
small {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
letter-spacing: .5px;
|
letter-spacing: .5px;
|
||||||
color: $text-dim;
|
color: $color-text-secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: $border-hi;
|
border-color: $color-accent-border-strong;
|
||||||
background: $bg-card-hi;
|
background: $color-background-card-hover;
|
||||||
color: $accent;
|
color: $color-accent-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
background: $accent;
|
background: $color-accent-primary;
|
||||||
color: $bg-deep;
|
color: $color-background-base;
|
||||||
border-color: $accent;
|
border-color: $color-accent-primary;
|
||||||
box-shadow: 0 0 24px $accent-dim;
|
box-shadow: 0 0 24px $color-accent-glow;
|
||||||
transform: scale(.94);
|
transform: scale(.94);
|
||||||
|
|
||||||
small {
|
small {
|
||||||
color: $bg-deep;
|
color: $color-background-base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,15 +421,15 @@ function onRelease() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 1px solid $border;
|
border: 1px solid $color-accent-border;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: rgba(0,195,255,0.03);
|
background: $color-accent-core-background;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: $accent;
|
background: $color-accent-primary;
|
||||||
opacity: .3;
|
opacity: .3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,12 +441,12 @@ function onRelease() {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
border-color: $danger !important;
|
border-color: $color-danger !important;
|
||||||
color: $danger !important;
|
color: $color-danger !important;
|
||||||
background: rgba(255,45,85,0.06) !important;
|
background: $color-danger-background !important;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba(255,45,85,0.14) !important;
|
background: $color-danger-background-hover !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,25 +463,25 @@ function onRelease() {
|
|||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: $text-dim;
|
color: $color-text-secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__val {
|
&__val {
|
||||||
font-family: $font-m;
|
font-family: $font-family-monospace;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: $accent;
|
color: $color-accent-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-slider) {
|
:deep(.el-slider) {
|
||||||
.el-slider__runway {
|
.el-slider__runway {
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: rgba(255,255,255,0.05);
|
background: $color-white-muted;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
.el-slider__bar {
|
.el-slider__bar {
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: $accent;
|
background: $color-accent-primary;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
.el-slider__button-wrapper {
|
.el-slider__button-wrapper {
|
||||||
@ -490,13 +490,13 @@ function onRelease() {
|
|||||||
.el-slider__button {
|
.el-slider__button {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
border: 2px solid $accent;
|
border: 2px solid $color-accent-primary;
|
||||||
background: $bg-deep;
|
background: $color-background-base;
|
||||||
box-shadow: 0 0 8px $accent-dim;
|
box-shadow: 0 0 8px $color-accent-glow;
|
||||||
transition: box-shadow .2s;
|
transition: box-shadow .2s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 0 14px rgba(0,195,255,0.35);
|
box-shadow: 0 0 14px $color-accent-slider-glow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,8 +511,8 @@ function onRelease() {
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
background: $bg-card;
|
background: $color-background-card;
|
||||||
border-top: 1px solid $border;
|
border-top: 1px solid $color-accent-border;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
.chip {
|
.chip {
|
||||||
@ -521,27 +521,31 @@ function onRelease() {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 3px 12px;
|
padding: 3px 12px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(255,255,255,0.02);
|
background: $color-white-subtle;
|
||||||
border: 1px solid $border;
|
border: 1px solid $color-accent-border;
|
||||||
|
|
||||||
&__label {
|
&__label {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
color: $text-dim;
|
color: $color-text-secondary;
|
||||||
letter-spacing: .5px;
|
letter-spacing: .5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__val {
|
&__val {
|
||||||
font-family: $font-m;
|
font-family: $font-family-monospace;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: $text-bright;
|
color: $color-text-bright;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
&--ok {
|
&--ok {
|
||||||
color: $success;
|
color: $color-success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
.map-action-icon {
|
||||||
|
color: $color-canvas-robot;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import {
|
|||||||
import { getCurrentMap, getRobotState } from '@/api/agv.js'
|
import { getCurrentMap, getRobotState } from '@/api/agv.js'
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { useRobotStore } from '@/stores/robot'
|
import { useRobotStore } from '@/stores/robot'
|
||||||
|
import { getThemeColor } from '@/utils/themeColors.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
mapName: {
|
mapName: {
|
||||||
@ -223,7 +224,7 @@ function renderFrame(timestamp) {
|
|||||||
drawAdvancedAreaList(canvasCtx, map, applicationState)
|
drawAdvancedAreaList(canvasCtx, map, applicationState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 图层4: normalLineList(基础直线,青色 #00e5ff)
|
// 图层4: normalLineList(基础青色直线)
|
||||||
if (layers.normalLines) {
|
if (layers.normalLines) {
|
||||||
drawNormalLines(canvasCtx, map, applicationState);
|
drawNormalLines(canvasCtx, map, applicationState);
|
||||||
}
|
}
|
||||||
@ -233,7 +234,7 @@ function renderFrame(timestamp) {
|
|||||||
drawAdvancedLineList(canvasCtx, map, applicationState);
|
drawAdvancedLineList(canvasCtx, map, applicationState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 图层6: advancedCurveList(贝塞尔曲线路径,酸绿色 #76ff03)
|
// 图层6: advancedCurveList(酸绿色贝塞尔曲线路径)
|
||||||
if (layers.curves) {
|
if (layers.curves) {
|
||||||
drawAdvancedCurveList(canvasCtx, map, applicationState);
|
drawAdvancedCurveList(canvasCtx, map, applicationState);
|
||||||
}
|
}
|
||||||
@ -345,7 +346,7 @@ const updateTooltipDisplay = (hitResult) => {
|
|||||||
<div class="tooltip-detail">朝向: ${(robot.angle * 180 / Math.PI).toFixed(1)}°</div>
|
<div class="tooltip-detail">朝向: ${(robot.angle * 180 / Math.PI).toFixed(1)}°</div>
|
||||||
<div class="tooltip-detail">ID: ${robot.id}</div>`;
|
<div class="tooltip-detail">ID: ${robot.id}</div>`;
|
||||||
}
|
}
|
||||||
tooltipEl.innerHTML = `<div class="tooltip-title" style="color:#00e5a0">${title}</div>${details}`;
|
tooltipEl.innerHTML = `<div class="tooltip-title">${title}</div>${details}`;
|
||||||
tooltipEl.style.display = 'block';
|
tooltipEl.style.display = 'block';
|
||||||
tooltipEl.style.left = Math.min(applicationState.mouseState.screenX + 14, applicationState.canvasWidthPx - 220) + 'px';
|
tooltipEl.style.left = Math.min(applicationState.mouseState.screenX + 14, applicationState.canvasWidthPx - 220) + 'px';
|
||||||
tooltipEl.style.top = Math.max(4, applicationState.mouseState.screenY - 8) + 'px';
|
tooltipEl.style.top = Math.max(4, applicationState.mouseState.screenY - 8) + 'px';
|
||||||
@ -424,7 +425,7 @@ watch(() => props.mapName,
|
|||||||
async (newVal) => {
|
async (newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
await loadSourceMap(newVal)
|
await loadSourceMap(newVal)
|
||||||
addRobot(robotStore.ip, robotStore.ip, robotStore.position.x, robotStore.position.y, robotStore.position.theta, '#00D4FF')
|
addRobot(robotStore.ip, robotStore.ip, robotStore.position.x, robotStore.position.y, robotStore.position.theta, getThemeColor('--color-canvas-robot'))
|
||||||
requestAnimationFrame(renderFrame);
|
requestAnimationFrame(renderFrame);
|
||||||
window.addEventListener('resize', resizeCanvasToContainer); // 监听窗口大小变化
|
window.addEventListener('resize', resizeCanvasToContainer); // 监听窗口大小变化
|
||||||
resizeCanvasToContainer(); // 初始调用一次
|
resizeCanvasToContainer(); // 初始调用一次
|
||||||
@ -454,8 +455,8 @@ onUnmounted(() => {
|
|||||||
#tooltip {
|
#tooltip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
background: #0b1120;
|
background: $color-background-tooltip-translucent;
|
||||||
border: 1px solid #2a3a5c;
|
border: 1px solid $color-accent-border-header;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@ -463,20 +464,21 @@ onUnmounted(() => {
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
min-width: 180px;
|
min-width: 180px;
|
||||||
max-width: 280px;
|
max-width: 280px;
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, .5);
|
box-shadow: 0 4px 16px $color-shadow-tooltip;
|
||||||
|
|
||||||
.tooltip-title {
|
.tooltip-title {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
color: $color-canvas-tooltip-title;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.tooltip-detail) {
|
:deep(.tooltip-detail) {
|
||||||
color: #94a3b8;
|
color: $color-text-tooltip;
|
||||||
padding: 2px 0;
|
padding: 2px 0;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
|
import { getThemeColor } from '@/utils/themeColors.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 6位十六进制颜色字符串转为 CSS rgba 字符串
|
* 6位十六进制颜色字符串转为 CSS rgba 字符串
|
||||||
* @param {string} hex - 如 "#ff6e40"
|
* @param {string} hexString - 六位十六进制颜色字符串
|
||||||
* @param {number} alpha - 透明度 0~1
|
* @param {number} alpha - 透明度 0~1
|
||||||
* @returns {string} CSS rgba 字符串
|
* @returns {string} CSS rgba 字符串
|
||||||
*/
|
*/
|
||||||
@ -61,7 +63,7 @@ export const decodeArgbInteger = (argbInt) => {
|
|||||||
* 将 decodeArgbInteger 的结果转为 CSS rgba() 字符串
|
* 将 decodeArgbInteger 的结果转为 CSS rgba() 字符串
|
||||||
* @param {{r,g,b,a}} colorObj - RGBA 分量对象
|
* @param {{r,g,b,a}} colorObj - RGBA 分量对象
|
||||||
* @param {number} [alphaOverride] - 可选,覆盖 alpha 值(0~1)
|
* @param {number} [alphaOverride] - 可选,覆盖 alpha 值(0~1)
|
||||||
* @returns {string|null} CSS rgba 字符串,如 "rgba(255,0,64,0.3)"
|
* @returns {string|null} CSS rgba 颜色字符串
|
||||||
*/
|
*/
|
||||||
export const toCssRgba = (colorObj, alphaOverride) => {
|
export const toCssRgba = (colorObj, alphaOverride) => {
|
||||||
if (!colorObj) return null; // 空对象返回 null
|
if (!colorObj) return null; // 空对象返回 null
|
||||||
@ -108,7 +110,7 @@ export const drawGridlines = (canvasCtx, dataStore) => {
|
|||||||
const viewMaxY = Math.ceil(Math.max(viewTopLeft.y, viewBottomRight.y)); // 可视Y最大整数
|
const viewMaxY = Math.ceil(Math.max(viewTopLeft.y, viewBottomRight.y)); // 可视Y最大整数
|
||||||
|
|
||||||
// 绘制1米间隔的浅色网格线
|
// 绘制1米间隔的浅色网格线
|
||||||
canvasCtx.strokeStyle = 'rgba(30,50,80,0.25)'; // 淡蓝灰色
|
canvasCtx.strokeStyle = getThemeColor('--color-canvas-grid-line');
|
||||||
canvasCtx.lineWidth = 0.5; // 细线
|
canvasCtx.lineWidth = 0.5; // 细线
|
||||||
canvasCtx.beginPath();
|
canvasCtx.beginPath();
|
||||||
for (let worldX = viewMinX; worldX <= viewMaxX; worldX++) { // 逐列绘制垂直线
|
for (let worldX = viewMinX; worldX <= viewMaxX; worldX++) { // 逐列绘制垂直线
|
||||||
@ -138,8 +140,8 @@ export const drawAdvancedAreaList = (canvasCtx, map, dataStore) => {
|
|||||||
if (vertices.length < 3) continue; // 少于3个顶点无法构成多边形,跳过
|
if (vertices.length < 3) continue; // 少于3个顶点无法构成多边形,跳过
|
||||||
|
|
||||||
// ── 颜色:优先使用 attribute 中的 ARGB 整数,否则用默认品红色 ──
|
// ── 颜色:优先使用 attribute 中的 ARGB 整数,否则用默认品红色 ──
|
||||||
let fillColorCss = 'rgba(224,64,251,0.12)'; // 默认填充(品红半透明)
|
let fillColorCss = getThemeColor('--color-canvas-area-fill');
|
||||||
let strokeColorCss = 'rgba(224,64,251,0.5)'; // 默认描边(品红较不透明)
|
let strokeColorCss = getThemeColor('--color-canvas-area-border');
|
||||||
if (area.attribute) {
|
if (area.attribute) {
|
||||||
const brushColor = decodeArgbInteger(area.attribute.colorBrush); // 解码填充色
|
const brushColor = decodeArgbInteger(area.attribute.colorBrush); // 解码填充色
|
||||||
const penColor = decodeArgbInteger(area.attribute.colorPen); // 解码描边色
|
const penColor = decodeArgbInteger(area.attribute.colorPen); // 解码描边色
|
||||||
@ -196,14 +198,14 @@ export const drawAdvancedLineList = (canvasCtx, map, dataStore) => {
|
|||||||
const endScreen = worldToScreen(lineData.endPos.x, lineData.endPos.y, store);
|
const endScreen = worldToScreen(lineData.endPos.x, lineData.endPos.y, store);
|
||||||
|
|
||||||
// ── 根据 className 决定颜色和线型 ──
|
// ── 根据 className 决定颜色和线型 ──
|
||||||
let lineColorHex = '#ff6e40'; // 默认橙色
|
let lineColorHex = getThemeColor('--color-canvas-line-default');
|
||||||
let lineDashPattern = []; // 默认实线(无虚线)
|
let lineDashPattern = []; // 默认实线(无虚线)
|
||||||
const classNameLower = (advLine.className || '').toLowerCase();
|
const classNameLower = (advLine.className || '').toLowerCase();
|
||||||
if (classNameLower.includes('forbidden')) { // 禁行线 → 红色虚线
|
if (classNameLower.includes('forbidden')) { // 禁行线 → 红色虚线
|
||||||
lineColorHex = '#ff1744';
|
lineColorHex = getThemeColor('--color-canvas-line-forbidden');
|
||||||
lineDashPattern = [8, 4]; // 虚线模式:8px实 4px空
|
lineDashPattern = [8, 4]; // 虚线模式:8px实 4px空
|
||||||
} else if (classNameLower.includes('virtual')) { // 虚拟线 → 橙色虚线
|
} else if (classNameLower.includes('virtual')) { // 虚拟线 → 橙色虚线
|
||||||
lineColorHex = '#ffab40';
|
lineColorHex = getThemeColor('--color-canvas-line-virtual');
|
||||||
lineDashPattern = [4, 4];
|
lineDashPattern = [4, 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,9 +249,9 @@ export const drawNormalLines = (canvasCtx, map, dataStore) => {
|
|||||||
|
|
||||||
// 绘制发光直线
|
// 绘制发光直线
|
||||||
canvasCtx.save();
|
canvasCtx.save();
|
||||||
canvasCtx.shadowColor = '#00e5ff'; // 阴影颜色(产生辉光)
|
canvasCtx.shadowColor = getThemeColor('--color-canvas-route');
|
||||||
canvasCtx.shadowBlur = 5; // 辉光扩散半径
|
canvasCtx.shadowBlur = 5; // 辉光扩散半径
|
||||||
canvasCtx.strokeStyle = '#00e5ff'; // 线条颜色:青色
|
canvasCtx.strokeStyle = getThemeColor('--color-canvas-route');
|
||||||
canvasCtx.lineWidth = 2; // 线宽
|
canvasCtx.lineWidth = 2; // 线宽
|
||||||
canvasCtx.globalAlpha = 0.8; // 80%不透明
|
canvasCtx.globalAlpha = 0.8; // 80%不透明
|
||||||
canvasCtx.beginPath();
|
canvasCtx.beginPath();
|
||||||
@ -263,7 +265,7 @@ export const drawNormalLines = (canvasCtx, map, dataStore) => {
|
|||||||
const midpointY = (startScreen.y + endScreen.y) / 2; // 中点Y
|
const midpointY = (startScreen.y + endScreen.y) / 2; // 中点Y
|
||||||
const arrowAngle = Math.atan2(endScreen.y - startScreen.y, endScreen.x - startScreen.x); // 线段方向角
|
const arrowAngle = Math.atan2(endScreen.y - startScreen.y, endScreen.x - startScreen.x); // 线段方向角
|
||||||
const arrowLength = 5; // 箭头长度
|
const arrowLength = 5; // 箭头长度
|
||||||
canvasCtx.fillStyle = 'rgba(0,229,255,0.6)'; // 箭头填充色
|
canvasCtx.fillStyle = getThemeColor('--color-canvas-route-arrow');
|
||||||
canvasCtx.beginPath();
|
canvasCtx.beginPath();
|
||||||
canvasCtx.moveTo(midpointX + Math.cos(arrowAngle) * arrowLength, midpointY + Math.sin(arrowAngle) * arrowLength); // 箭头尖端
|
canvasCtx.moveTo(midpointX + Math.cos(arrowAngle) * arrowLength, midpointY + Math.sin(arrowAngle) * arrowLength); // 箭头尖端
|
||||||
canvasCtx.lineTo(midpointX + Math.cos(arrowAngle + 2.5) * 4, midpointY + Math.sin(arrowAngle + 2.5) * 4); // 左翼
|
canvasCtx.lineTo(midpointX + Math.cos(arrowAngle + 2.5) * 4, midpointY + Math.sin(arrowAngle + 2.5) * 4); // 左翼
|
||||||
@ -299,9 +301,9 @@ export const drawAdvancedCurveList = (canvasCtx, map, dataStore) => {
|
|||||||
|
|
||||||
// ── 绘制贝塞尔曲线(虚线)──
|
// ── 绘制贝塞尔曲线(虚线)──
|
||||||
canvasCtx.save();
|
canvasCtx.save();
|
||||||
canvasCtx.shadowColor = '#76ff03'; // 酸绿色辉光
|
canvasCtx.shadowColor = getThemeColor('--color-canvas-curve');
|
||||||
canvasCtx.shadowBlur = 5;
|
canvasCtx.shadowBlur = 5;
|
||||||
canvasCtx.strokeStyle = '#76ff03'; // 酸绿色线条
|
canvasCtx.strokeStyle = getThemeColor('--color-canvas-curve');
|
||||||
canvasCtx.lineWidth = 2;
|
canvasCtx.lineWidth = 2;
|
||||||
canvasCtx.setLineDash([8, 5]); // 虚线模式
|
canvasCtx.setLineDash([8, 5]); // 虚线模式
|
||||||
canvasCtx.globalAlpha = 0.85;
|
canvasCtx.globalAlpha = 0.85;
|
||||||
@ -334,7 +336,7 @@ export const drawAdvancedCurveList = (canvasCtx, map, dataStore) => {
|
|||||||
const tangentAngle = Math.atan2(tangentY, tangentX); // 切线角度
|
const tangentAngle = Math.atan2(tangentY, tangentX); // 切线角度
|
||||||
|
|
||||||
// 绘制箭头
|
// 绘制箭头
|
||||||
canvasCtx.fillStyle = 'rgba(118,255,3,0.7)';
|
canvasCtx.fillStyle = getThemeColor('--color-canvas-curve-arrow');
|
||||||
canvasCtx.beginPath();
|
canvasCtx.beginPath();
|
||||||
canvasCtx.moveTo(arrowX + Math.cos(tangentAngle) * 5, arrowY + Math.sin(tangentAngle) * 5);
|
canvasCtx.moveTo(arrowX + Math.cos(tangentAngle) * 5, arrowY + Math.sin(tangentAngle) * 5);
|
||||||
canvasCtx.lineTo(arrowX + Math.cos(tangentAngle + 2.5) * 4, arrowY + Math.sin(tangentAngle + 2.5) * 4);
|
canvasCtx.lineTo(arrowX + Math.cos(tangentAngle + 2.5) * 4, arrowY + Math.sin(tangentAngle + 2.5) * 4);
|
||||||
@ -343,7 +345,7 @@ export const drawAdvancedCurveList = (canvasCtx, map, dataStore) => {
|
|||||||
canvasCtx.fill();
|
canvasCtx.fill();
|
||||||
|
|
||||||
// 绘制控制点小圆(辅助调试用)
|
// 绘制控制点小圆(辅助调试用)
|
||||||
canvasCtx.fillStyle = 'rgba(118,255,3,0.25)'; // 浅绿色半透明
|
canvasCtx.fillStyle = getThemeColor('--color-canvas-curve-marker');
|
||||||
for (const controlScreen of [cp1Screen, cp2Screen]) {
|
for (const controlScreen of [cp1Screen, cp2Screen]) {
|
||||||
canvasCtx.beginPath();
|
canvasCtx.beginPath();
|
||||||
canvasCtx.arc(controlScreen.x, controlScreen.y, 2.5, 0, Math.PI * 2); // 半径2.5px的小圆
|
canvasCtx.arc(controlScreen.x, controlScreen.y, 2.5, 0, Math.PI * 2); // 半径2.5px的小圆
|
||||||
@ -353,7 +355,6 @@ export const drawAdvancedCurveList = (canvasCtx, map, dataStore) => {
|
|||||||
|
|
||||||
// ── 曲线名称标签 ──
|
// ── 曲线名称标签 ──
|
||||||
// canvasCtx.font = '500 7px "JetBrains Mono"';
|
// canvasCtx.font = '500 7px "JetBrains Mono"';
|
||||||
// canvasCtx.fillStyle = 'rgba(118,255,3,0.5)';
|
|
||||||
// canvasCtx.textAlign = 'center';
|
// canvasCtx.textAlign = 'center';
|
||||||
// const labelScreenY = Math.min(startScreen.y, endScreen.y) - 8; // 标签放在最高点上方
|
// const labelScreenY = Math.min(startScreen.y, endScreen.y) - 8; // 标签放在最高点上方
|
||||||
// canvasCtx.fillText(curve.instanceName || '', (startScreen.x + endScreen.x) / 2, labelScreenY);
|
// canvasCtx.fillText(curve.instanceName || '', (startScreen.x + endScreen.x) / 2, labelScreenY);
|
||||||
@ -378,18 +379,18 @@ export const drawAdvancedPointList = (canvasCtx, map, dataStore) => {
|
|||||||
store.hoveredElement.index === pointIndex;
|
store.hoveredElement.index === pointIndex;
|
||||||
|
|
||||||
// ── 根据 className 决定颜色 ──
|
// ── 根据 className 决定颜色 ──
|
||||||
let pointColorHex = '#ffd600'; // 默认琥珀色
|
let pointColorHex = getThemeColor('--color-canvas-landmark');
|
||||||
const classNameLower = (advPoint.className || '').toLowerCase();
|
const classNameLower = (advPoint.className || '').toLowerCase();
|
||||||
if (classNameLower.includes('landmark') || classNameLower.includes('land')) {
|
if (classNameLower.includes('landmark') || classNameLower.includes('land')) {
|
||||||
pointColorHex = '#ffd600'; // LandMark → 琥珀色
|
pointColorHex = getThemeColor('--color-canvas-landmark');
|
||||||
} else if (classNameLower.includes('charge')) {
|
} else if (classNameLower.includes('charge')) {
|
||||||
pointColorHex = '#22c55e'; // 充电点 → 绿色
|
pointColorHex = getThemeColor('--color-canvas-charging-point');
|
||||||
} else if (classNameLower.includes('load')) {
|
} else if (classNameLower.includes('load')) {
|
||||||
pointColorHex = '#3b82f6'; // 装载点 → 蓝色
|
pointColorHex = getThemeColor('--color-canvas-loading-point');
|
||||||
} else if (classNameLower.includes('work') || classNameLower.includes('process')) {
|
} else if (classNameLower.includes('work') || classNameLower.includes('process')) {
|
||||||
pointColorHex = '#a855f7'; // 工位 → 紫色
|
pointColorHex = getThemeColor('--color-canvas-workstation');
|
||||||
} else if (classNameLower.includes('station')) {
|
} else if (classNameLower.includes('station')) {
|
||||||
pointColorHex = '#00e5ff'; // 站点 → 青色
|
pointColorHex = getThemeColor('--color-canvas-route');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 绘制菱形标记 ──
|
// ── 绘制菱形标记 ──
|
||||||
@ -413,7 +414,7 @@ export const drawAdvancedPointList = (canvasCtx, map, dataStore) => {
|
|||||||
|
|
||||||
// 中心白色小圆点(指示精确位置)
|
// 中心白色小圆点(指示精确位置)
|
||||||
canvasCtx.shadowBlur = 0;
|
canvasCtx.shadowBlur = 0;
|
||||||
canvasCtx.fillStyle = '#fff';
|
canvasCtx.fillStyle = getThemeColor('--color-connection-card');
|
||||||
canvasCtx.globalAlpha = 0.9;
|
canvasCtx.globalAlpha = 0.9;
|
||||||
canvasCtx.beginPath();
|
canvasCtx.beginPath();
|
||||||
canvasCtx.arc(pointScreen.x, pointScreen.y, 1.8, 0, Math.PI * 2); // 半径1.8px
|
canvasCtx.arc(pointScreen.x, pointScreen.y, 1.8, 0, Math.PI * 2); // 半径1.8px
|
||||||
@ -457,7 +458,7 @@ export const drawMapBoundary = (canvasCtx, map, dataStore) => {
|
|||||||
const store = dataStore ;
|
const store = dataStore ;
|
||||||
const boundaryTopLeft = worldToScreen(map.originX, map.maxY, store); // 边界左上角屏幕位置
|
const boundaryTopLeft = worldToScreen(map.originX, map.maxY, store); // 边界左上角屏幕位置
|
||||||
const boundaryBottomRight = worldToScreen(map.maxX, map.originY, store); // 边界右下角屏幕位置
|
const boundaryBottomRight = worldToScreen(map.maxX, map.originY, store); // 边界右下角屏幕位置
|
||||||
canvasCtx.strokeStyle = 'rgba(0,229,160,0.1)'; // 极淡的青绿色
|
canvasCtx.strokeStyle = getThemeColor('--color-canvas-boundary');
|
||||||
canvasCtx.lineWidth = 1;
|
canvasCtx.lineWidth = 1;
|
||||||
canvasCtx.setLineDash([5, 4]); // 虚线
|
canvasCtx.setLineDash([5, 4]); // 虚线
|
||||||
canvasCtx.strokeRect(
|
canvasCtx.strokeRect(
|
||||||
@ -555,7 +556,7 @@ export const buildOccupancyGridImage = (parsedMap, showEdgeGlow) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class MobileRobot {
|
export class MobileRobot {
|
||||||
constructor(id, name, x, y, angleRad = 0, color= "#00D4FF", imageUrl = null) {
|
constructor(id, name, x, y, angleRad = 0, color = getThemeColor('--color-canvas-robot'), imageUrl = null) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.x = x; // 世界坐标X (米)
|
this.x = x; // 世界坐标X (米)
|
||||||
@ -602,7 +603,7 @@ export class MobileRobot {
|
|||||||
}
|
}
|
||||||
// 名字标签
|
// 名字标签
|
||||||
ctx.font = '12px "JetBrains Mono"';
|
ctx.font = '12px "JetBrains Mono"';
|
||||||
ctx.fillStyle = '#a0c0f0';
|
ctx.fillStyle = getThemeColor('--color-canvas-robot-label');
|
||||||
ctx.shadowBlur = 0;
|
ctx.shadowBlur = 0;
|
||||||
ctx.fillText(this.name, screenX, screenY - 20);
|
ctx.fillText(this.name, screenX, screenY - 20);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user