<template>
|
<div
|
class="drawflow"
|
:style="{ borderColor: primaryColor ? primaryColor : '#ccc' }"
|
>
|
<div
|
class="menu"
|
:style="{ borderColor: primaryColor ? primaryColor : '#ccc' }"
|
>
|
<div
|
class="menuItem"
|
:style="{ borderColor: primaryColor ? primaryColor : '#ccc' }"
|
>
|
<div
|
class="drag-drawflow"
|
draggable="true"
|
@dragstart="drag"
|
data-node="template"
|
>
|
<span>拖拽此处创建</span>
|
</div>
|
</div>
|
</div>
|
<div class="content" :id="strId" @drop="drop" @dragover="allowDrop">
|
<div class="btn-export" @click="exportData">导出</div>
|
<div class="btn-clear" @click="editor.clearModuleSelected()">清空</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import Vue from "vue";
|
import Drawflow from "drawflow";
|
export default {
|
data() {
|
return {
|
editor: null,
|
mobile_item_selec: "",
|
mobile_last_move: null,
|
};
|
},
|
props: {
|
importData: {
|
type: Object,
|
},
|
primaryColor: {
|
type: String,
|
},
|
strId: {
|
type: String,
|
default: "drawflow",
|
},
|
},
|
mounted() {
|
this.init();
|
},
|
methods: {
|
exportData() {
|
let dataJ = this.editor.export();
|
this.$emit("getDrawData", dataJ);
|
},
|
init() {
|
this.editor = new Drawflow(
|
document.getElementById(this.strId),
|
Vue,
|
this
|
);
|
this.editor.reroute = true;
|
this.editor.start();
|
if (this.importData) {
|
// 渲染记录的数据
|
this.editor.import(this.importData);
|
}
|
|
// 事件绑定
|
this.editor.on("nodeCreated", function (id) {
|
console.log("Node created " + id);
|
});
|
|
this.editor.on("nodeRemoved", function (id) {
|
console.log("Node removed " + id);
|
});
|
|
this.editor.on("nodeSelected", function (id) {
|
console.log("Node selected " + id);
|
});
|
|
this.editor.on("moduleCreated", function (name) {
|
console.log("Module Created " + name);
|
});
|
|
this.editor.on("moduleChanged", function (name) {
|
console.log("Module Changed " + name);
|
});
|
|
this.editor.on("connectionCreated", function (connection) {
|
console.log("Connection created");
|
console.log(connection);
|
});
|
|
this.editor.on("connectionRemoved", function (connection) {
|
console.log("Connection removed");
|
console.log(connection);
|
});
|
|
this.editor.on("mouseMove", function (position) {
|
// console.log("Position mouse x:" + position.x + " y:" + position.y);
|
});
|
|
this.editor.on("nodeMoved", function (id) {
|
console.log("Node moved " + id);
|
});
|
|
this.editor.on("zoom", function (zoom) {
|
console.log("Zoom level " + zoom);
|
});
|
|
this.editor.on("translate", function (position) {
|
console.log("Translate x:" + position.x + " y:" + position.y);
|
});
|
|
this.editor.on("addReroute", function (id) {
|
console.log("Reroute added " + id);
|
});
|
|
this.editor.on("removeReroute", function (id) {
|
console.log("Reroute removed " + id);
|
});
|
},
|
drop(ev) {
|
if (ev.type === "touchend") {
|
var parentdrawflow = document
|
.elementFromPoint(
|
this.mobile_last_move.touches[0].clientX,
|
this.mobile_last_move.touches[0].clientY
|
)
|
.closest("#drawflow");
|
if (parentdrawflow != null) {
|
this.addNodeToDrawFlow(
|
this.mobile_item_selec,
|
this.mobile_last_move.touches[0].clientX,
|
this.mobile_last_move.touches[0].clientY
|
);
|
}
|
this.mobile_item_selec = "";
|
} else {
|
ev.preventDefault();
|
var data = ev.dataTransfer.getData("node");
|
this.addNodeToDrawFlow(data, ev.clientX, ev.clientY);
|
}
|
},
|
positionMobile(ev) {
|
this.mobile_last_move = ev;
|
},
|
drag(ev) {
|
if (ev.type === "touchstart") {
|
this.mobile_item_selec = ev.target
|
.closest(".drag-drawflow")
|
.getAttribute("data-node");
|
} else {
|
ev.dataTransfer.setData("node", ev.target.getAttribute("data-node"));
|
}
|
},
|
addNodeToDrawFlow(name, pos_x, pos_y) {
|
if (this.editor.editor_mode === "fixed") {
|
return false;
|
}
|
pos_x =
|
pos_x *
|
(this.editor.precanvas.clientWidth /
|
(this.editor.precanvas.clientWidth * this.editor.zoom)) -
|
this.editor.precanvas.getBoundingClientRect().x *
|
(this.editor.precanvas.clientWidth /
|
(this.editor.precanvas.clientWidth * this.editor.zoom));
|
pos_y =
|
pos_y *
|
(this.editor.precanvas.clientHeight /
|
(this.editor.precanvas.clientHeight * this.editor.zoom)) -
|
this.editor.precanvas.getBoundingClientRect().y *
|
(this.editor.precanvas.clientHeight /
|
(this.editor.precanvas.clientHeight * this.editor.zoom));
|
|
switch (name) {
|
case "template":
|
// eslint-disable-next-line no-case-declarations
|
let noneEle = `
|
<div class="contentWall">
|
<div class="contentTitle">
|
<input placeholder="请输入标题" df-title />
|
</div>
|
<div class="contentText">
|
<textarea rows="4" placeholder="请输入描述" df-content></textarea>
|
</div>
|
</div>
|
`;
|
this.editor.addNode(
|
"noneEle",
|
1,
|
1,
|
pos_x,
|
pos_y,
|
"noneEle",
|
{
|
title: "",
|
content: "",
|
},
|
noneEle
|
);
|
break;
|
}
|
},
|
allowDrop(ev) {
|
ev.preventDefault();
|
},
|
},
|
};
|
</script>
|
|
<style scoped>
|
@import "drawflow/dist/drawflow.min.css";
|
.drawflow {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
border: 1px solid #ccc;
|
background: #fff;
|
}
|
.menu {
|
width: 160px;
|
border-right: 1px solid #ccc;
|
}
|
.menuItem {
|
border-bottom: 1px solid #ccc;
|
}
|
.drag-drawflow {
|
padding: 10px 20px;
|
cursor: move;
|
user-select: none;
|
}
|
.content {
|
flex: 1;
|
overflow: hidden;
|
background-size: 25px 25px;
|
background-image: linear-gradient(to right, #f1f1f1 1px, transparent 1px),
|
linear-gradient(to bottom, #f1f1f1 1px, transparent 1px);
|
}
|
</style>
|