zoukankan      html  css  js  c++  java
  • 流程图(HTML5拖拽)

      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

  • 相关阅读:
    Oil Deposits UVA
    工作区的颜值选择(中等)
    计算机网络 自定向下方法1.1-1.2
    工作区的颜值选择(简单)
    排序算法之简单选择排序
    排序算法之直接插入排序
    查找算法之查找一个数组中只出现过一次的数
    查找算法之查找一个数组中两两数字相同,只有其中两个数字是不一样的,将其找出
    Linux
    ASP.NET Web – 状态管理
  • 原文地址:https://www.cnblogs.com/zjhr/p/8514001.html
Copyright © 2011-2022 走看看