|
@@ -2,7 +2,7 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
<div class="main-cont" ref="myElement" id="treedom">
|
|
|
- <div class="main-left">
|
|
|
+ <div class="main-left" ref="leftElement">
|
|
|
<div
|
|
|
v-for="(item, index) in leftList"
|
|
|
:key="index"
|
|
@@ -26,7 +26,7 @@
|
|
|
<div v-if="listData">{{ listData.desc }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="main-right">
|
|
|
+ <div class="main-right" ref="rightElement">
|
|
|
<div
|
|
|
v-for="(item, index) in rightList"
|
|
|
:key="index"
|
|
@@ -46,334 +46,387 @@
|
|
|
</div>
|
|
|
<div id="wrapper"></div>
|
|
|
</div>
|
|
|
- </template>
|
|
|
+</template>
|
|
|
<script setup>
|
|
|
- import { onMounted, watch, ref, nextTick, defineEmits } from "vue";
|
|
|
- import devicePng from "@/assets/image/instruct/device.png";
|
|
|
- import LeaderLine from "../../../../public/leader-line.min.js";
|
|
|
- import AnimEvent from "../../../../public/anim-event.min.js";
|
|
|
- const props = defineProps({
|
|
|
- checkData: {
|
|
|
- type: Object,
|
|
|
- default: () => {},
|
|
|
- },
|
|
|
- isOpen: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- iedRelation: {
|
|
|
- type: Object,
|
|
|
- default: () => {},
|
|
|
- },
|
|
|
- tabName: {
|
|
|
+import { onMounted, watch, ref, nextTick, defineEmits } from "vue";
|
|
|
+import devicePng from "@/assets/image/instruct/device.png";
|
|
|
+import LeaderLine from "../../../../public/leader-line.min.js";
|
|
|
+import AnimEvent from "../../../../public/anim-event.min.js";
|
|
|
+const props = defineProps({
|
|
|
+ checkData: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {},
|
|
|
+ },
|
|
|
+ isOpen: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ iedRelation: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {},
|
|
|
+ },
|
|
|
+ tabName: {
|
|
|
type: String,
|
|
|
default: "",
|
|
|
},
|
|
|
- });
|
|
|
- const middleElement = ref(null);
|
|
|
- const myElement = ref(null);
|
|
|
- let leaderLines = ref([]); //控制线条显示
|
|
|
- const leftList = ref([]);
|
|
|
- const rightList = ref([]);
|
|
|
- const domList = ref(new Map()); //获取 所有的ref
|
|
|
- const domListRight = ref(new Map()); //获取 所有的ref
|
|
|
- const listData = ref(props.checkData); //线条左右两侧的数据
|
|
|
- const emit = defineEmits(["result"]); //如果不加这个再次点击左侧会没有反应
|
|
|
- const setdom = (el, item) => {
|
|
|
- //左侧dom
|
|
|
- if (el) {
|
|
|
- domList.value.set(item, el);
|
|
|
- }
|
|
|
- };
|
|
|
- const setdomRight = (el, item) => {
|
|
|
- //右侧dom
|
|
|
- if (el) {
|
|
|
- domListRight.value.set(item, el);
|
|
|
- }
|
|
|
- };
|
|
|
- const processArray = (arr) => {
|
|
|
- // ref_ied_id作为键,obj作为值
|
|
|
- const uniqueObjects = new Map();
|
|
|
- // 遍历数组
|
|
|
- for (const obj of arr) {
|
|
|
- const { ref_ied_id } = obj;
|
|
|
- // 如果当前对象的 ref_ied_id 属性已经存在于 uniqueObjects 中
|
|
|
- if (uniqueObjects.has(ref_ied_id)) {
|
|
|
- // 将对应对象的 ref_type 属性设为 2,箭头双向
|
|
|
- uniqueObjects.get(ref_ied_id).ref_type = 2;
|
|
|
- } else {
|
|
|
- // 否则,将当前对象添加到 uniqueObjects 中
|
|
|
- uniqueObjects.set(ref_ied_id, obj);
|
|
|
- }
|
|
|
- }
|
|
|
- // 将 uniqueObjects 中的值转为数组并返回
|
|
|
- return Array.from(uniqueObjects.values());
|
|
|
- };
|
|
|
- //点击图片的时候筛选出数据
|
|
|
- const clickImg = (dataItem) => {
|
|
|
- Object.values(props.iedRelation).find((item) => {
|
|
|
- if (item.ied_name == dataItem.ref_ied_name) {
|
|
|
- listData.value = item;
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
- watch(
|
|
|
- () => props.checkData,
|
|
|
- (newValue, oldV) => {
|
|
|
- listData.value = newValue;
|
|
|
- if (newValue && leaderLines.value.length > 0) {
|
|
|
- // leaderLines.value.forEach((line) => line.remove()); //清除连线
|
|
|
- leaderLines.value = [];
|
|
|
- }
|
|
|
- },
|
|
|
- { deep: true }
|
|
|
- );
|
|
|
- watch(
|
|
|
- () => listData.value,
|
|
|
- (newValue) => {
|
|
|
- emit("result", newValue);
|
|
|
- clickResetLine();
|
|
|
+});
|
|
|
+const middleElement = ref(null);
|
|
|
+const rightElement = ref(null);
|
|
|
+const leftElement = ref(null);
|
|
|
+const myElement = ref(null);
|
|
|
+let leaderLines = ref([]); //控制线条显示
|
|
|
+const leftList = ref([]);
|
|
|
+const rightList = ref([]);
|
|
|
+const domList = ref(new Map()); //获取 所有的ref
|
|
|
+const domListRight = ref(new Map()); //获取 所有的ref
|
|
|
+const listData = ref(props.checkData); //线条左右两侧的数据
|
|
|
+const emit = defineEmits(["result"]); //如果不加这个再次点击左侧会没有反应
|
|
|
+const setdom = (el, item) => {
|
|
|
+ //左侧dom
|
|
|
+ if (el) {
|
|
|
+ domList.value.set(item, el);
|
|
|
+ }
|
|
|
+};
|
|
|
+const setdomRight = (el, item) => {
|
|
|
+ //右侧dom
|
|
|
+ if (el) {
|
|
|
+ domListRight.value.set(item, el);
|
|
|
+ }
|
|
|
+};
|
|
|
+const processArray = (arr) => {
|
|
|
+ // ref_ied_id作为键,obj作为值
|
|
|
+ const uniqueObjects = new Map();
|
|
|
+ // 遍历数组
|
|
|
+ for (const obj of arr) {
|
|
|
+ const { ref_ied_id } = obj;
|
|
|
+ // 如果当前对象的 ref_ied_id 属性已经存在于 uniqueObjects 中
|
|
|
+ if (uniqueObjects.has(ref_ied_id)) {
|
|
|
+ // 将对应对象的 ref_type 属性设为 2,箭头双向
|
|
|
+ uniqueObjects.get(ref_ied_id).ref_type = 2;
|
|
|
+ } else {
|
|
|
+ // 否则,将当前对象添加到 uniqueObjects 中
|
|
|
+ uniqueObjects.set(ref_ied_id, obj);
|
|
|
}
|
|
|
- );
|
|
|
- watch(
|
|
|
- () => props.isOpen,
|
|
|
- (newValue) => {
|
|
|
- if (newValue) {
|
|
|
- domList.value.clear();
|
|
|
- domListRight.value.clear();
|
|
|
- leaderLines.value = [];
|
|
|
- }
|
|
|
- nextTick(() => {
|
|
|
- middleLinePosition();
|
|
|
- removeLine();
|
|
|
- });
|
|
|
+ }
|
|
|
+ // 将 uniqueObjects 中的值转为数组并返回
|
|
|
+ return Array.from(uniqueObjects.values());
|
|
|
+};
|
|
|
+//点击图片的时候筛选出数据
|
|
|
+const clickImg = (dataItem) => {
|
|
|
+ Object.values(props.iedRelation).find((item) => {
|
|
|
+ if (item.ied_name == dataItem.ref_ied_name) {
|
|
|
+ listData.value = item;
|
|
|
}
|
|
|
- );
|
|
|
- //点击后重置数据和线条
|
|
|
- const clickResetLine = () => {
|
|
|
- domList.value.clear();
|
|
|
- domListRight.value.clear();
|
|
|
- leaderLines.value = [];
|
|
|
- middleLinePosition();
|
|
|
- setLine();
|
|
|
- removeLine();
|
|
|
- };
|
|
|
- // 将设备列表分成两份
|
|
|
- const bothSide = (data) => {
|
|
|
- const formatArr = processArray(data);
|
|
|
- const arrlenght = formatArr.length;
|
|
|
- const long1 = Math.ceil(arrlenght / 2);
|
|
|
- leftList.value = formatArr.splice(0, long1);
|
|
|
- rightList.value = formatArr.splice(0);
|
|
|
- };
|
|
|
-
|
|
|
- const setLeaderline = () => {
|
|
|
- // lineArr.value = [];
|
|
|
- //线条样式
|
|
|
- const lineStyle0 = {
|
|
|
- color: "#51637F",
|
|
|
- size: 2,
|
|
|
- path: "straight",
|
|
|
- startPlug: "arrow1",
|
|
|
- endPlug: "behind",
|
|
|
- startSocket: "right",
|
|
|
- endSocket: "left",
|
|
|
- };
|
|
|
- const lineStyle1 = {
|
|
|
- color: "#51637F",
|
|
|
- size: 2,
|
|
|
- path: "straight",
|
|
|
- endPlug: "arrow1",
|
|
|
- startSocket: "right",
|
|
|
- endSocket: "left",
|
|
|
- };
|
|
|
- const lineStyle2 = {
|
|
|
- color: "#134BEA",
|
|
|
- size: 2,
|
|
|
- path: "straight",
|
|
|
- startPlug: "arrow1",
|
|
|
- endPlug: "arrow1",
|
|
|
- startSocket: "right",
|
|
|
- endSocket: "left",
|
|
|
- };
|
|
|
- const lineStyleRight0 = {
|
|
|
- color: "#51637F",
|
|
|
- size: 2,
|
|
|
- path: "straight",
|
|
|
- startPlug: "arrow1",
|
|
|
- endPlug: "behind",
|
|
|
- startSocket: "left",
|
|
|
- endSocket: "right",
|
|
|
- };
|
|
|
- const lineStyleRight1 = {
|
|
|
- color: "#51637F",
|
|
|
- size: 2,
|
|
|
- path: "straight",
|
|
|
- endPlug: "arrow1",
|
|
|
- startSocket: "left",
|
|
|
- endSocket: "right",
|
|
|
- };
|
|
|
- const lineStyleRight2 = {
|
|
|
- color: "#134BEA",
|
|
|
- size: 2,
|
|
|
- path: "straight",
|
|
|
- startPlug: "arrow1",
|
|
|
- endPlug: "arrow1",
|
|
|
- startSocket: "left",
|
|
|
- endSocket: "right",
|
|
|
- };
|
|
|
- const startDom = document.getElementById("end");
|
|
|
- //循环画线
|
|
|
- for (const [key, value] of domList.value) {
|
|
|
- const endDom = value;
|
|
|
- let line;
|
|
|
- if (key.ref_type == 0) {
|
|
|
- line = new LeaderLine(endDom, startDom, lineStyle0);
|
|
|
- } else if (key.ref_type == 1) {
|
|
|
- line = new LeaderLine(endDom, startDom, lineStyle1);
|
|
|
- } else if (key.ref_type == 2) {
|
|
|
- line = new LeaderLine(endDom, startDom, lineStyle2);
|
|
|
- }
|
|
|
- // 保存进数组,方便进行遍历删除
|
|
|
- leaderLines.value.push(line);
|
|
|
+ });
|
|
|
+};
|
|
|
+watch(
|
|
|
+ () => props.checkData,
|
|
|
+ (newValue, oldV) => {
|
|
|
+ listData.value = newValue;
|
|
|
+ if (newValue && leaderLines.value.length > 0) {
|
|
|
+ // leaderLines.value.forEach((line) => line.remove()); //清除连线
|
|
|
+ leaderLines.value = [];
|
|
|
}
|
|
|
- //循环画线右侧
|
|
|
- for (const [key, value] of domListRight.value) {
|
|
|
- const endDom = value;
|
|
|
- let line2;
|
|
|
- if (key.ref_type == 0) {
|
|
|
- line2 = new LeaderLine(endDom, startDom, lineStyleRight0);
|
|
|
- } else if (key.ref_type == 1) {
|
|
|
- line2 = new LeaderLine(endDom, startDom, lineStyleRight1);
|
|
|
- } else if (key.ref_type == 2) {
|
|
|
- line2 = new LeaderLine(endDom, startDom, lineStyleRight2);
|
|
|
- }
|
|
|
- // 保存进数组,方便进行遍历删除
|
|
|
- leaderLines.value.push(line2);
|
|
|
+ },
|
|
|
+ { deep: true }
|
|
|
+);
|
|
|
+watch(
|
|
|
+ () => listData.value,
|
|
|
+ (newValue) => {
|
|
|
+ emit("result", newValue);
|
|
|
+ clickResetLine();
|
|
|
+ }
|
|
|
+);
|
|
|
+watch(
|
|
|
+ () => props.isOpen,
|
|
|
+ (newValue) => {
|
|
|
+ if (newValue) {
|
|
|
+ domList.value.clear();
|
|
|
+ domListRight.value.clear();
|
|
|
+ leaderLines.value = [];
|
|
|
}
|
|
|
- hiddenLine();
|
|
|
- };
|
|
|
- //设置中间盒子的所在位置
|
|
|
- const middleLinePosition = () => {
|
|
|
- setTimeout(() => {
|
|
|
- const heights = myElement.value.scrollHeight;
|
|
|
- if (leftList.value.length > 3 || rightList.value.length > 3) {
|
|
|
- middleElement.value.style.marginTop = `${(heights - 60) / 2}px`; // 设置元素的垂直位置
|
|
|
- } else {
|
|
|
- middleElement.value.style.marginTop = "150px"; // 设置元素的垂直位置
|
|
|
- }
|
|
|
- }, 0);
|
|
|
- };
|
|
|
- onMounted(() => {
|
|
|
nextTick(() => {
|
|
|
- setLine();
|
|
|
middleLinePosition();
|
|
|
- nextTick(() => {
|
|
|
- newPositionLine();
|
|
|
- });
|
|
|
+ removeLine();
|
|
|
});
|
|
|
- });
|
|
|
- //滚动时重定位线条
|
|
|
- const newPositionLine = () => {
|
|
|
- document.getElementById("treedom").addEventListener(
|
|
|
- "scroll",
|
|
|
- AnimEvent.add(() => {
|
|
|
- leaderLines.value.forEach((line) => {
|
|
|
- hiddenLine();
|
|
|
- line.position();
|
|
|
- line.positionByWindowResize = false;
|
|
|
- });
|
|
|
- //中间展示图片的
|
|
|
- }),
|
|
|
- false
|
|
|
- );
|
|
|
+ }
|
|
|
+);
|
|
|
+//点击后重置数据和线条
|
|
|
+const clickResetLine = () => {
|
|
|
+ domList.value.clear();
|
|
|
+ domListRight.value.clear();
|
|
|
+ leaderLines.value = [];
|
|
|
+ middleLinePosition();
|
|
|
+ setLine();
|
|
|
+ removeLine();
|
|
|
+};
|
|
|
+// 将设备列表分成两份
|
|
|
+const bothSide = (data) => {
|
|
|
+ const formatArr = processArray(data);
|
|
|
+ const arrlenght = formatArr.length;
|
|
|
+ const long1 = Math.ceil(arrlenght / 2);
|
|
|
+ leftList.value = formatArr.splice(0, long1);
|
|
|
+ rightList.value = formatArr.splice(0);
|
|
|
+};
|
|
|
+
|
|
|
+const setLeaderline = () => {
|
|
|
+ // lineArr.value = [];
|
|
|
+ //线条样式
|
|
|
+ const lineStyle0 = {
|
|
|
+ color: "#51637F",
|
|
|
+ size: 2,
|
|
|
+ path: "straight",
|
|
|
+ startPlug: "arrow1",
|
|
|
+ endPlug: "behind",
|
|
|
+ startSocket: "right",
|
|
|
+ endSocket: "left",
|
|
|
};
|
|
|
- //弹窗打开后使得线条在指定区域中
|
|
|
- const hiddenLine = () => {
|
|
|
- const elmWrapper = document.getElementById("wrapper");
|
|
|
- // 移动 line
|
|
|
- document.body.querySelectorAll("body .leader-line").forEach((node) => {
|
|
|
- elmWrapper.appendChild(node);
|
|
|
- });
|
|
|
- elmWrapper.style.transform = "none";
|
|
|
- var rectWrapper = elmWrapper.getBoundingClientRect();
|
|
|
- // Move to the origin of coordinates as the document
|
|
|
- elmWrapper.style.transform = `translate(${
|
|
|
- (rectWrapper.left + window.scrollY) * -1
|
|
|
- }px, ${(rectWrapper.top + window.scrollX) * -1}px)`;
|
|
|
+ const lineStyle1 = {
|
|
|
+ color: "#51637F",
|
|
|
+ size: 2,
|
|
|
+ path: "straight",
|
|
|
+ endPlug: "arrow1",
|
|
|
+ startSocket: "right",
|
|
|
+ endSocket: "left",
|
|
|
};
|
|
|
- const setLine = () => {
|
|
|
- if (listData.value) {
|
|
|
- bothSide(listData.value.list);
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- setLeaderline();
|
|
|
- }, 30);
|
|
|
+ const lineStyle2 = {
|
|
|
+ color: "#134BEA",
|
|
|
+ size: 2,
|
|
|
+ path: "straight",
|
|
|
+ startPlug: "arrow1",
|
|
|
+ endPlug: "arrow1",
|
|
|
+ startSocket: "right",
|
|
|
+ endSocket: "left",
|
|
|
};
|
|
|
- const removeLine = () => {
|
|
|
- const elmWrapper = document.getElementById("wrapper");
|
|
|
- document.body.querySelectorAll("body .leader-line").forEach((node) => {
|
|
|
- elmWrapper.removeChild(node);
|
|
|
- });
|
|
|
+ const lineStyleRight0 = {
|
|
|
+ color: "#51637F",
|
|
|
+ size: 2,
|
|
|
+ path: "straight",
|
|
|
+ startPlug: "arrow1",
|
|
|
+ endPlug: "behind",
|
|
|
+ startSocket: "left",
|
|
|
+ endSocket: "right",
|
|
|
};
|
|
|
- </script>
|
|
|
- <style lang="scss">
|
|
|
- @mixin img-size {
|
|
|
- width: 150px;
|
|
|
- height: 90px;
|
|
|
- margin-bottom: 10px;
|
|
|
- }
|
|
|
- @mixin left-and-right {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- }
|
|
|
- .main-cont {
|
|
|
- margin-top: 60px;
|
|
|
- display: flex;
|
|
|
- justify-content: space-evenly;
|
|
|
- }
|
|
|
-
|
|
|
- .leader-line {
|
|
|
- z-index: 3000;
|
|
|
+ const lineStyleRight1 = {
|
|
|
+ color: "#51637F",
|
|
|
+ size: 2,
|
|
|
+ path: "straight",
|
|
|
+ endPlug: "arrow1",
|
|
|
+ startSocket: "left",
|
|
|
+ endSocket: "right",
|
|
|
+ };
|
|
|
+ const lineStyleRight2 = {
|
|
|
+ color: "#134BEA",
|
|
|
+ size: 2,
|
|
|
+ path: "straight",
|
|
|
+ startPlug: "arrow1",
|
|
|
+ endPlug: "arrow1",
|
|
|
+ startSocket: "left",
|
|
|
+ endSocket: "right",
|
|
|
+ };
|
|
|
+ const startDom = document.getElementById("end");
|
|
|
+ let count = 56;
|
|
|
+ //循环画线
|
|
|
+ for (const [key, value] of domList.value) {
|
|
|
+ const endDom = value;
|
|
|
+ let line;
|
|
|
+ count += 5;
|
|
|
+ if (key.ref_type == 0) {
|
|
|
+ line = new LeaderLine(
|
|
|
+ endDom,
|
|
|
+ LeaderLine.pointAnchor(startDom, { x: 0, y: count }),
|
|
|
+ lineStyle0
|
|
|
+ );
|
|
|
+ } else if (key.ref_type == 1) {
|
|
|
+ line = new LeaderLine(
|
|
|
+ endDom,
|
|
|
+ LeaderLine.pointAnchor(startDom, { x: 0, y: count }),
|
|
|
+ lineStyle1
|
|
|
+ );
|
|
|
+ } else if (key.ref_type == 2) {
|
|
|
+ line = new LeaderLine(
|
|
|
+ endDom,
|
|
|
+ LeaderLine.pointAnchor(startDom, { x: 0, y: count }),
|
|
|
+ lineStyle2
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // 保存进数组,方便进行遍历删除
|
|
|
+ leaderLines.value.push(line);
|
|
|
}
|
|
|
- .main-left {
|
|
|
- display: flex;
|
|
|
- @include left-and-right;
|
|
|
- .img-item {
|
|
|
- @include img-size;
|
|
|
+ let count2 = 56;
|
|
|
+ //循环画线右侧
|
|
|
+ for (const [key, value] of domListRight.value) {
|
|
|
+ const endDom = value;
|
|
|
+ let line2;
|
|
|
+ count2 += 5;
|
|
|
+ if (key.ref_type == 0) {
|
|
|
+ line2 = new LeaderLine(
|
|
|
+ endDom,
|
|
|
+ LeaderLine.pointAnchor(startDom, { x: "100%", y: count2 }),
|
|
|
+ lineStyleRight0
|
|
|
+ );
|
|
|
+ } else if (key.ref_type == 1) {
|
|
|
+ line2 = new LeaderLine(
|
|
|
+ endDom,
|
|
|
+ LeaderLine.pointAnchor(startDom, { x: "100%", y: count2 }),
|
|
|
+ lineStyleRight1
|
|
|
+ );
|
|
|
+ } else if (key.ref_type == 2) {
|
|
|
+ line2 = new LeaderLine(
|
|
|
+ endDom,
|
|
|
+ LeaderLine.pointAnchor(startDom, { x: "100%", y: count2 }),
|
|
|
+ lineStyleRight2
|
|
|
+ );
|
|
|
}
|
|
|
+ // 保存进数组,方便进行遍历删除
|
|
|
+ leaderLines.value.push(line2);
|
|
|
}
|
|
|
- .main-middle {
|
|
|
- box-sizing: border-box;
|
|
|
- img {
|
|
|
- margin-bottom: 10px;
|
|
|
+ hiddenLine();
|
|
|
+};
|
|
|
+//设置中间盒子的所在位置
|
|
|
+const middleLinePosition = () => {
|
|
|
+ setTimeout(() => {
|
|
|
+ const heights = myElement.value.scrollHeight;
|
|
|
+ const leftListLength = leftList.value.length;
|
|
|
+ const rightListLength = rightList.value.length;
|
|
|
+ const setElementMarginTop = (element, value) => {
|
|
|
+ element.value.style.marginTop = `${value}px`;
|
|
|
+ };
|
|
|
+ if (leftList.value.length > 3 || rightList.value.length > 3) {
|
|
|
+ middleElement.value.style.marginTop = `${(heights - 60) / 2}px`; // 设置元素的垂直位置
|
|
|
+ } else {
|
|
|
+ setElementMarginTop(leftElement, 0);
|
|
|
+ setElementMarginTop(rightElement, 0);
|
|
|
+ setElementMarginTop(middleElement, 150);
|
|
|
}
|
|
|
- .middle-item {
|
|
|
- @include left-and-right;
|
|
|
- align-items: center;
|
|
|
- color: #ffcb11;
|
|
|
+ if (rightListLength == 1) {
|
|
|
+ setElementMarginTop(rightElement, 165);
|
|
|
}
|
|
|
- }
|
|
|
- .main-right {
|
|
|
- display: flex;
|
|
|
- @include left-and-right;
|
|
|
- .img-item {
|
|
|
- @include img-size;
|
|
|
+ if (leftListLength == 1) {
|
|
|
+ setElementMarginTop(leftElement, 165);
|
|
|
}
|
|
|
+ }, 0);
|
|
|
+};
|
|
|
+onMounted(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ setLine();
|
|
|
+ middleLinePosition();
|
|
|
+ nextTick(() => {
|
|
|
+ newPositionLine();
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|
|
|
+//滚动时重定位线条
|
|
|
+const newPositionLine = () => {
|
|
|
+ document.getElementById("treedom").addEventListener(
|
|
|
+ "scroll",
|
|
|
+ AnimEvent.add(() => {
|
|
|
+ leaderLines.value.forEach((line) => {
|
|
|
+ hiddenLine();
|
|
|
+ line.position();
|
|
|
+ line.positionByWindowResize = false;
|
|
|
+ });
|
|
|
+ }),
|
|
|
+ false
|
|
|
+ );
|
|
|
+ window.addEventListener(
|
|
|
+ "resize",
|
|
|
+ AnimEvent.add(function () {
|
|
|
+ leaderLines.value.forEach((line) => {
|
|
|
+ hiddenLine();
|
|
|
+ line.position();
|
|
|
+ line.positionByWindowResize = false;
|
|
|
+ });
|
|
|
+ }),
|
|
|
+ false
|
|
|
+ );
|
|
|
+};
|
|
|
+//弹窗打开后使得线条在指定区域中
|
|
|
+const hiddenLine = () => {
|
|
|
+ const elmWrapper = document.getElementById("wrapper");
|
|
|
+ // 移动 line
|
|
|
+ document.body.querySelectorAll("body .leader-line").forEach((node) => {
|
|
|
+ elmWrapper.appendChild(node);
|
|
|
+ });
|
|
|
+ elmWrapper.style.transform = "none";
|
|
|
+ var rectWrapper = elmWrapper.getBoundingClientRect();
|
|
|
+ // Move to the origin of coordinates as the document
|
|
|
+ elmWrapper.style.transform = `translate(${
|
|
|
+ (rectWrapper.left + window.scrollY) * -1
|
|
|
+ }px, ${(rectWrapper.top + window.scrollX) * -1}px)`;
|
|
|
+};
|
|
|
+const setLine = () => {
|
|
|
+ if (listData.value) {
|
|
|
+ bothSide(listData.value.list);
|
|
|
}
|
|
|
-
|
|
|
- .cont {
|
|
|
+ setTimeout(() => {
|
|
|
+ setLeaderline();
|
|
|
+ }, 200);
|
|
|
+};
|
|
|
+const removeLine = () => {
|
|
|
+ const elmWrapper = document.getElementById("wrapper");
|
|
|
+ document.body.querySelectorAll("body .leader-line").forEach((node) => {
|
|
|
+ elmWrapper.removeChild(node);
|
|
|
+ });
|
|
|
+};
|
|
|
+</script>
|
|
|
+ <style lang="scss">
|
|
|
+@mixin img-size {
|
|
|
+ width: 150px;
|
|
|
+ height: 90px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+@mixin left-and-right {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+.main-cont {
|
|
|
+ margin-top: 60px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-evenly;
|
|
|
+}
|
|
|
+
|
|
|
+.leader-line {
|
|
|
+ z-index: 3000;
|
|
|
+}
|
|
|
+.main-left {
|
|
|
+ display: flex;
|
|
|
+ @include left-and-right;
|
|
|
+ .img-item {
|
|
|
+ @include img-size;
|
|
|
+ }
|
|
|
+}
|
|
|
+.main-middle {
|
|
|
+ box-sizing: border-box;
|
|
|
+ img {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ .middle-item {
|
|
|
@include left-and-right;
|
|
|
align-items: center;
|
|
|
- margin-bottom: 10px;
|
|
|
- .ied-desc {
|
|
|
- color: #255ce7;
|
|
|
- }
|
|
|
+ color: #ffcb11;
|
|
|
+ }
|
|
|
+}
|
|
|
+.main-right {
|
|
|
+ display: flex;
|
|
|
+ @include left-and-right;
|
|
|
+ .img-item {
|
|
|
+ @include img-size;
|
|
|
}
|
|
|
-
|
|
|
- #wrapper {
|
|
|
- width: 0;
|
|
|
- height: 0;
|
|
|
- position: relative; /* Origin of coordinates for lines, and scrolled content (i.e. not `absolute`) */
|
|
|
+}
|
|
|
+
|
|
|
+.cont {
|
|
|
+ @include left-and-right;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ .ied-desc {
|
|
|
+ color: #255ce7;
|
|
|
}
|
|
|
- </style>
|
|
|
+}
|
|
|
+
|
|
|
+#wrapper {
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ position: relative; /* Origin of coordinates for lines, and scrolled content (i.e. not `absolute`) */
|
|
|
+}
|
|
|
+</style>
|