style/图标替换,样式调整
This commit is contained in:
parent
cf439e471d
commit
63e2794dc0
|
|
@ -1,177 +0,0 @@
|
||||||
# Canvas 场景下使用 Driver.js 的指南
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
|
|
||||||
Driver.js 可以用于 Canvas 场景,但有一些限制和特殊处理方式。
|
|
||||||
|
|
||||||
## Driver.js 在 Canvas 中的限制
|
|
||||||
|
|
||||||
1. **无法直接高亮 Canvas 内部元素**:Driver.js 只能高亮 DOM 元素,而 Canvas 内部绘制的内容(如设备图标、点标记等)不是 DOM 元素,无法直接高亮。
|
|
||||||
|
|
||||||
2. **可以高亮 Canvas 元素本身**:可以高亮整个 `<canvas>` 标签,但无法精确定位到 Canvas 内部的某个绘制内容。
|
|
||||||
|
|
||||||
## 解决方案
|
|
||||||
|
|
||||||
### 方案 1:高亮整个 Canvas(最简单)
|
|
||||||
|
|
||||||
直接高亮 Canvas 元素本身,适用于引导用户了解 Canvas 区域的功能。
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
element: '.main-canvas', // 或 '.canvas-wrapper'
|
|
||||||
popover: {
|
|
||||||
title: '平面图区域',
|
|
||||||
description: '这是平面图显示区域,您可以在这里查看设备位置和状态。',
|
|
||||||
side: 'top',
|
|
||||||
align: 'center'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案 2:使用占位元素(推荐用于精确引导)
|
|
||||||
|
|
||||||
如果需要在 Canvas 内部某个特定位置进行引导,可以创建一个临时的占位 DOM 元素:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 创建占位元素
|
|
||||||
const createPlaceholder = (x, y, width, height) => {
|
|
||||||
const placeholder = document.createElement('div');
|
|
||||||
placeholder.className = 'canvas-placeholder';
|
|
||||||
placeholder.style.position = 'absolute';
|
|
||||||
placeholder.style.left = `${x}px`;
|
|
||||||
placeholder.style.top = `${y}px`;
|
|
||||||
placeholder.style.width = `${width}px`;
|
|
||||||
placeholder.style.height = `${height}px`;
|
|
||||||
placeholder.style.pointerEvents = 'none'; // 不阻挡 Canvas 交互
|
|
||||||
placeholder.style.zIndex = '1000';
|
|
||||||
document.body.appendChild(placeholder);
|
|
||||||
return placeholder;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 在引导步骤中使用
|
|
||||||
{
|
|
||||||
element: '.canvas-placeholder',
|
|
||||||
popover: {
|
|
||||||
title: '设备图标',
|
|
||||||
description: '这是设备图标的位置,在编辑模式下可以拖拽移动。',
|
|
||||||
side: 'top',
|
|
||||||
align: 'center'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案 3:使用自定义高亮(高级)
|
|
||||||
|
|
||||||
结合 Canvas 坐标计算和自定义高亮层:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 计算 Canvas 内部元素的屏幕坐标
|
|
||||||
const getCanvasElementScreenPos = (canvasElement, canvasX, canvasY, scale, offsetX, offsetY) => {
|
|
||||||
const rect = canvasElement.getBoundingClientRect();
|
|
||||||
const screenX = rect.left + (canvasX * scale + offsetX);
|
|
||||||
const screenY = rect.top + (canvasY * scale + offsetY);
|
|
||||||
return { screenX, screenY };
|
|
||||||
};
|
|
||||||
|
|
||||||
// 创建自定义高亮层
|
|
||||||
const createCustomHighlight = (x, y, width, height) => {
|
|
||||||
const highlight = document.createElement('div');
|
|
||||||
highlight.className = 'custom-canvas-highlight';
|
|
||||||
highlight.style.position = 'fixed';
|
|
||||||
highlight.style.left = `${x}px`;
|
|
||||||
highlight.style.top = `${y}px`;
|
|
||||||
highlight.style.width = `${width}px`;
|
|
||||||
highlight.style.height = `${height}px`;
|
|
||||||
highlight.style.border = '3px solid #4dabf7';
|
|
||||||
highlight.style.borderRadius = '8px';
|
|
||||||
highlight.style.boxShadow = '0 0 20px rgba(77, 171, 247, 0.5)';
|
|
||||||
highlight.style.pointerEvents = 'none';
|
|
||||||
highlight.style.zIndex = '9999';
|
|
||||||
document.body.appendChild(highlight);
|
|
||||||
return highlight;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## 实际应用示例
|
|
||||||
|
|
||||||
### 示例 1:引导 Canvas 区域
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
element: '.canvas-wrapper',
|
|
||||||
popover: {
|
|
||||||
title: '平面图区域',
|
|
||||||
description: '这是主要的平面图显示区域,所有设备都会在这里显示。',
|
|
||||||
side: 'top',
|
|
||||||
align: 'center'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 示例 2:引导 Canvas 中的特定设备(需要坐标计算)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 假设要引导一个设备,其 Canvas 坐标为 (pointX, pointY)
|
|
||||||
const guideDevice = (pointX, pointY) => {
|
|
||||||
nextTick(() => {
|
|
||||||
if (!canvasRef.value) return;
|
|
||||||
|
|
||||||
// 计算设备在屏幕上的位置
|
|
||||||
const rect = canvasRef.value.getBoundingClientRect();
|
|
||||||
const screenX = rect.left + (pointX * BL.value * scale.value + offsetX.value);
|
|
||||||
const screenY = rect.top + (pointY * BL.value * scale.value + offsetY.value);
|
|
||||||
|
|
||||||
// 创建占位元素
|
|
||||||
const placeholder = document.createElement('div');
|
|
||||||
placeholder.className = 'device-placeholder';
|
|
||||||
placeholder.style.position = 'fixed';
|
|
||||||
placeholder.style.left = `${screenX - 20}px`;
|
|
||||||
placeholder.style.top = `${screenY - 20}px`;
|
|
||||||
placeholder.style.width = '40px';
|
|
||||||
placeholder.style.height = '40px';
|
|
||||||
placeholder.style.pointerEvents = 'none';
|
|
||||||
placeholder.style.zIndex = '9999';
|
|
||||||
document.body.appendChild(placeholder);
|
|
||||||
|
|
||||||
// 使用 driver.js 高亮占位元素
|
|
||||||
driverObj.highlight({
|
|
||||||
element: '.device-placeholder',
|
|
||||||
popover: {
|
|
||||||
title: '设备图标',
|
|
||||||
description: '这是设备图标,在编辑模式下可以拖拽移动。',
|
|
||||||
side: 'bottom',
|
|
||||||
align: 'center'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 引导结束后移除占位元素
|
|
||||||
setTimeout(() => {
|
|
||||||
placeholder.remove();
|
|
||||||
}, 5000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## 当前项目中的最佳实践
|
|
||||||
|
|
||||||
在当前项目中,由于主要功能按钮(筛选、分区、编辑)都是 DOM 元素,Driver.js 可以正常工作。对于 Canvas 内部的引导,建议:
|
|
||||||
|
|
||||||
1. **引导 Canvas 容器**:高亮整个 Canvas 区域,说明整体功能
|
|
||||||
2. **引导相关操作按钮**:通过引导操作按钮(如编辑按钮)来间接引导 Canvas 功能
|
|
||||||
3. **结合文字说明**:在引导提示中详细说明 Canvas 的操作方式
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **坐标转换**:Canvas 内部坐标需要转换为屏幕坐标才能创建占位元素
|
|
||||||
2. **缩放和偏移**:需要考虑 Canvas 的缩放(scale)和偏移(offsetX, offsetY)
|
|
||||||
3. **动态更新**:如果 Canvas 内容会移动或变化,占位元素的位置也需要动态更新
|
|
||||||
4. **性能考虑**:占位元素应该及时清理,避免内存泄漏
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
Driver.js **可以**用于 Canvas 场景,但需要根据具体需求选择合适的方案:
|
|
||||||
- 简单场景:直接高亮 Canvas 元素
|
|
||||||
- 精确引导:使用占位元素或自定义高亮
|
|
||||||
- 当前项目:已有 DOM 按钮的引导已经足够,无需额外处理 Canvas 内部元素
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 6.9 KiB |
|
|
@ -8,11 +8,11 @@
|
||||||
<transition name="sidebarLogoFade">
|
<transition name="sidebarLogoFade">
|
||||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||||
<h1 v-else class="sidebar-title">{{ title }}</h1>
|
<!-- <h1 v-else class="sidebar-title">{{ title }}</h1> -->
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||||
<h1 class="sidebar-title">{{ title }}</h1>
|
<!-- <h1 class="sidebar-title">{{ title }}</h1> -->
|
||||||
</router-link>
|
</router-link>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -78,7 +78,6 @@ const getLogoTextColor = computed(() => {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-right: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& .sidebar-title {
|
& .sidebar-title {
|
||||||
|
|
|
||||||
|
|
@ -43,19 +43,19 @@ export default {
|
||||||
let data = [
|
let data = [
|
||||||
{
|
{
|
||||||
name: "正常运行数",
|
name: "正常运行数",
|
||||||
value: 268,
|
value: 3763,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "正常停止数",
|
name: "正常停止数",
|
||||||
value: 132,
|
value: 142,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "故障运行数",
|
name: "故障运行数",
|
||||||
value: 2,
|
value: 15,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "故障停止数",
|
name: "故障停止数",
|
||||||
value: 0,
|
value: 22,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
this.initChart(data);
|
this.initChart(data);
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,9 @@ export default {
|
||||||
background: url("/src/assets/beij/nrk.png");
|
background: url("/src/assets/beij/nrk.png");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
box-shadow: 0 0 15px 3px rgba(212, 234, 255, 0.2),
|
||||||
|
0 0 30px 10px rgba(212, 234, 255, 0.1),
|
||||||
|
0 0 50px 15px rgba(212, 234, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog__wrapper {
|
.el-dialog__wrapper {
|
||||||
|
|
@ -450,6 +453,7 @@ export default {
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
|
min-width: 475px;
|
||||||
height: 95%;
|
height: 95%;
|
||||||
padding: 0.5% 0.3% 0% 0%;
|
padding: 0.5% 0.3% 0% 0%;
|
||||||
background: url(../../assets/beij/left.png) no-repeat;
|
background: url(../../assets/beij/left.png) no-repeat;
|
||||||
|
|
@ -532,6 +536,7 @@ export default {
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
|
min-width: 475px;
|
||||||
height: 95%;
|
height: 95%;
|
||||||
padding: 0.5% 0.3% 0% 0%;
|
padding: 0.5% 0.3% 0% 0%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
@ -785,6 +790,10 @@ export default {
|
||||||
}
|
}
|
||||||
.remark-content {
|
.remark-content {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: start;
|
||||||
|
line-height: 28px;
|
||||||
}
|
}
|
||||||
.close-btn {
|
.close-btn {
|
||||||
background: #d4eaff50;
|
background: #d4eaff50;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue