根据svg文本显示svg 并且支持鼠标划过显示器件名称 放大缩小拖动
整个页面Demo如下:
<template>
<div id="home">
<section id="top-section">
<label for="">svg路径:</label>
<el-input v-model="svgPath" size="small"></el-input>
<el-button type="primary" size="small" @click="loadSvgData()"
>加载</el-button
>
</section>
<article>
<div
id="svg-container"
style="width: 1300px; height: 700px; overflow: auto"
></div>
<!-- svg元件鼠标悬浮提示框 -->
<div
id="svgTipBox"
v-show="svgTipBoxVisible"
v-bind:style="{
left: svgTipBoxPositionX + 'px',
top: svgTipBoxPositionY + 'px'
}"
>
{{ svgTipBoxData }}
</div>
</article>
</div>
</template>
<script>
import axios from 'axios';
// import Hammer from 'hammerjs'; //缩放比例
import svgPanZoom from 'svg-pan-zoom';
export default {
name: 'Home',
data() {
return {
url: '',
srcList: [],
svgPath: '/svg.svg', //svg文件路径 因为是本地测试需要把svg文件放在public里面
svgData: '', //svg文件内容
svgTipBoxData: '', //svg元件鼠标悬浮提示框内容
svgTipBoxVisible: false, //svg元件鼠标悬浮提示框显示状态
svgTipBoxPositionX: 0, //svg元件鼠标悬浮提示框x坐标
svgTipBoxPositionY: 0 //svg元件鼠标悬浮提示框y坐标
};
},
// 由于svg上添加的鼠标事件无法直接调用vue里的methods方法,需要将这些方法绑定到window下面,提供给外部调用
async mounted() {
// 将svgClick方法绑定到window下面,提供给外部调用
window['handleClick'] = (evt, id) => {
this.svgClick(evt, id);
};
// 将svgMouseOver方法绑定到window下面,提供给外部调用
window['handleMouseOver'] = (evt, id) => {
this.svgMouseOver(evt, id);
};
// 将svgMouseMove方法绑定到window下面,提供给外部调用ping 20.
window['handleMouseMove'] = (evt, id) => {
this.svgMouseMove(evt, id);
};
// 将svgMouseOut方法绑定到window下面,提供给外部调用
window['handleMouseOut'] = (evt, id) => {
this.svgMouseOut(evt, id);
};
},
methods: {
//加载按钮点击
loadSvgData() {
// ajax请求数据,并携带参数
axios
.get(this.svgPath)
.then(
(response) => {
// console.log(response, 'res');
// 将svg平面图显示在制定容器中
let svgContainer = document.getElementById('svg-container');
svgContainer.innerHTML = response.data;
const svgElement = svgContainer.querySelector('svg'); // 查找 SVG 元素
if (svgElement) {
console.log(svgElement, 'svgElement');
svgPanZoom(svgElement, {
viewportSelector: '#svg-container',
zoomEnabled: true,
controlIconsEnabled: true,
fit: true, // 自适应容器
center: true //将 SVG 居中显示
});
}
// 遍历svg里面的元素,自动添加鼠标事件
this.addMouseEvent(svgContainer);
},
(err) => {
console.log(err);
}
)
.catch((error) => {
console.log(error);
});
},
// 遍历svg里面的元素,自动添加鼠标事件
addMouseEvent(parent) {
for (var i = 0; i < parent.childNodes.length; i++) {
//循坏svg里面的元素
var child = parent.childNodes[i];
// 判断是不是g元素,并且具有id值,是的话,就添加鼠标事件
if (
child.tagName == 'g' &&
child.id != null &&
child.id.length > 0 &&
child.id.indexOf('PD_') == 0
) {
console.log(child.tagName + ':' + child.id);
child.setAttribute('onclick', "handleClick(evt,'" + child.id + "')");
child.setAttribute(
'onmouseover',
"handleMouseOver(evt,'" + child.id + "')"
);
child.setAttribute(
'onmousemove',
"handleMouseMove(evt,'" + child.id + "')"
);
child.setAttribute(
'onmouseout',
"handleMouseOut(evt,'" + child.id + "')"
);
}
//继续递归遍历子元素
this.addMouseEvent(child);
}
},
// svg图元件点击事件
svgClick(evt, id) {
console.log(evt);
alert(id);
},
// svg图元件鼠标移入事件
svgMouseOver(evt, id) {
// console.log('svgMouseOver');
// console.log(evt);
this.svgTipBoxData = id; //这里测试显示的开关的id
this.svgTipBoxVisible = true;
},
// svg图元件鼠标移动事件
svgMouseMove(evt, id) {
// console.log('svgMouseMove');
// console.log(evt);
this.svgTipBoxPositionX = evt.pageX;
this.svgTipBoxPositionY = evt.pageY - 50;
},
// svg图元件鼠标移出事件
svgMouseOut(evt, id) {
// console.log('svgMouseOut');
// console.log(evt);
this.svgTipBoxVisible = false;
}
}
};
</script>
<style scoped>
#home {
padding: 22px 34px 22px 34px;
}
#top-section {
width: 100%;
margin-bottom: 20px;
}
#top-section label {
font-size: 14px;
line-height: 32px;
}
#top-section .el-input {
margin-right: 20px;
width: 200px;
}
#svgTipBox {
position: absolute;
padding: 10px;
background: rgba(0, 0, 0, 0.8);
color: red;
border: 1px solid;
}
#svgControlBox {
position: absolute;
}
/* #svg-container {
width: 1000px;
height: 800px;
} */
</style>

浙公网安备 33010602011771号