javascript - 使用 Javascript 返回在 SVG 中单击的哪一段线

标签 javascript html web svg graphics

我有一个带有一堆不同路径的 svg。一个看起来的例子如下:

<path d="M2943648.169104896,472020.4539518825L2943637.730875478,472048.6771215173" />

我正在尝试找到一种方法来获取该行的哪一部分已被单击。我可以添加一个返回 d 的 onclick 函数,但这只会给我上面列出的完整字符串,而我只需要相关部分。例如,如果用户单击该行的第一部分,它将返回正确的坐标 (2943648.169104896,472020.4539518825),或者如果他们单击第二部分,它将显示该行中的其他坐标d 的值。其中一些路径有许多不同的线段。

我在这里找到了一个不推荐使用的方法的答案,我想知道最新的方法是什么。谢谢。

最佳答案

  • 我从另一个 SO 答案获取了 Array segments 代码的路径:
    Split a svg path d to array of objects

  • 将其包装在创建新 d 路径的代码中,逐步添加每个段

  • 用点击替换鼠标悬停

  • 删除路径段的特定颜色

  • 因为 N 条路径叠加了一些额外的抗锯齿

<svg-path-extractor colors="orange,green,blue,gold,hotpink,red">
  <div id=label></div>
  <svg viewBox="0 0 24 24">
    <path d="M 0 0 C 15 2 3 18 7 21 A 1 1 0 0 0 14 6 L 0 10 C 0 10 20 30 20 20 q -2 -4 4.13 -1 Z"></path>
    <g id=segments></g>
  </svg>
</svg-path-extractor>
<script>
  customElements.define("svg-path-extractor", class extends HTMLElement {
    connectedCallback() {
      let addPath = (d, stroke) => {}
      setTimeout(() => {
        let colors = this.getAttribute("colors").split `,`;
        let segments = [...this.querySelectorAll("svg path")].map(p => {
          return this.pathToArray(p);
        }).flat().map(seg => Object.keys(seg).map(key => seg[key]).join ` `);
        segments.map((seg, idx, arr) => {
          let d = arr.slice(0, idx + 1).join(" ");
          let p = document.createElementNS("http://www.w3.org/2000/svg", "path");
          p.setAttribute("d", d);
          p.setAttribute("fill", "none");
          p.setAttribute("stroke", colors.shift());
          p.onmouseover = (evt) => {
          let label = `${idx}d=${d}`.replace(seg,`<b>${seg}</b>`);
            this.querySelector("#label").innerHTML = label;
          }
          this.querySelector("svg #segments").prepend(p);
        })
      });
    }

    pathToArray(path) {
      if (typeof path != "string") path = path.getAttribute("d");
      const PATH_COMMANDS = {
        M: ["x", "y"],
        m: ["dx", "dy"],
        H: ["x"],
        h: ["dx"],
        V: ["y"],
        v: ["dy"],
        L: ["x", "y"],
        l: ["dx", "dy"],
        Z: [],
        C: ["x1", "y1", "x2", "y2", "x", "y"],
        c: ["dx1", "dy1", "dx2", "dy2", "dx", "dy"],
        S: ["x2", "y2", "x", "y"],
        s: ["dx2", "dy2", "dx", "dy"],
        Q: ["x1", "y1", "x", "y"],
        q: ["dx1", "dy1", "dx", "dy"],
        T: ["x", "y"],
        t: ["dx", "dy"],
        A: ["rx", "ry", "rotation", "large-arc", "sweep", "x", "y"],
        a: ["rx", "ry", "rotation", "large-arc", "sweep", "dx", "dy"]
      };
      const items = path.replace(/[\n\r]/g, '').
      replace(/-/g, ' -').
      replace(/(\d*\.)(\d+)(?=\.)/g, '$1$2 ').
      trim().
      split(/\s*,|\s+/);
      const segments = [];
      let currentCommand = '';
      let currentElement = {};
      while (items.length > 0) {
        let it = items.shift();
        if (PATH_COMMANDS.hasOwnProperty(it))
          currentCommand = it;
        else
          items.unshift(it);
        currentElement = {
          type: currentCommand
        };
        PATH_COMMANDS[currentCommand].forEach((prop) => {
          it = items.shift(); // TODO sanity check
          currentElement[prop] = it;
        });
        if (currentCommand === 'M') {
          currentCommand = 'L';
        } else if (currentCommand === 'm') {
          currentCommand = 'l';
        }
        segments.push(currentElement);
      }
      return segments
    }
  });
</script>
<style>
  body {
    font: 12px Arial
  }
  b{
    font-size:1.2em;
    color:darkgreen;
  }
  svg {
    width: 180px;
    background: pink;
  }
  svg #segments path{
    cursor:pointer;
  }

</style>

关于javascript - 使用 Javascript 返回在 SVG 中单击的哪一段线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66661128/

相关文章:

javascript - 如何在同一域上的 IE8 中访问嵌套框架的 location.href ?

javascript - 我的基于浏览器的 JS API 客户端可以工作,但处理请求似乎非常慢。问题可能是什么?

javascript - HTML 输入值属性 - 相同的输入,(显然)不同的结果

php - 传递 html 文件并使用 php 从表中获取值?

python - 使用 Mechanize 在 wordpress 上发帖

javascript - 导入没有文件名的类

html - 自定义字体无法加载,也从 fontmaker 复制了 CSS 文件,没有结果

Azure 网站 SSL - 每个证书或每个绑定(bind)的价格?

javascript - 我是否需要 Goodreads API key 来检索图书元数据?

javascript - 即使带有 CORS header ,HTML Canvas 也会受到污染