1. 程式人生 > >利用jsplumb和碰撞檢測自動生成流程圖

利用jsplumb和碰撞檢測自動生成流程圖

for ans ont != 500px cat clone tran tex

使用jsplumb構建流程圖模型時,有一個需求要求,選項可以從選項表中拖拽到指定容器,並且兩個選項要接觸到的時候才能連接起來,不接觸不能連接。效果圖如下技術分享圖片

略醜~

因為這裏用到了拖拽,拖放功能,所以用到的有jquery,jquery-ui,jsplumb,考慮到兼容ie8,用到的是jsplumb-1.7.10版本。
首先簡單的布局

<style>
html,body {
    height:100%;
    padding:0;
    margin:0;
}
    #container{
        width:200px;
        height:500px;
    
        background
:#eee; float:left; } #container .node { width:50px; height:50px; border:1px solid #000; margin-top:20px; margin-left:20px; z-index:999; } #wrapper { width:500px; height:500px; margin-left:200px; border
:1px solid #5182E4; background:#ddd; position:relative; } </style> <div id="container"> <div class="node" id="Node1">1</div> <div class="node" id="Node2">2</div> <div class="node" id="Node3">3</div> </
div> <div id="wrapper"> </div>

接下來就是功能實現,第一步拖拽

 $(‘#container .node‘).draggable({
          helper:‘clone‘,
          revert: ‘invalid‘,//放置不到位自動恢復原位     
          stop:function(event,ui){
            //準備碰撞檢測所需要的條件
              var r1 = ui.offset.left+ui.helper.context.offsetWidth;
              var l1 = ui.offset.left;
              var b1 = ui.offset.top+ui.helper.context.offsetHeight;
              var t1 = ui.offset.top;

              var L = $(‘#wrapper‘)[0].offsetLeft;

              var T = $(‘#wrapper‘)[0].offsetTop;

              var id= ui.helper.context.id;

              var len = $(‘#wrapper‘).children(‘.node‘).length;

        
             var uid = ‘dragNode‘+len;

              var arr=[];
          
              $(‘#wrapper‘).children(‘.node‘).each(function(){

                  
                  var json={};

                  json.id = $(this).context.id;
                  json.left = $(this).context.offsetLeft+L;
                  json.right = $(this).context.offsetLeft+L+$(this)[0].offsetWidth;
                  json.top = $(this).context.offsetTop+T;
                  json.bottom = $(this).context.offsetTop+T+$(this)[0].offsetHeight;

                  arr.push(json);

              });

        
            //jsplumb 設置樣式
              var common = {
                          anchors:[‘Left‘,‘Right‘],
                          endpoint:[‘Dot‘,{radius:2}],
                      
                          paintStyle:{
                            strokeStyle:‘#1e8151‘,
                            fillStyle:‘transparent‘,
                            radius:2,
                            lineWidth:2,
                        }
                    
                          
                      };

          

              for(var i=0;i<arr.length;i++){
                  if(arr[i].id!=uid){

                      var id3= arr[i].id;
                    //碰撞檢測
                      if(r1<arr[i].left||b1<arr[i].top||l1>arr[i].right||t1>arr[i].bottom){

                          $(‘#‘+id3).css(‘background‘,‘red‘)
                          console.log(2);
                      }else {
                          $(‘#‘+id3).css(‘background‘,‘green‘);

                      //碰撞後,連接到一起
                        jsPlumb.connect({
                            source:uid,
                            target:arr[i].id,
                            scope:‘‘,
                            connector:[
                                ‘Straight‘,
                                {
                                    stub:[10,10],
                                    gap:0
                                }
                            ],
                            overlays:[
                                [‘Arrow‘,{width:10,height:10,location:0.9}],
                                [‘Label‘,{label:‘hello‘,location:0.5}]
                            ]
                        },common);

                        var lef = ui.offset.left+50;

                        //jsPlumb 動畫,選項連接後自動分離開一段距離

                        jsPlumb.animate(uid,{left:lef},{duration:350,easing:‘easeOutBack‘});

                      }

                  }
              }

    
          }
        });

選項可以拖拽後,還要有放置的地兒,當然draggable裏也可以,這裏使用droppable;

$(‘#wrapper‘).droppable({
            
            drop:function(event,ui){

                var leng = $(‘#wrapper‘).children(‘.node‘).length+1;

                 var arr=[];

                var id = "dragNode"+leng;

                var id2 = ui.draggable[0].id;

                var left = parseInt(ui.offset.left-$(this).offset().left);
                var top = parseInt(ui.offset.top-$(this).offset().top);

                var width = ui.draggable[0].clientWidth;
                var height = ui.draggable[0].clientHeight;
            
        

                var len = $(this).children(‘.node‘).length;

            //判斷容器內拖拽的是否重復
                if(!len){
                    $(this).append($(‘<div style="position:absolute;" class="node" id="‘+id+‘">‘+$(ui.helper).html()+‘</div>‘));
                    $(‘#‘+id).css(‘left‘,left).css(‘top‘,top);
                    $(‘#‘+id).css(‘width‘,width).css(‘height‘,height);

                    $(‘#‘+id).css(‘border‘,‘1px solid #000‘);
                }else {
                        $(this).children(‘.node‘).each(function(){
                             // console.log($(this).html());

                             arr.push($(this).html());

                        });

                    

                        if(arr.indexOf($(ui.helper).html())>-1){
                            alert(‘已存在!‘);
                            return;
                        }else {
                            $(this).append($(‘<div style="position:absolute;" class="node" id="‘+id+‘">‘+$(ui.helper).html()+‘</div>‘));
                            $(‘#‘+id).css(‘left‘,left).css(‘top‘,top);
                            $(‘#‘+id).css(‘width‘,width).css(‘height‘,height);

                            $(‘#‘+id).css(‘border‘,‘1px solid #000‘);
                        }
                }

            
                arr.push(id2);
            
            //限制容器內選項的拖拽範圍
                jsPlumb.draggable(id,{
                    containment:‘parent‘
                });

            //
                var connectorPaintStyle={
                    lineWidth:4,
                    strokeStyle:‘#61B7CF‘,
                    joinstyle:‘round‘,
                    
                };
                var connectorHoverStyle = {
                    lineWidth:4,
                    strokeStyle:‘#216477‘,
                    
                };
                var defaults = {
                    endpoint:[‘Dot‘,{radius:2}],
                    connectorStyle:connectorPaintStyle,
                    connectorHoverStyle:connectorHoverStyle,
                    paintStyle:{
                        strokeStyle:‘#1e8151‘,
                        fillStyle:‘transparent‘,
                        radius:2,
                        lineWidth:2,

                    },
                    isSource:true,
                    connector:[‘Flowchart‘,{stub:[40,60],gap:5,cornerRadius:5,alwaysRespectStubs:true}],
                    isTarget:true,
                    maxConnections:-1,
                    connectorOverlays:[
                        [‘Arrow‘,{width:10,length:10,location:1}],
                        [‘Label‘,{label:‘yes‘,width:10,height:10}]
                        ]
                };

                //在添加連接點
                jsPlumb.addEndpoint(id,{anchors:‘TopCenter‘},defaults);
                jsPlumb.addEndpoint(id,{anchors:‘BottomCenter‘},defaults);
                jsPlumb.addEndpoint(id,{anchors:‘RightMiddle‘},defaults);
                jsPlumb.addEndpoint(id,{anchors:‘LeftMiddle‘},defaults);


    

                
            }
            
        });

利用jsplumb與碰撞檢測,自動生成流程圖的過程基本就這樣了。

利用jsplumb和碰撞檢測自動生成流程圖