javascript - 如何在多个位置绘制 svg,在另一个 svg 图像之上

标签 javascript html svg html5-canvas canvg

我使用 MS Visio 2013 绘制了超市的平面图。我已将其转换为 svg 文件。 我想要做的是使用另一个 svg 文件来确定楼层 map 的某些位置。

我已经通过许多其他方式尝试过了。 我创建了一个 html 5 Canvas 并使用 javascript 命令绘制 map 。然后我使用 svg 图像显示位置。

ctx.drawSvg('location.svg', x_coordinate , y_coordinate , 10, 14);

//x_coordinate,y_coordinate is defining the multiple locations which this location.svg file will be drawn.

但该方法的结果质量很低。更不用说当您放大 map 时,它的质量会变得更差。

我知道将 svg 嵌入到 html 页面或使用 svg 文件作为背景的方法。但是对于这两个,我如何使用另一个 svg 文件来查明多个位置?

有什么方法可以使用 svg 文件做到这一点吗? :)

最佳答案

这其实很简单。有几种方法可以做到这一点,但以下方法可能是最简单的方法之一。它根本不使用 Canvas,只是纯 SVG。

我假设当您说“pin”是另一个文件时,这并不是一个严格的要求。 IE。您没有理由不在 map SVG 文件中包含图钉图片。

这是一个示例 SVG map 文件。我现在假设它嵌入在 HTML 文件中,但外部文件应该也能正常工作。

<html>
<body>
<svg id="map" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="500" height="400" viewBox="0 0 500 400">

  <defs>
      <!-- Define our map "pin". Just a circle in this case.
           The circle is centred on (0,0) to make positioning at the destination point simpler. -->
      <g id="pin">
          <circle cx="0" cy="0" r="7" fill="white" stroke="green" stroke-width="2"/>
      </g>
  </defs>

  <!-- A simple floorplan map -->
  <g id="floor" fill="#ddd" stroke="black" stroke-width="3">
      <rect x="50" y="50" width="200" height="150" />
      <rect x="100" y="200" width="150" height="150" />
      <rect x="250" y="100" width="200" height="225" />
  </g>

  <!-- A group to hold the created pin refernces. Not necessary, but keeps things tidy. -->
  <g id="markers">
  </g>
</svg>
</body>
</html>

“floor”组是我们的平面图,图钉图像已包含在 <defs> 中部分。 <defs> 中定义的内容节本身不呈现。必须在文件的其他地方引用它。

从这里开始,您只需要一个简单的 Javascript 循环,它使用 DOM 添加一个 <use>每个引脚的元素。

var  markerPositions = [[225,175], [75,75], [150,225], [400,125], [300,300]];

var svgNS = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";

for (var i=0; i<markerPositions.length; i++) {
    // Create an SVG <use> element
    var  use = document.createElementNS(svgNS, "use");
    // Point it at our pin marker (the circle)
    use.setAttributeNS(xlinkNS, "href", "#pin");
    // Set it's x and y
    use.setAttribute("x", markerPositions[i][0]);
    use.setAttribute("y", markerPositions[i][1]);
    // Add it to the "markers" group
    document.getElementById("markers").appendChild(use);
}

<use>允许我们引用 SVG 文件中的另一个元素。所以我们创建一个 <use>我们要放置的每个引脚的元素。每个<use>引用我们预定义的 pin 符号。

这是一个演示:http://jsfiddle.net/6cFfU/3/

更新:

要使用外部“pin”文件,从图像中引用它应该可行。

<g id="pin">
  <image xlink:href="pin.svg"/>
</g>

此处演示:http://jsfiddle.net/6cFfU/4/

如果您甚至不允许引用您的 map 文件中的 pin 文件。然后您只需要使用一些 DOM 操作来插入这个标记定义。像这样的东西:

var  grp = document.createElementNS(svgNS, "g");
grp.id = "pin";
var  img = document.createElementNS(svgNS, "image");
img.setAttributeNS(xlinkNS, "href", "pin.pvg");
grp.appendChild(img);
document.getElementsByTagName("defs")[0].appendChild(grp);

此处演示:http://jsfiddle.net/7Mysc/1/

这是假设您想要走纯 SVG 路线。还有其他方法。例如,您可以使用 HTML 做类似的事情。将您的 PIN 文件包装在 <div> 中并使用 jQuery 克隆 div,然后使用绝对定位将它们定位在正确的位置。然而,您必须担心调整 map 比例等。

关于javascript - 如何在多个位置绘制 svg,在另一个 svg 图像之上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18492492/

相关文章:

javascript - Storybook:无法使用 @svgr/webpack 在 svg 文件上执行 'createElement'

javascript - 如何让瓶子看起来静止不动

css - 使用 css 插入 Logo

javascript - [javascript]IE中所有的函数都在哪里?

html - 如何让 flex 元素占据这些空间?

javascript - 用于在 JavaScript 中捕获 Heredoc 的正则表达式

javascript - Nodejs 中的 Passport 身份验证

ios - 如何让 iOS 缓存带有查询参数的 HTML5 文档?

javascript - Spotify 获取艺术家信息 - 错误 503 服务

javascript - 在Electron 1.X版中,如何从一个BrowserWindow发出事件并在另一个BrowserWindow中使用它?