【问题标题】:how to know if any x or y point is on svg path如何知道任何 x 或 y 点是否在 svg 路径上
【发布时间】:2017-06-15 04:40:49
【问题描述】:

我有一个 svg 路径,我想知道我的鼠标是否在 svg 路径上,如果我想将光标更改为鼠标指针。

这可以通过在路径上添加鼠标悬停属性以及Recognize point(x,y) is inside svg path or outside来轻松完成 用这个解决方案。

但是有一个转折点,我在它上面有另一个透明层,因此我不能有这两种解决方案。

现在我正在让顶层不显示,它工作正常。但正因为如此,我的鼠标指针和我所做的动作(例如在鼠标移动时移动某个元素)很慢,

因此我想知道是否有任何其他更好的方法而不使显示等于无。

请找到小提琴示例,我想在 mypath 元素上将光标更改为指针,并且还希望当我将鼠标移到图层上时 myline 应该移动,我可以暂时在图层上显示为无,但是我在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>

【问题讨论】:

  • 使透明层指针事件:无
  • 这不起作用..因为我需要透明层上的鼠标移动事件。在鼠标移动时,我沿着鼠标移动一个元素,如果鼠标在底层路径上,我想改变光标到指针
  • 创建一个minimal reproducible example 并将其添加到问题中。
  • 创建示例
  • SVGGeometryElement.isPointInStroke() 目前仅在 Chrome 中实现。 Firefox,在 Edge 上没有找到任何东西。

标签: javascript jquery svg svg-path


【解决方案1】:

我使用https://bl.ocks.org/mbostock/8027637给出的解决方案,它返回x和y点到路径的距离,如果距离小于1px或笔划宽度,我认为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;
  }
}

【讨论】:

    猜你喜欢
    • 2020-08-12
    • 2014-01-14
    • 2022-01-19
    • 1970-01-01
    • 2014-12-17
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    相关资源
    最近更新 更多