Javascript два объекта, пересекающиеся - PullRequest
0 голосов
/ 16 сентября 2018

Я использовал Konva для рисования, я хотел бы, чтобы стрелка «привязывалась» к другим группам или фигурам, когда кончик стрелки пересекает их и пользователь отпускает мышь.Если стрелка не пересекает единицу, она должна автоматически удалить себя.

Затем, когда группы или фигуры перемещаются, я бы хотел, чтобы кончики стрелки двигались вместе с ней.

Я нашел пример чего-то похожего, но я не уверен, как я могу объединить их, чтобы получить то, что я хочу.

Я опубликую свой текущий код ниже.

Пример ссылки

Нажмите здесь

Код

var width = height = 170;

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

var layer = new Konva.Layer();
var isDrawArrow;
var Startpos;
var Endpos;

var arrow = new Konva.Arrow({
  points: [],
  pointerLength: 10,
  pointerWidth: 10,
  fill: 'black',
  stroke: 'black',
  strokeWidth: 4
});

var circle = new Konva.Circle({
  x: stage.getWidth() / 2,
  y: stage.getHeight() / 2,
  radius: 20,
  fill: 'green'
});

var circleA = new Konva.Circle({
  x: stage.getWidth() / 5,
  y: stage.getHeight() / 5,
  radius: 30,
  fill: 'red',
  draggable: true
});

circle.on('mouseover', function() {
  document.body.style.cursor = 'pointer';
  layer.draw()
});

circle.on('mouseout', function() {
  document.body.style.cursor = 'default';
  layer.draw()
});

circle.on('mousedown touchstart', function() {
  isDrawArrow = true;
  circleA.on('dragmove', adjustPoint);
  Startpos = stage.getPointerPosition();
});

stage.addEventListener('mouseup touchend', function() {
  isDrawArrow = false;
});


stage.addEventListener('mousemove touchmove', function() {
  if (!isDrawArrow) return;
  Endpos = stage.getPointerPosition()
  
  var p = [Startpos.x, Startpos.y, Endpos.x, Endpos.y];
  arrow.setPoints(p);
  layer.add(arrow);
  layer.batchDraw();
});


circle.on('mouseup', function() {
  this.setFill('green');
  layer.batchDraw();
});


function adjustPoint(e) {
  var p = [circle.getX(), circle.getY(), circleA.getX(), circleA.getY()];

  arrow.setPoints(p);
  layer.draw();
  stage.draw();

}

function haveIntersection(r1, r2) {
  return !(
    r2.x > r1.x + r1.width ||
    r2.x + r2.width < r1.x ||
    r2.y > r1.y + r1.height ||
    r2.y + r2.height < r1.y
  );
}

layer.add(circle);
layer.add(circleA);

stage.add(layer);
adjustPoint();
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.3.0/konva.js"></script>
<div id="container"></div>

1 Ответ

0 голосов
/ 16 сентября 2018

Чтобы сделать снимок, вам нужна была функция для определения расстояния между двумя точками.
Легко сделать с помощью пифагорейского вычисления (, если вам нужна помощь, прочитайте об этом здесь ).

  • При перемещении мыши, когда вы обнаружите, что расстояние между концом стрелки и вашей точкой (в данном случае центр или красный круг) меньше, чем вы хотите, вы можете «защелкнуть», то есть то, что вы делаете в своей функции adjustPoint, это было все хорошо.

  • При наведении курсора мыши также необходимо проверить расстояние, а если оно слишком далеко, просто скройте стрелку

Рабочий код ниже:

var width = height = 170;

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

var layer = new Konva.Layer();
var isDrawArrow, Startpos, Endpos;
var snapDistance = 20;

function distance(p, c) {
  var dx = p.x - c.getX();
  var dy = p.y - c.getY();
  return Math.sqrt(dx * dx + dy * dy);
}

var arrow = new Konva.Arrow({
  points: [],
  pointerLength: 10,
  pointerWidth: 10,
  fill: 'black',
  stroke: 'black',
  strokeWidth: 4
});

var circle = new Konva.Circle({
  x: stage.getWidth() - 25,
  y: stage.getHeight() - 25,
  radius: 20,
  fill: 'green'
});

var circleA = new Konva.Circle({
  x: stage.getWidth() / 5,
  y: stage.getHeight() / 5,
  radius: 25,
  fill: 'red',
  draggable: true
});

circle.on('mousedown touchstart', function() {
  isDrawArrow = true;
  circleA.on('dragmove', adjustPoint);
  Startpos = stage.getPointerPosition();
});

stage.addEventListener('mouseup touchend', function() {
  isDrawArrow = false;
  if (distance(Endpos, circleA) > snapDistance) {
    arrow.hide();
    layer.batchDraw();
  }
});

stage.addEventListener('mousemove touchmove', function() {
  if (!isDrawArrow) return;
  Endpos = stage.getPointerPosition()

  var p = [Startpos.x, Startpos.y, Endpos.x, Endpos.y];
  arrow.setPoints(p);
  arrow.show();
  layer.add(arrow);
  layer.batchDraw();

  if (distance(Endpos, circleA) <= snapDistance) {
    adjustPoint();
    isDrawArrow = false
  }
});

function adjustPoint(e) {
  var p = [circle.getX(), circle.getY(), circleA.getX(), circleA.getY()];
  arrow.setPoints(p);
  layer.draw();
  stage.draw();
}

layer.add(circle);
layer.add(circleA);
stage.add(layer);
canvas {
  border: 1px solid #eaeaea !IMPORTANT;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.3.0/konva.js"></script>
<div id="container"></div>
...