2014-05-24 91 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

相关问题