为两个形状定义x,y的线(开始/结束)连接器

Define x,y of line (start/end) connector for two shapes KineticJS/HTML5

本文关键字:的线 开始 结束 连接器 定义 两个      更新时间:2023-09-26

我在一个小项目中工作,我需要创建一个可调整大小的父形状和一个可调整大小的子形状与连接线。我在kineticjs中做的。但是,当形状调整大小时,我有一个计算x1, x2(开始连接器)和x2,y2(结束连接器)的问题。

这个计算是在函数addConnection:

var x1 = parentNode.getX() + rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getWidth()/2; 
var y2 = childNode.getY() + rectChild.getHeight()/2;

我把我的工作代码放在http://jsfiddle.net/geremora/nxDNH/

Javascript代码:

var stage = new Kinetic.Stage({
    container: 'container',
    width: 400,
    height: 400
});
var groupRoot = new Kinetic.Group({
    x: 100,
    y: 50,
    draggable: true,
});
var layer = new Kinetic.Layer();
layer.add(groupRoot);
stage.add(layer);
newRect(groupRoot);
var groupChild = new Kinetic.Group({
    x: 270,
    y: 100,
    draggable: true
});
layer.add(groupChild);
newRect(groupChild);
var con = addConnection(groupRoot, groupChild);
layer.add(con);
con.moveToBottom();
stage.draw();

function newRect(group){
        var rect = new Kinetic.Rect({
          x: 0,
          y: 0,
          width: 50,
          height: 50,
          fill: 'blue',
          stroke: 'black',
          strokeWidth: 1,
          name:'rect'
          });
          group.add(rect);
          addAnchor(group, rect.x, rect.y, 'topLeft');
          addAnchor(group, rect.getWidth(), rect.y, 'topRight');
          addAnchor(group, rect.getWidth(), rect.getHeight(), 'bottomRight');
          addAnchor(group, rect.x, rect.getHeight(), 'bottomLeft');
          group.on('dragstart', function() {
          this.moveToTop();
          });
        stage.draw();
 }
function update(activeAnchor) {
        var group = activeAnchor.getParent();
        var topLeft = group.get('.topLeft')[0];
        var topRight = group.get('.topRight')[0];
        var bottomRight = group.get('.bottomRight')[0];
        var bottomLeft = group.get('.bottomLeft')[0];
        var rect = group.get('.rect')[0];
        var anchorX = activeAnchor.getX();
        var anchorY = activeAnchor.getY();

        switch (activeAnchor.getName()) {
          case 'topLeft':
            topRight.setY(anchorY);
            bottomLeft.setX(anchorX);
            break;
          case 'topRight':
            topLeft.setY(anchorY);
            bottomRight.setX(anchorX);
            break;
          case 'bottomRight':
            bottomLeft.setY(anchorY);
            topRight.setX(anchorX); 
            break;
          case 'bottomLeft':
            bottomRight.setY(anchorY);
            topLeft.setX(anchorX); 
            break;
        }
        rect.setPosition(topLeft.getPosition());
        var width = topRight.getX() - topLeft.getX();
        var height = bottomLeft.getY() - topLeft.getY();
        if(width && height) {
          rect.setSize(width, height);
        }
}
function addAnchor(group, x, y, name) {
        var stage = group.getStage();
        var layer = group.getLayer();
        var anchor = new Kinetic.Circle({
          x: x,
          y: y,
          stroke: '#666',
          fill: '#ddd',
          strokeWidth: 1,
          radius: 5,
          name: name,
          draggable: true,
          dragOnTop: false
        });
        anchor.on('dragmove', function() {
          update(this);
          layer.draw();
        });
        anchor.on('mousedown touchstart', function() {
          group.setDraggable(false);
          this.moveToTop();
        });
        anchor.on('dragend', function() {
          group.setDraggable(true);
          layer.draw();
        });
        anchor.on('mouseover', function() {
          var layer = this.getLayer();
          document.body.style.cursor = 'pointer';
          this.setStrokeWidth(4);
          layer.draw();
        });
        anchor.on('mouseout', function() {
          var layer = this.getLayer();
          document.body.style.cursor = 'default';
          this.setStrokeWidth(2);
          layer.draw();
        });
        group.add(anchor);
}
function addConnection(parentNode, childNode){
 var connector = new Kinetic.Line({
              drawFunc: function (canvas) {
                  var rectParent = parentNode.get('.rect')[0];
                  var rectChild = childNode.get('.rect')[0];
                  var ctx = canvas.getContext();
                  var x1 = parentNode.getX() + rectParent.getWidth()/2;
                  var y1 = parentNode.getY() + rectParent.getHeight()/2;
                  var x2 = childNode.getX() + rectChild.getWidth()/2; 
                  var y2 = childNode.getY() + rectChild.getHeight()/2;
                  ctx.save();
                  ctx.strokeStyle = "red";
                  ctx.lineWidth = 3;
                  ctx.beginPath();
                  ctx.moveTo(x1, y1);
                  ctx.lineTo(x2, y2);
                  ctx.stroke();
                  ctx.restore();
              },
              points: [1, 1, 1, 3],
              stroke: "red",
              strokeWidth: 2,
              lineCap: 'round',
              lineJoin: 'round',
              opacity: 1,
              draggable: false
      });
  return connector;
}

问题:当您移动时,例如topLeft锚,您正在改变矩形的X位置。但是基团的X位置没有改变。因此,解决方案-在计算连接器位置时添加矩形位置:

var x1 = parentNode.getX() + rectParent.getX()+ rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getX()+ rectChild.getWidth()/2; 
var y2 = childNode.getY() + rectChild.getY() + rectChild.getHeight()/2;
http://jsfiddle.net/lavrton/pAQKx/