【问题标题】:How to draw a svg in multiple locations, on top of another svg image如何在多个位置绘制 svg,在另一个 svg 图像之上
【发布时间】:2013-08-31 19:08:37
【问题描述】:

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

我已经尝试过很多其他方法。 我创建了一个 html 5 画布并使用 javascript 命令绘制了地图。然后我使用 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.

但是这种方法的结果质量很低。更不用说当你放大地图时它的质量会变得更差。

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

有没有办法使用 svg 文件来做到这一点? :)

【问题讨论】:

    标签: javascript html svg html5-canvas canvg


    【解决方案1】:

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

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

    这是一个示例 SVG 地图文件。我现在假设它嵌入在 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>
    

    “楼层”组是我们的平面图,图钉图片已包含在&lt;defs&gt; 部分。 &lt;defs&gt; 部分中定义的内容不会自行呈现。它必须在文件的其他地方引用。

    从这里你只需要一个简单的 Javascript 循环,它使用 DOM 为每个 pin 添加一个 &lt;use&gt; 元素。

    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);
    }
    

    &lt;use&gt; 允许我们引用 SVG 文件中的另一个元素。因此,我们为要放置的每个引脚创建一个&lt;use&gt; 元素。每个&lt;use&gt; 都引用了我们预定义的引脚符号。

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

    更新:

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

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

    在这里演示:http://jsfiddle.net/6cFfU/4/

    如果您甚至不允许引用地图文件中的 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 文件包装在 &lt;div&gt; 中并使用 jQuery 克隆 div,然后使用绝对定位将它们定位在正确的位置。但是,您必须担心调整地图比例等。

    【讨论】:

    • 我了解您的解决方案,但我有两个外部 svg 文件。地图也是 svg,图钉也是 svg 文件。我可以使用这两个并使用 pin.svg 在 map.svg 中显示多个位置吗?
    • 更新了如何使用外部 SVG 文件的示例。
    • 使用图像确实有效。您使用的网址是否有效?我已经用几个演示更新了我的答案,以表明(a)它确实有效,以及(b)如何使用 DOM 函数将标记添加到地图文件中。 PIN 图像只是我通过 Google 找到的一个随机 SVG 文件。
    • SVG 中一行的格式是&lt;line x1="0" y1="0" x2="100" y2="100" stroke="#0000ff" stroke-width="4"&gt;。从您已经拥有的&lt;use&gt; 示例中应该很明显,您需要做什么才能向文档添加行。我会把它作为练习留给你。
    • 您不需要使用&lt;defs&gt;&lt;use&gt; 来表示这些行。那只是为了让我们可以定义一次引脚并重新使用它。只需将线条本身添加到图表中即可。见jsfiddle.net/TAbbn
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 2015-02-08
    • 1970-01-01
    相关资源
    最近更新 更多