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

标签 javascript html kineticjs shapes

我正在一个小项目中工作,我需要创建一个可调整大小的父形状和一个带有连接线的可调整大小的子形状。我是在 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;
}

最佳答案

问题:当您移动时,例如左上 anchor ,您正在更改矩形的 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/

关于javascript - 为两个形状 KineticJS/HTML5 定义线(开始/结束)连接器的 x,y,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16502289/

相关文章:

javascript - 使用 mootools Fx 缩放背景大小

javascript - 使用 Bootstrap 的 Metro 磁贴布局?

javascript - 如何通过 Javascript 将 div 中的某些 HTML 代码替换为另一个新的 HTML 代码

javascript - 在 HTML5 Canvas 上删除部分图像?

javascript - kinetic.js 绝对线位置而不是相对位置

javascript - 设置文本颜色并根据数据文本更改图标

javascript - Safari iOS 不加载 Javascript 文件?

javascript - 使用 onClick 提交 PHP 表单

javascript - Angular/Javascript - 隐藏带有 id onclick 的按钮

javascript - Kineticjs 按 CSS 宽度和高度比例缩放 Canvas 。发生鼠标事件破坏