简体   繁体   中英

KineticJS: Curved line between two draggable shapes

I am using KineticJS in my project. I need to connect two shapes using a curved line. One of the shapes can be dragged. I am able to put the curved line between shapes. The problem arises when user starts dragging the shapes. The requirement is that it should be properly curved (please refer to screen shots), irrespective of distance between them and their position with respect to each other. I am doing this:

var utils = {
  _getCenter: function(x1, y1, x2, y2) {
    return {
      x: (x1 + x2) / 2,
      y: (y1 + y2) / 2
    }
  },
  // Converts from degrees to radians.
  _radians: function(degrees) {
    return degrees * Math.PI / 180;
  },
  // Converts from radians to degrees.
  _degrees: function(radians) {
    return radians * 180 / Math.PI;
  }
};

function amplitude(point) {
  var rad_90 = utils._radians(90);
  var rad_45 = utils._radians(45);
  var rad_60 = utils._radians(60);
  console.log(rad_90);
  return {
    x: point.x * Math.cos(rad_60),
    y: point.y * Math.sin(rad_60)
  };
}
var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Kinetic.Stage({
  container: 'container',
  width: width,
  height: height
});

var layer = new Kinetic.Layer();

var circle = new Kinetic.Circle({
  x: stage.getWidth() / 2,
  y: stage.getHeight() / 2,
  radius: 20,
  fill: 'red',
  stroke: 'black',
  strokeWidth: 2
});
var attachedCircle = new Kinetic.Circle({
  x: stage.getWidth() / 4,
  y: stage.getHeight() / 4,
  radius: 20,
  fill: 'red',
  stroke: 'black',
  strokeWidth: 2,
  draggable: true
});
var center = amplitude(utils._getCenter(circle.getX(), circle.getY(), attachedCircle.getX(), attachedCircle.getY()));

var line = new Kinetic.Line({
  points: [circle.getX(), circle.getY(), center.x, center.y, attachedCircle.getX(), attachedCircle.getY()],
  fill: 'black',
  stroke: 'green',
  strokeWidth: 3,
  /*
   * line segments with a length of 33px
   * with a gap of 10px
   */
  dash: [33, 10],
  id: 'line',
  tension: 0.5
});
attachedCircle.on('dragmove', function(e) {
  var targetCircle = e.target;
  var tempCenter = amplitude(utils._getCenter(circle.getX(), circle.getY(), targetCircle.getX(), targetCircle.getY()));
  console.log(tempCenter);
  line.setPoints([circle.getX(), circle.getY(), tempCenter.x, tempCenter.y, targetCircle.getX(), targetCircle.getY()]);
});




// add the shape to the layer
layer.add(line);

layer.add(attachedCircle);
layer.add(circle);
// add the layer to the stage
stage.add(layer);

I don't know what I am missing. I have created the plunkr for this .

To define you amplitude function you need to use two input points:

function amplidure2(p1, p2) {
  var alpha = Math.atan((p1.x - p2.x) / (p1.y - p2.y)) + Math.PI / 2;
  if (p1.y < p2.y) {
    alpha += Math.PI;
  }
  var center = utils._getCenter(p1.x, p1.y, p2.x, p2.y);
  var r = 50;
  return {
    x: center.x + r * Math.sin(alpha),
    y: center.y + r * Math.cos(alpha)
  }
}

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM