1. <!DOCTYPE html>
  2. <html lang="en">
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Document</title>
  7. <style type="text/css">
  8. #d1 {
  9. width: 800px;
  10. height: 800px;
  11. border: 1px solid #ccc;
  12. position: relative;
  13. background: #fafafa;
  14. }
  15.  
  16. #d1>div {
  17. width: 130px;
  18. height: 30px;
  19. border: 1px solid #ccc;
  20. border-radius: 8px;
  21. position: absolute;
  22. z-index: 2;
  23. text-align: center;
  24. line-height: 30px;
  25. background: #fff;
  26. }
  27.  
  28. #d1>svg {
  29. width: 100%;
  30. height: 100%;
  31. position: absolute;
  32. z-index: 1
  33. }
  34.  
  35. .input .point {
  36. position: absolute;
  37. border: 6px solid transparent;
  38. border-top: 6px solid #ccc;
  39. top: 0px;
  40. left: 58px;
  41. }
  42.  
  43. .input .circle {
  44. position: absolute;
  45. width: 10px;
  46. height: 10px;
  47. border: 1px solid #ccc;
  48. top: -7px;
  49. left: 60px;
  50. border-radius: 50%;
  51. background: #fff;
  52. }
  53.  
  54. .output .circle {
  55. position: absolute;
  56. width: 15px;
  57. height: 15px;
  58. border: 1px solid #ccc;
  59. bottom: -10px;
  60. left: 57px;
  61. border-radius: 50%;
  62. background: #fff;
  63. cursor: crosshair;
  64. z-index: 10;
  65. }
  66.  
  67. .output .circle:hover {
  68. background: #FC9901;
  69. }
  70. </style>
  71. </head>
  72.  
  73. <body>
  74. <ul class="shuiguo">
  75. <li draggable="true" data-name="ps1">ps1</li>
  76. <li draggable="true" data-name="ps2">ps2</li>
  77. <li draggable="true" data-name="ps3">ps3</li>
  78. <li draggable="true" data-name="ps4">ps4</li>
  79. <li draggable="true" data-name="switch">switch</li>
  80. </ul>
  81. <div id="d1">
  82. <svg>
  83.  
  84. </svg>
  85. </div>
  86. <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  87. <script type="text/javascript">
  88. var dragData = [];
  89. //重置拖拽后流程图展示
  90. function reload(isend) {
  91. $(function() {
  92. var html = "";
  93. var g = `
  94. <defs>
  95. <marker id="markerArrow1" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
  96. <path d="M0,1 L0,5 L3,3 z" fill="#CCCCCC"></path>
  97. </marker>
  98. <marker id="markerArrow2" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
  99. <path d="M0,1 L0,5 L3,3 z" fill="#cccdff"></path>
  100. </marker>
  101. <marker id="markerArrow3" markerWidth="10" markerHeight="10" refX="3" refY="2.6" orient="auto" markerUnits="strokeWidth">
  102. <path fill="#f00" d="m6.75848,4.22161c-0.13193,0.12924 -0.3468,0.12924 -0.47903,0l-3.03436,-2.97252c-0.13193,-0.12953 -0.13223,-0.33974 0,-0.46927c0.13163,-0.12953 0.3465,-0.12953 0.47933,0l3.03406,2.97223c0.13193,0.13012 0.13253,0.34003 0,0.46956l0,0l0,0zm-0.00361,-2.974l-3.03406,2.97223c-0.13253,0.12983 -0.3471,0.12983 -0.47933,0c-0.13223,-0.12924 -0.13223,-0.33915 0.0003,-0.46927l3.03406,-2.97193c0.13253,-0.12953 0.3474,-0.12953 0.47903,-0.0003c0.13253,0.12953 0.13193,0.33974 0,0.46927l0,0l0,0z"/>
  103. </marker>
  104. </defs>
  105. `;
  106. if($('svg').siblings()) { //清除$('svg')范围外的所有元素
  107. var prev = $('svg').siblings();
  108. for(var i = 0; i < prev.length; i++) {
  109. prev[i].remove();
  110. }
  111. }
  112. console.log(dragData);
  113. for(var i = 0; i < dragData.length; i++) { //循环dragData,重置流程图所有dom节点
  114. if(dragData[i] != undefined) {
  115. var data = dragData[i];
  116. html +=
  117. `
  118. <div class = "${data.name}" data-drag="1" data-id = "${data.id}" data-inx = "${data.inx}" data-iny = "${data.iny}" data-label = "${data.label}" ondragstart = "insideDrag(this)" draggable = "true" style = "transform:translate(${data.x}px,${data.y}px)">
  119. <span class = "${data.icon}" data-id = "${data.id}"></span>
  120. <span data-id = "${data.id}">${data.label}</span>
  121. <div class = "output">
  122. <span class = "circle" title = "输出" onmousedown = "noDrag(this)" onmouseup = "addDrag(this)" onmouseleave = "draw(this)" onmouseenter = "noMove()" data-id = "${data.id}"></span>
  123. </div>
  124. </div>
  125. `
  126. if(data.link.length > 0) {
  127. for(var j = 0; j < data.link.length; j++) {
  128. g +=
  129. `
  130. <g id="${data.link[j].name}">
  131. <path style="cursor:pointer" d = "M${data.outx} ${data.outy} Q${data.link[j].mx1} ${data.link[j].my1} ${data.link[j].mx2} ${data.link[j].my2} T${data.link[j].dx} ${data.link[j].dy}" stroke = "#CCCCCC" fill = "none" stroke-width="4" marker-end="url(#markerArrow1)"/>
  132. </g>
  133. `
  134. }
  135. }
  136. }
  137. }
  138. $('svg').before(html);
  139. $('svg').html(g);
  140. if(isend) {
  141. $('svg').on('mouseenter', "path", function() {
  142. $(this).attr({
  143. "stroke": "#cccdff",
  144. "marker-end": "url(#markerArrow2)",
  145. "marker-mid": "url(#markerArrow3)"
  146. })
  147. }).on('mouseleave', "path", function() {
  148. $(this).attr({
  149. "stroke": "#cccccc",
  150. "marker-end": "url(#markerArrow1)",
  151. "marker-mid": ""
  152. })
  153. }).on('click', "path", function() {
  154. var $p = $(this).parent();
  155. var id = $p[0].id;
  156. for(var i = 0; i < dragData.length; i++) {
  157. var data = dragData[i];
  158. for(var j = 0; j < data.link.length; j++) {
  159. if(id == data.link[j].name) {
  160. data.link.splice(j, 1)
  161. }
  162. }
  163. for(var j = 0; j < data.linked.length; j++) {
  164. if(id == data.linked[j].name) {
  165. data.linked.splice(j, 1)
  166. }
  167. }
  168. }
  169. $p.remove()
  170. });
  171. } else {
  172. $('svg').off('mouseenter mouseleave', "path");
  173. }
  174. console.log($('svg').siblings());
  175. })
  176. }
  177. //reload();
  178. document.getElementById('d1').ondragover = function(e) {
  179. e.preventDefault(); //流程图展示区阻止默认事件
  180. }
  181. var dWidth = Number($('#d1').css('width').slice(0, -2)); //流程图展示区域宽度
  182. console.log(dWidth);
  183. var dHeight = Number($('#d1').css('height').slice(0, -2)); //流程图展示区域高度
  184. console.log(dHeight);
  185. var dClient = $("#d1").offset().top; //流程图展示区偏移位置top
  186. var dLeft = $("#d1").offset().left; //流程图展示区偏移位置left
  187. console.log('顶部位置', dClient);
  188. console.log('左边位置', dLeft);
  189.  
  190. //模块拖进流程图后,初始化拖拽方法
  191. /*
  192. * word:模块名称
  193. * name:模块数据名称
  194. * type:拖拽事件类型,用于判断来执行不同拖拽事件,"outside":拖拽完成,"inside":开始拖拽
  195. * id:模块id
  196. */
  197. function drag(word, name, type, id) {
  198. console.log(type);
  199. console.log(name);
  200. //在可拖动元素放置在 <div> 元素中时执行事件ondrop
  201. document.getElementById('d1').ondrop = function(e) {
  202. var sTop = $(document).scrollTop(); //文档滚动条偏移量top
  203. var sLeft = $(document).scrollLeft(); //文档滚动条偏移量left
  204. console.log('e.target', e.target.dataset.id);
  205. var x, y;
  206. console.log('e.clientX', e.clientX);
  207. console.log('e.clientY', e.clientY);
  208. if((dWidth - e.clientX + dLeft + 65) - sLeft >= 132) {
  209. x = e.clientX - 65 - dLeft + sLeft;
  210. } else {
  211. x = dWidth - 133;
  212. }
  213. if((e.clientX - dLeft) < 65) {
  214. x = 1;
  215. }
  216. if((dHeight - e.clientY + dClient + 15) - sTop >= 33) {
  217. y = e.clientY - 15 - dClient + sTop;
  218. } else {
  219. y = dHeight - 33;
  220. }
  221. if(e.clientY - 15 - dClient + sTop < 0) {
  222. y = 1;
  223. }
  224. if(type == "outside") {
  225. console.log('放下了');
  226. dragData.push({
  227. id: dragData.length,
  228. label: word,
  229. name: name,
  230. x: x, //模块相对展示区域的位移x
  231. y: y, //模块相对展示区域的位移y
  232. outx: x + 68, //模块输出点位置x/贝塞尔曲线起点x
  233. outy: y + 30, //模块输出点位置y/贝塞尔曲线起点y
  234. inx: x + 65, //模块输入点位置x
  235. iny: y - 1, //模块输入点位置y
  236. link: [], //存放由该模块连接的关联线数据数组
  237. linked: [], //存放由其他模块连接该模块的关联线数据数组
  238. dx: 0,
  239. dy: 0,
  240. mx1: 0,
  241. my1: 0,
  242. mx2: 0,
  243. my2: 0,
  244. style: name,
  245. draw: false,
  246. icon: name + "Icon"
  247. });
  248. console.log(dragData);
  249. reload(1);
  250. }
  251. if(type == "inside") {
  252. console.log(word, name, type, id);
  253. for(var i = 0; i < dragData.length; i++) {
  254. if(id == dragData[i].id) {
  255. dragData[i].x = x;
  256. dragData[i].y = y;
  257. dragData[i].outx = dragData[i].x + 68;
  258. dragData[i].outy = dragData[i].y + 30;
  259. dragData[i].inx = dragData[i].x + 65;
  260. dragData[i].iny = dragData[i].y - 1;
  261. console.log('dragData[i].link', dragData[i].link);
  262. for(let j = 0; j < dragData[i].link.length; j++) {
  263. dragData[i].link[j].linkId = parseFloat(dragData[i].link[j].name.split("|")[1]);
  264. }
  265. for(var k = 0; k < dragData[i].linked.length; k++) {
  266. console.log('dragData[i].linked[k]', dragData[i].linked[k]);
  267. for(let j = 0; j < dragData.length; j++) {
  268. if(dragData[i].linked[k].linkedNum == dragData[j].id) {
  269. console.log('ID一样了啊');
  270. for(let m = 0; m < dragData[j].link.length; m++) {
  271. if(dragData[i].linked[k].name == dragData[j].link[m].name) {
  272. console.log("名字一样了啊");
  273. dragData[j].link[m].dx = dragData[i].inx;
  274. dragData[j].link[m].dy = dragData[i].iny-10;
  275. dragData[j].link[m].mx1 = dragData[j].outx;
  276. dragData[j].link[m].my1 = dragData[j].link[m].dy > dragData[j].outy ? dragData[j].outy + (dragData[j].link[m].dy - dragData[j].outy) / 3 : dragData[j].outy - (dragData[j].link[m].dy - dragData[j].outy) / 3;
  277. dragData[j].link[m].mx2 = dragData[j].outx + (dragData[j].link[m].dx - dragData[j].outx) / 2,
  278. dragData[j].link[m].my2 = dragData[j].outy + (dragData[j].link[m].dy - dragData[j].outy) / 2
  279. }
  280. }
  281. }
  282. }
  283. }
  284. if(dragData[i].link.length > 0) {
  285. for(var j = 0; j < dragData[i].link.length; j++) {
  286. dragData[i].link[j].mx1 = dragData[i].outx;
  287. dragData[i].link[j].my1 = dragData[i].link[j].dy > dragData[i].outy ? dragData[i].outy + (dragData[i].link[j].dy - dragData[i].outy) / 3 : dragData[i].outy - (dragData[i].link[j].dy - dragData[i].outy) / 3;
  288. dragData[i].link[j].mx2 = dragData[i].outx + (dragData[i].link[j].dx - dragData[i].outx) / 2,
  289. dragData[i].link[j].my2 = dragData[i].outy + (dragData[i].link[j].dy - dragData[i].outy) / 2
  290. }
  291. }
  292. }
  293. }
  294. reload(1);
  295. }
  296. }
  297. }
  298. var shuiguo = $('.shuiguo li');
  299. var isondrag = 0;
  300. console.log(shuiguo);
  301. for(var i = 0; i < shuiguo.length; i++) {
  302. console.log(shuiguo[i]);
  303. shuiguo[i].ondragstart = function() {
  304. console.log('东完了')
  305. drag(this.innerHTML, this.dataset.name, 'outside');
  306. }
  307. }
  308.  
  309. function insideDrag(item) {
  310. console.log(item);
  311. if(item.getAttribute('draggable')) {
  312. drag(item.dataset.label, item.className, 'inside', item.dataset.id);
  313. }
  314. }
  315.  
  316. function noDrag(item) {
  317. event.preventDefault();
  318. event.stopPropagation();
  319. console.log(item.parentNode.parentNode);
  320. var parent = item.parentNode.parentNode;
  321. parent.setAttribute('draggable', false);
  322. for(var i = 0; i < dragData.length; i++) {
  323. for(var d = 0; d < dragData[i].link.length; d++) {
  324. if(!~dragData[i].link[d].name.indexOf("|")) {
  325. dragData[i].link.splice(d, 1)
  326. }
  327. }
  328. if(parent.dataset.id == dragData[i].id) {
  329. dragData[i].draw = true;
  330. dragData[i].link.push({
  331. name: parent.dataset.id + parent.className,
  332. dx: 0,
  333. dy: 0,
  334. mx1: 0,
  335. my1: 0,
  336. mx2: 0,
  337. my2: 0
  338. });
  339. $('body').on('mouseup', function(e) {
  340. for(var j = 0; j < dragData.length; j++) {
  341. if(parent.dataset.id == dragData[j].id) {
  342. console.log('页面抬起了');
  343. dragData[j].draw = false;
  344. var $dom = $(e.target).data("drag") ? $(e.target) : $(e.target).closest("div[data-drag]");
  345. if($dom.length) {
  346. if($dom.data("drag") && $dom[0].dataset.id != dragData[j].id) { //判断是否关联另外模块,非自己
  347. $('svg').unbind('mousemove');
  348. var name = dragData[j].link[dragData[j].link.length - 1].name + "|" + $dom[0].dataset.id + $dom[0].className;
  349. var isontbe = 0; //判断是否存在关联
  350. for(let i = 0; i < dragData.length; i++) {
  351. if($dom[0].dataset.id == dragData[i].id) {
  352. for(let c = 0; c < dragData[i].linked.length; c++) {
  353. if(name == dragData[i].linked[c].name) {
  354. isontbe = 1
  355. }
  356. }
  357. if(!isontbe) { //不存在时候存入linked
  358. dragData[i].linked.push({
  359. name: name,
  360. linkedNum: parseFloat(name)
  361. })
  362. }
  363. }
  364. }
  365. if(!isontbe) { //不存在时候生成link数据
  366. dragData[j].link[dragData[j].link.length - 1].name = name;
  367. dragData[j].link[dragData[j].link.length - 1].dx = Number($dom[0].dataset.inx);
  368. dragData[j].link[dragData[j].link.length - 1].dy = Number($dom[0].dataset.iny)-10;
  369. } else {
  370. dragData[j].link.splice(dragData[j].link.length - 1, 1);
  371. }
  372. } else {
  373. dragData[j].link.splice(dragData[j].link.length - 1, 1);
  374. }
  375. } else {
  376. dragData[j].link.splice(dragData[j].link.length - 1, 1);
  377. }
  378. $('svg').unbind('mousemove');
  379. reload(1);
  380. }
  381. }
  382. $('body').unbind('mouseup');
  383. })
  384. //reload();
  385. }
  386. }
  387. }
  388.  
  389. function addDrag(item) {
  390. var parent = item.parentNode.parentNode;
  391. parent.setAttribute('draggable', true);
  392. for(var i = 0; i < dragData.length; i++) {
  393. if(parent.dataset.id == dragData[i].id) {
  394. dragData[i].draw = false;
  395. console.log(dragData[i]);
  396. }
  397. }
  398. }
  399.  
  400. function draw(item) {
  401. var parent = item.parentNode.parentNode;
  402. parent.setAttribute('draggable', true);
  403. for(var i = 0; i < dragData.length; i++) {
  404. if(parent.dataset.id == dragData[i].id) {
  405. if(dragData[i].draw == true) {
  406. $('svg').mousemove(function(e) {
  407. console.log(parent.dataset.id);
  408. for(var i = 0; i < dragData.length; i++) {
  409. if(parent.dataset.id == dragData[i].id) {
  410. console.log(dragData[i]);
  411. if(dragData[i].link[dragData[i].link.length - 1]) {
  412. dragData[i].link[dragData[i].link.length - 1].dx = e.offsetX;
  413. dragData[i].link[dragData[i].link.length - 1].dy = e.offsetY-10;
  414. dragData[i].link[dragData[i].link.length - 1].mx1 = dragData[i].outx;
  415. dragData[i].link[dragData[i].link.length - 1].my1 = dragData[i].dy > dragData[i].outy ? dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 3 : dragData[i].outy - (dragData[i].dy - dragData[i].outy) / 3;
  416. dragData[i].link[dragData[i].link.length - 1].mx2 = dragData[i].outx + (dragData[i].dx - dragData[i].outx) / 2,
  417. dragData[i].link[dragData[i].link.length - 1].my2 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 2
  418. }
  419. //////////////////////////////////////////////
  420. dragData[i].dx = e.offsetX;
  421. dragData[i].dy = e.offsetY-10;
  422. dragData[i].mx1 = dragData[i].outx;
  423. if(dragData[i].dy > dragData[i].outy) {
  424. dragData[i].my1 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 3;
  425. } else {
  426. dragData[i].my1 = dragData[i].outy - (dragData[i].dy - dragData[i].outy) / 3;
  427. }
  428. dragData[i].mx2 = dragData[i].outx + (dragData[i].dx - dragData[i].outx) / 2
  429. dragData[i].my2 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 2
  430. }
  431. }
  432. reload();
  433. console.log(2333);
  434. })
  435. } else {
  436. $('svg').unbind('mousemove');
  437. }
  438.  
  439. }
  440. }
  441. }
  442.  
  443. function noMove() {
  444. $('svg').unbind('mousemove');
  445. }
  446. $('svg').mouseup(function(e) {
  447. console.log(e.target);
  448. $('svg').unbind('mousemove');
  449. for(var i = 0; i < dragData.length; i++) {
  450. dragData[i].draw = false;
  451. }
  452. console.log('起来了');
  453. })
  454. </script>
  455. </body>
  456.  
  457. </html>

参考了http://blog.csdn.net/zhaoxiang66/article/details/78063271

根据大神的思路加强了功能,修复了bug

流程图(HTML5拖拽)的更多相关文章

  1. Html5拖拽复制

    拖拽是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖拽是标准的一部分,任何元素都能够拖拽. Html5拖拽非常常见的一个功能,但是大部分拖拽的案例都是一个剪切的过程, 项目中需 ...

  2. html5拖拽

    html5拖拽一 <!DOCTYPE html> <html> <head lang="en"> <meta charset=" ...

  3. HTML5 拖拽复制功能的实现方法

    Internet Explorer 9FirefoxOpera 12ChromeSafari 5 v1.0代码部分 <!DOCTYPE html><html><head& ...

  4. 每天一个JavaScript实例-html5拖拽

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. HTML5拖拽功能中 dataTransfer对象详解

    有了HTML5,老板再也不用担心我们的上传了,再加上有拖拽上传是不是很酷.百度一下,有关HTML5拖拽上传的文章和实例不少,都缺不了一个至关重要的东东DataTransfer.但是详细介绍的不多,尤其 ...

  6. 基于html5拖拽api实现列表的拖拽排序

    基于html5拖拽api实现列表的拖拽排序 html代码: <ul ondrop="drop_handler(event);" ondragover="dragov ...

  7. html5拖拽事件 xhr2 实现文件上传 含进度条

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. html5拖拽总结

    拖拽(Drag 和 drop)是 HTML5 标准的组成部分.拖拽是一种常见的特性,即抓取对象以后拖到另一个位置. Internet Explorer 9.Firefox.Opera 12.Chrom ...

  9. HTML5拖拽实例

    最近应该会用到,借用一下......小妹儿,你又变懒了 拖拽相关属性 draggable属性是html5的全局属性,是html5支持拖放操作的方式之一,用来表示元素是否可以被拖放,draggable有 ...

随机推荐

  1. java8 新特性Stream流的应用

    作为一个合格的程序员,如何让代码更简洁明了,提升编码速度尼. 今天跟着我一起来学习下java 8  stream 流的应用吧. 废话不多说,直入正题. 考虑以下业务场景,有四个人员信息,我们需要根据性 ...

  2. 使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴

    使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴. 1.首先在本地maven位置的配置文件setting.xml(没有 ...

  3. mybatis 自定义缓存 cache

    缓存不管哪个框架都是显得特别的重要,今天自己测试实现了mybatis自定义缓存,从而理解mybatis缓存的工作原理. 首先缓存类要实现Cache接口:具体实现如下package com.ibatis ...

  4. springmvc 文件上传异步处理

    springmvc3提供了文件上传异步处理功能,当文件上传时,controller不需要一直等到文件上传成功后再返回视图,而是先返回到servlet容器,待异步处理的线程完成后转向指定视图! 首先要在 ...

  5. java 获取请求ip,服务本地ip

    /** * 获取请求IP * * @param request * @return */ public static String getRequestIpAddress(HttpServletReq ...

  6. Redux:异步操作

    最近状态不太好,学习redux的异步操作花的时间比想象的多,这里尽量清晰简要的表述一下在redux中怎么实现异步操作. 先回顾一下同步操作: 我们用redux执行同步的时候,都是先发起一个dispat ...

  7. Enjoy the pain about Moloch

    这echo出来的啥子嘛?意思是小姐姐有自虐倾向?可若是moloch有汉化包或翻译文件,小姐姐至于这么“享受”install的过程吗? 过程都走过了,那就记录一下吧:1.找个Ubuntu镜像,阿里云镜像 ...

  8. Django模板之模板变量

    深度查询句点符(.)在模板语言中有特殊的含义. 当模版系统遇到点("."),它将以这样的顺序查询: 字典查询(Dictionary lookup) 属性或方法查询(Attribut ...

  9. scroll 方法 获取滚轴距离顶部高度

    $(window).scroll(function(){ var supportPageOffset = window.pageXOffset !== undefined; // 判断是否支持page ...

  10. HashMap的源码浅析

    一.HashMap 的数据结构 Java7 及之前主要是"数组+链表",到了 Java8 之后,就变成了"数组+链表+红黑树". 二.Java7 源码浅析: 在 ...