2014-05-24 94 views
0

我是KineticJS的新手,並且存在可拖動形狀(圓形)和連接此形狀與另一形狀的線的問題。 移動可拖動形狀後,我無法重繪線條。也許你們中的一個可以給我一個提示。KineticJS - 可連接的可拖動形狀

這裏是我的代碼:

<!DOCTYPE html> 
<html> 
<head> 
<title></title> 
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
<script type="text/javascript" src="kinetic.js"></script> 
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'> 
<style type="text/css"> 
    html, body { 
     font-family: 'Open Sans Condensed', Arial, sans-serif; 
     font-size: 14px; 
     background: #EFEFEF; 
     width: 100%; 
     height: 100%; 
    } 

    h1 { 
     text-align: center; 
     font-size: 30px; 
    } 

    #canvas { 
     display: block; 
     background: white; 
     border: 1px solid #CCC; 
     margin: 50px auto; 
     width: 700px; 
     height: 500px; 
    } 
</style> 
</head> 
<body> 


<h1>kinetic.js test</h1> 

<div id="canvas"></div> 

<script defer="defer"> 

    /** 
    * get circle center coordinates 
    * 
    * @desc gets coordinates of circle center 
    * @param shapeId  - id of circle 
    * @returns {object} - object with x and y coordinates 
    */ 
    function getCircleCenterCoordinates(shapeId) { 

     var shape = getShapeById(shapeId); 

     if(typeof shape == 'object') { 

      return {x: shape.shape.attrs.x, y: shape.shape.attrs.y} 

     } 

    } 


    /** 
    * get shape by id 
    * 
    * @desc searches for given shape id and returns the matching 
    * @param shapeId  - id of the circle 
    * @returns {*} 
    */ 
    function getShapeById(shapeId) { 

     var result = jQuery.grep(shapes, function(e) { return e.id == shapeId; }); 

     if(result.length == 1) { 

      return result[0]; 

     } else { 

      return null; 

     } 

    } 


    /** 
    * draw 
    * 
    * @desc draw shapes 
    * @retuns {void} 
    */ 
    function draw() { 

     // add shapes to the layer and register event listeners 
     for(var i = 0; i < shapes.length; i++) { 

      var shapeObj = shapes[i]; 


      // add shape to layer 
      circleLayer.add(shapeObj.shape); 

      // register event listeners 
      for(var n = 0; n < shapeObj.events.length; n++) { 

       var eventObj = shapeObj.events[n]; 

       shapeObj.shape.on(eventObj.type, eventObj.callback); 

      } 

      // draw connections 
      for(var m = 0; m < shapeObj.connections.length; m++) { 

       var connectionObj = shapeObj.connections[m]; 

       // get ids 
       var fromId = shapeObj.id; 
       var toId = connectionObj.to; 

       // check if connection is already drawn 
       if(fromId > toId) { 

        // do not draw it again 
        continue; 

       } 

       // get coordinates 
       var fromCoordinatesObj = getCircleCenterCoordinates(fromId); 
       var toCoordinatesObj = getCircleCenterCoordinates(toId); 

       // check coordinates 
       if(typeof fromCoordinatesObj != 'object' || typeof toCoordinatesObj != 'object') { 

        // was not able to get valid coordinates 
        continue; 

       } 

       // update/set line points for this connection 
       connectionObj.line.attrs.points = [fromCoordinatesObj.x, fromCoordinatesObj.y, toCoordinatesObj.x, toCoordinatesObj.y]; 

       // add line to layer 
       connectorLayer.add(connectionObj.line); 

      } 

     } 


     // add the layers to the stage 
     stage.add(connectorLayer); 
     stage.add(circleLayer); 

    } 


    /** 
    * init shapes and layers 
    * ------------------------------------------------------------------------------------------------------- 
    */ 

    // create stage 
    var stage = new Kinetic.Stage({ 
     container: 'canvas', 
     width: 700, 
     height: 500 
    }); 


    // create layers 
    var circleLayer  = new Kinetic.Layer(); 
    var connectorLayer = new Kinetic.Layer(); 


    // define shapes 
    var shapes = [ 

     { 
      id:  1001, 
      label: 'me', 
      shape: new Kinetic.Circle({ 
       x: stage.getWidth()/2 - 200, 
       y: stage.getHeight()/2 + 100, 
       radius: 70, 
       fill: '#DDD', 
       stroke: '#EFEFEF', 
       strokeWidth: 10, 
       draggable: true 
      }), 
      events: [ 
       {type: 'mouseover', callback: function() { console.log('over 1');}} 
      ], 
      connections: [ 
       {to: 2001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}, 
       {to: 3001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}, 
       {to: 4001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})} 
      ] 

     }, 
     { 
      id:  2001, 
      label: 'you', 
      shape: new Kinetic.Circle({ 
       x: stage.getWidth()/2 + 200, 
       y: stage.getHeight()/2 + 100, 
       radius: 70, 
       fill: '#DDD', 
       stroke: '#EFEFEF', 
       strokeWidth: 10, 
       draggable: true 
      }), 
      events: [ 
       {type: 'mouseover', callback: function() { console.log('over 2');}} 
      ], 
      connections: [ 
       {to: 1001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}, 
       {to: 3001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}, 
       {to: 4001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})} 
      ] 
     }, 
     { 
      id:  3001, 
      label: 'her', 
      shape: new Kinetic.Circle({ 
       x: stage.getWidth()/2, 
       y: stage.getHeight()/2 - 100, 
       radius: 70, 
       fill: '#DDD', 
       stroke: '#EFEFEF', 
       strokeWidth: 10, 
       draggable: true 
      }), 
      events: [ 
       {type: 'mouseover', callback: function() { console.log('over 3');}} 
      ], 
      connections: [ 
       {to: 1001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}, 
       {to: 2001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})} 
      ] 
     }, 
     { 
      id:  4001, 
      label: 'his', 
      shape: new Kinetic.Circle({ 
       x: 100, 
       y: 150, 
       radius: 70, 
       fill: '#DDD', 
       stroke: '#EFEFEF', 
       strokeWidth: 10, 
       draggable: true 
      }), 
      events: [ 
       {type: 'mouseover', callback: function() { console.log('over 4');}}, 
       {type: 'dragend', callback: function() { console.log(this.getPosition()); console.log(shapes[3]); }} 
      ], 
      connections: [ 
       {to: 1001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}, 
       {to: 2001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})} 
      ] 
     } 

    ]; 


    // draw shapes 
    draw(); 

</script> 

+0

你爲什麼不使用Kinetic.Group是什麼? –

+0

Hy Elsa,謝謝你的回覆!我對KineticJs很新。在檢查手冊後,它不會像我的問題一樣解決問題。如果我將從節點A到節點B的連接線放在一個組中,另一個節點不會知道它,對吧?當節點A或節點B移動時,我只想對節點A和節點B進行「粘性」連接,節點A和節點B也會移動。謝謝。 – roman

+0

那麼如果你創建一個組,然後將它添加到你想要的任何節點(例如線條和圓圈)並將它們設置爲可正確拖動,則整個組將在您拖動一個項目時一起移動。這就是我理解你到現在要做的事情:-)不客氣,祝你好運! –

回答

0

這裏是如何保持與Kinetic.Line連接2個節點。

  • 設置連接要連接的2個節點點創建Kinetic.Line。

  • 在您希望連接的2個節點上偵聽dragmove事件。

  • 在任一節點的拖移時,重置連接線的點以再次連接到2個節點。

事情是這樣的......

NodeA.on('dragmove',function(){ 
    connectorAB.points([NodeA.x(),nodeA.y(),nodeB.x(),nodeB.y()]); 
    layer.draw(); 
}); 

// same thing for NodeB 
+0

謝謝markE!它幾乎工作。當我移動我的節點時,該線將按預期繪製,但舊線仍會出現。我是否必須清潔圖層或其他東西?我目前只是更新我的KineticJs線對象中的點,然後調用draw()函數。謝謝 – roman

+0

如果圓圈和連接器位於不同圖層中,則必須更新兩個圖層。無論如何'stage.draw()'可能工作。 – user3632710

+0

謝謝! .batchDraw()是解決方案。 – roman

相關問題