通过JavaScript访问SVG数据

通过JavaScript访问SVG数据,javascript,html,canvas,svg,Javascript,Html,Canvas,Svg,我正在使用SVG和JS开发一个web应用程序。事情进展顺利,但我对数据处理有点困惑 用户创建的对象的数据将动态附加到SVG根目录。SVG数据存储在何处以及如何访问?我之所以想读它,是因为我想将这些SVG数据转换成HTML5画布(使用谷歌的),最后将其转换成png图像,存储在数据库中供参考 任何指导都将不胜感激。当web浏览器加载SVG文件时,它(粗略地)解析字节流,并在内存中为SVG文件创建DOM结构。当脚本动态地创建新元素并将其附加到文档中时,会修改内存中的表示 您可以在这里看到一个非常简单的

我正在使用SVG和JS开发一个web应用程序。事情进展顺利,但我对数据处理有点困惑

用户创建的对象的数据将动态附加到SVG根目录。SVG数据存储在何处以及如何访问?我之所以想读它,是因为我想将这些SVG数据转换成HTML5画布(使用谷歌的),最后将其转换成png图像,存储在数据库中供参考


任何指导都将不胜感激。

当web浏览器加载SVG文件时,它(粗略地)解析字节流,并在内存中为SVG文件创建DOM结构。当脚本动态地创建新元素并将其附加到文档中时,会修改内存中的表示

您可以在这里看到一个非常简单的例子:

SVG文件以一个圆圈作为人脸的背景加载,然后JavaScript动态创建眼睛和鼻子,并将它们作为SVG元素的子元素附加

我知道有三种方法可以访问此信息并将其放入画布:

  • 您可以自己遍历元素的DOM,并发出画布上下文绘制命令:

    var svg = document.getElementsByTagName('svg')[0];
    var kids = svg.childNodes;
    for (var i=0,len=kids.length;i<len;++i){
      var kid = kids[i];
      if (kid.nodeType!=1) continue; // skip anything that isn't an element
      switch(kid.nodeName){
        case 'circle':
          // ...
        break;
        case 'path':
          // ...
        break;
        // ...
      }
    }
    
    如果在XHTML中有SVG(如我的示例所示),序列化将不会捕获SVG块之外定义的样式(如我的示例所示),因此它们不会应用于图像中

    请注意,根据(我的),如果您想要IE9兼容性,则必须在将
    src
    设置为数据URL之前设置
    onload
    属性

    不幸的是,由于可能的或可能的原因,将数据url图像绘制到画布会导致原点清除标志设置为
    false
    ,这意味着您将无法在画布上调用
    toDataURL()
    ,并取回PNG。所以

  • 我想,对于服务器上客户端修改的SVG->Canvas->PNG的特定需求,您需要使用上面的第一步来序列化
    SVG\u xml
    ,然后将原始源代码传递给


  • 另一方面,您可以考虑将SVG按上述顺序序列化,并直接提交给您的服务器并执行.

    < P> @ PHLogz中提到的WebKIT bug似乎已被固定在更近的版本中,因此我发现了一个不需要手动解析的解决方案是

    // from http://bl.ocks.org/biovisualize/1209499
    // via https://groups.google.com/forum/?fromgroups=#!topic/d3-js/RnORDkLeS-Q
    var xml = d3.select("svg")
      .attr("title", "test2")
      .attr("version", 1.1)
      .attr("xmlns", "http://www.w3.org/2000/svg")
      .node().parentNode.innerHTML;
    
    // from http://webcache.googleusercontent.com/search?q=cache:http://phpepe.com/2012/07/export-raphael-graphic-to-image.html
    // via http://stackoverflow.com/questions/4216927/problem-saving-as-png-a-svg-generated-by-raphael-js-in-a-canvas
    var canvas = document.getElementById("myCanvas")
    canvg(canvas, svgfix(xml));
    document.location.href = canvas.toDataURL();
    
    这需要
    并使用d3.js获取svg源代码,这在没有d3.js的情况下也应该是可行的(但这需要注意添加所需的元数据,如果缺少这些元数据,可能会导致问题)。

    精彩答案!!您还可以指出为什么var svg=document.getElementById('svg')之类的东西不起作用……@keybrbdbasher只要找到就行了,假设您的页面上有
    。如果没有ID,可以使用
    getElementsByTagName('svg')[0]
    ,或者更简单地说(在现代浏览器上)
    var svg=document.querySelector('svg')
    // from http://bl.ocks.org/biovisualize/1209499
    // via https://groups.google.com/forum/?fromgroups=#!topic/d3-js/RnORDkLeS-Q
    var xml = d3.select("svg")
      .attr("title", "test2")
      .attr("version", 1.1)
      .attr("xmlns", "http://www.w3.org/2000/svg")
      .node().parentNode.innerHTML;
    
    // from http://webcache.googleusercontent.com/search?q=cache:http://phpepe.com/2012/07/export-raphael-graphic-to-image.html
    // via http://stackoverflow.com/questions/4216927/problem-saving-as-png-a-svg-generated-by-raphael-js-in-a-canvas
    var canvas = document.getElementById("myCanvas")
    canvg(canvas, svgfix(xml));
    document.location.href = canvas.toDataURL();