Как проверить, что мышь находится над крестом на холсте? - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь показать, находится ли мышь над какой-либо из двух линий, образующих форму креста. Сейчас это работает, если вы наведите курсор мыши на нижнюю правую часть 'X' . Но не на всех

const x1 = 50;
const y1 = 50;

const x2 = 100;
const y2 = 100;

const xdiff = x2 - x1;
const ydiff = y2 - y1;

function drawX(x, y) {
ctx.beginPath();

ctx.moveTo(x - xdiff, y - ydiff);
ctx.lineTo(x + xdiff, y + ydiff);
ctx.stroke();

ctx.moveTo(x + xdiff, y - ydiff);
ctx.lineTo(x - xdiff, y + ydiff);
ctx.stroke();
}


const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");

 
drawX(x1,y1);

function myFunction(e) {
const x = e.clientX;
const y = e.clientY;
//const coor = "Coordinates: (" + x + "," + y + ")";
const overShape = () => ( (x > x1 && x < (x1 +xdiff)) && (y > y1 && y < (y1 +ydiff)) ) ;

console.log('I am over X, ', overShape() )

}
<canvas id="myCanvas" width="300" height="150" onmousemove="myFunction(event)" style="border:1px solid #d3d3d3;">
  Your browser does not support the HTML5 canvas tag.</canvas>

Ответы [ 3 ]

1 голос
/ 19 июня 2019

Вы можете решить эту проблему, проверив цвет в текущей позиции мыши.Если он черный, вы, скорее всего, дотронетесь до X. Конечно, это сработает, если на вашем изображении нет других черных цветов, поэтому лучший способ сделать это - использовать математические вычисления.

Итак, сначала определите начало иКонечные точки ваших линий в виде отдельных точек - таким образом, мы можем использовать их для расчета.

const pointA={x:0,y:0};
const pointB={x:100,y:100};
const pointC={x:100,y:0};
const pointD={x:0,y:100};

Теперь, чтобы проверить, что вы находитесь на одной из линий, эти четыре точки образуют, вы можете использовать эту формулу:

var treshold=0.01;
var onFirstLine=distance(pointA, mousePosition) + distance(pointB, mousePosition)-distance(pointA, pointB)<treshold;

Здесь мы складываем расстояния от точки A и точки B до положения мыши, и если результат будет равен расстоянию от точки A до точки B, мы обнаружили попадание.Проблема в том, что нам нужно сделать это очень точно, поэтому мы вычитаем расстояние и сравниваем его с порогом.

Вот полный пример:

const pointA={x:0,y:0};
const pointB={x:100,y:100};
const pointC={x:100,y:0};
const pointD={x:0,y:100};

function drawX(x, y) {
  ctx.beginPath();

  ctx.moveTo(pointA.x, pointA.y);
  ctx.lineTo(pointB.x, pointB.y);
  ctx.stroke();

  ctx.moveTo(pointC.x, pointC.y);
  ctx.lineTo(pointD.x, pointD.y)
  ctx.stroke();
}

const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");

drawX();

function myFunction(e) {
  var tempPoint = {
    x: e.offsetX,
    y: e.offsetY
  };
  var treshold = 0.01;
  if (distance(pointA, tempPoint) + distance(pointB, tempPoint) - distance(pointA, pointB) < treshold || distance(pointC, tempPoint) + distance(pointD, tempPoint) - distance(pointC, pointD) < treshold) {
    console.log("you're touching X")
  } else {
    console.log("you're NOT touching X")
  }
}

function distance(locPointA, locPointB) {
  return Math.sqrt(Math.pow(locPointB.x - locPointA.x, 2) + Math.pow(locPointB.y - locPointA.y, 2));
}
<canvas id="myCanvas" width="300" height="150" onmousemove="myFunction(event)" style="border:1px solid #d3d3d3;">
  Your browser does not support the HTML5 canvas tag.</canvas>
1 голос
/ 19 июня 2019

Вместо

const overShape = () => ( (x > x1 && x < (x1 +xdiff)) && (y > y1 && y < (y1 +ydiff)) ) ;

Ваши границы должны быть проверены как

const overShape = () => ( (x  > (x1 - xdiff) && x < (x1 +xdiff)) && (y > (y1 - ydiff) && y < (y1 +ydiff)) ) ;

const x1 = 50;
const y1 = 50;

const x2 = 100;
const y2 = 100;

const xdiff = x2 - x1;
const ydiff = y2 - y1;

function drawX(x, y) {
  ctx.beginPath();

  ctx.moveTo(x - xdiff, y - ydiff);
  ctx.lineTo(x + xdiff, y + ydiff);
  ctx.stroke();

  ctx.moveTo(x + xdiff, y - ydiff);
  ctx.lineTo(x - xdiff, y + ydiff);
  ctx.stroke();
}


const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");


drawX(x1, y1);

function myFunction(e) {
  const x = e.clientX;
  const y = e.clientY;
  //const coor = "Coordinates: (" + x + "," + y + ")";
  const overShape = () => ((x > (x1 - xdiff) && x < (x1 + xdiff)) && (y > (y1 - ydiff) && y < (y1 + ydiff)));

  console.log('I am over X, ', overShape())

}
<canvas id="myCanvas" width="300" height="150" onmousemove="myFunction(event)" style="border:1px solid #d3d3d3;">
  Your browser does not support the HTML5 canvas tag.</canvas>
0 голосов
/ 19 июня 2019

Использование решения @Kaiido Это лучший способ решить эту проблему

const x1 = 50;
const y1 = 50;

const x2 = 100;
const y2 = 100;

const xdiff = x2 - x1;
const ydiff = y2 - y1;

const threshold = 20;

let path;

function drawX(x, y) {
  path = new Path2D();
  path.moveTo(x - xdiff, y - ydiff);
  path.lineTo(x + xdiff, y + ydiff);
  path.moveTo(x + xdiff, y - ydiff);
  path.lineTo(x - xdiff, y + ydiff);
  ctx.stroke(path);
}


const c = document.getElementById("canvas");
const ctx = c.getContext("2d");


drawX(x1, y1);

canvas.onmousemove = ({
  offsetX,
  offsetY
}) => {
  ctx.lineWidth = threshold;
  console.log('I am over X, ', ctx.isPointInStroke(path, offsetX, offsetY))
}
canvas {
  border: 1px solid #d3d3d3;
  width: 300px;
  height: 150;
}
<canvas id="canvas">
      Your browser does not support the HTML5 canvas tag.</canvas>
...