как узнать, находится ли какая-либо точка x или y на пути svg

у меня есть путь svg, и я хочу знать, находится ли моя мышь на пути svg или нет, если это так, я хочу изменить курсор мыши на указатель.

Это можно было бы легко сделать, добавив свойство наведения мыши на путь, а также с помощью Распознать точку (x, y) внутри пути svg или снаружи с помощью этого решения.

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

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

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

пожалуйста, найдите пример скрипки, я хочу изменить курсор на указатель, когда он находится на элементе mypath, а также хочу, чтобы моя линия двигалась, когда я двигаю мышью по слою, я могу пока не отображать на слое, но я заметил на firefox, движение линии не такое плавное,

https://jsfiddle.net/shyam_bhiogade/9a7zuou2/6/

<svg width="400" height="400">
  <g>
    <path id="mypath" d="M10 200 L200 90 L200 200" fill="transparent" stroke="black" stroke-width="5" />
    <rect class="interactiveArea" width="500" height="500" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0);opacity:0.2" />
    <line id="myline" x1="20" y1="0" x2="20" y2="400" stroke-width="2" stroke="black" />
  </g>
</svg>

person shyam_    schedule 08.06.2017    source источник
comment
сделать прозрачный слой события-указателя: нет   -  person Robert Longson    schedule 08.06.2017
comment
это не сработает... потому что мне нужно событие перемещения мыши на прозрачном слое. При перемещении мыши я перемещаю элемент вдоль мыши, а также, если мышь находится на основном пути, я хочу изменить курсор на указатель   -  person shyam_    schedule 08.06.2017
comment
создайте минимально воспроизводимый пример и добавьте его к вопросу.   -  person Robert Longson    schedule 08.06.2017
comment
Создал пример   -  person shyam_    schedule 08.06.2017
comment
SVGGeometryElement.isPointInStroke() пока реализован только в Chrome. Firefox ничего не нашел в Edge.   -  person ccprog    schedule 08.06.2017
comment
мне нужно то же самое, но он должен поддерживать все браузеры. вы найдете реализацию для него где-нибудь   -  person shyam_    schedule 08.06.2017
comment
нашел решение.   -  person shyam_    schedule 14.06.2017


Ответы (1)


Я использовал решение, приведенное на странице https://bl.ocks.org/mbostock/8027637. , он возвращает расстояние точек x и y от пути, если расстояние меньше 1 пикселя или ширины штриха, я считаю, что точки x и y находятся на пути.

   function closestPoint(pathNode, point) {
  var pathLength = pathNode.getTotalLength(),
      precision = 8,
      best,
      bestLength,
      bestDistance = Infinity;

  // linear scan for coarse approximation
  for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) {
    if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) {
      best = scan, bestLength = scanLength, bestDistance = scanDistance;
    }
  }

  // binary search for precise estimate
  precision /= 2;
  while (precision > 0.5) {
    var before,
        after,
        beforeLength,
        afterLength,
        beforeDistance,
        afterDistance;
    if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) {
      best = before, bestLength = beforeLength, bestDistance = beforeDistance;
    } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) {
      best = after, bestLength = afterLength, bestDistance = afterDistance;
    } else {
      precision /= 2;
    }
  }

  best = [best.x, best.y];
  best.distance = Math.sqrt(bestDistance);
  return best;

  function distance2(p) {
    var dx = p.x - point[0],
        dy = p.y - point[1];
    return dx * dx + dy * dy;
  }
}
person shyam_    schedule 14.06.2017