通过JavaScript访问SVG数据 [英] Accessing the SVG data through JavaScript

查看:139
本文介绍了通过JavaScript访问SVG数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SVG& JS。事情进展顺利,但我对数据处理感到困惑。



用户创建的对象的数据动态附加到SVG根目录。在哪里&如何存储这个SVG数据,我如何访问它?我想读取的原因是,我想将此SVG数据转换为HTML5画布(使用Google的 canvg )和



任何指导都会非常感激。



在脚本动态创建和添加新元素时,这是内存中的表示形式。在这里可以看到一个非常简单的例子:

http://phrogz.net/svg/svg_in_xhtml5.xhtml

SVG文件在面部的背景中加载一个圆,然后JavaScript动态创建眼睛和鼻子,并将它们追加为SVG元素的子项。



有三个方法我知道你可以访问这些信息,并把它放到一个画布:


  1. 你可以自己走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; //跳过任何不是元素的东西
    switch(kid.nodeName){
    case'circle':
    // ...
    break;
    case'path':
    // ...
    break;
    // ...
    }
    }

    SVG DOM参考了解有关您可用的属性和方法的更多信息,或只需使用 DOM 2 Core 方法来获取属性。



    例如,您可以访问当前(非SMIL动画) cx code>使用SVG DOM通过 var cx = kid.cx.baseVal.value; 或者你可以更简单地做 var这将是简单的,其中SVG和Canvas有类似的命令(例如

    code> rect ),一点工作,他们不完全匹配(例如 lineTo / code>命令),并为路径元素及其许多绘图命令


  2. 此答案本文,使用 XMLSerializer 接口将SVG返回为标记,使用直接作为 img 的源,然后 drawImage 到画布。使用我上面的例子:

      var svg_xml =(new XMLSerializer).serializeToString(svg); 
    console.log(svg_xml);
    //< svg xmlns =http://www.w3.org/2000/svgversion =1.1baseProfile =fullviewBox = - 350 -250 700 500>
    //< circle r =200class =facefill =red/>
    //< path fill =noneclass =facetransform =translate -396,-230)d =M487.41,282.411c-15.07,36.137-50.735,61.537-92.333,61.537 c-41.421,0-76.961-25.185-92.142-61.076/>
    //< ; circle cx = - 60cy = - 50r =20fill =#000/>
    //< circle cx =60cy = 20fill =#000/>
    //< / svg>
    var ctx = myCanvas.getContext('2d');
    var img = new Image;
    img.onload = function(){ctx.drawImage(img,0,0); };
    img.src =data:image / svg + xml; base64,+ btoa(svg_xml);

    如果你在XHTML中有SVG(如我的例子),序列化将不会捕获的SVG块(如我的例子),因此它们不会应用于图像。



    请注意,每 this question / answer (mine),你必须设置 onload 属性之前,请将 src 设置为数据网址。 >

    很遗憾,由于可能或可能不是错误,将数据URL图像绘制到画布会导致origin-clean标志设置为 false ,这意味着您将无法调用 toDataURL(),并获取您的PNG。所以...


  3. 我想你的特定需求的客户端修改SVG-> Canvas-> PNG服务器上,你将需要使用第一然后将该原始来源传递到 canvg ,然后将 svg_xml a>。


或者,您可以考虑按上述顺序将SVG序列化并直接提交给您的服务器, 服务器端SVG到PNG转化


I am working on a web application using SVG & JS. Things are going well but I am a bit confused by data handling.

The data for objects that users create is dynamically appended to the SVG root. Where & how is this SVG data stored, & how can I access it? The reason I want to read it is that I want to convert this SVG data into HTML5 canvas (using Google's canvg) and finally turn that into a png image to be stored in our db for reference.

Any guidance would be much appreciated.

解决方案

When a web browser loads an SVG file, it (roughly) parses the stream of bytes and creates a DOM structure in memory for the SVG file. It is this in-memory representation that is modified when script dynamically creates and appends new elements to the document.

You can see a very simple example of this here:
http://phrogz.net/svg/svg_in_xhtml5.xhtml
The SVG file loads with a circle in the background for the face, and then JavaScript dynamically creates the eyes and nose and appends them as children of the SVG element.

There are three ways I know of that you can access this information and get it into a canvas:

  1. You can walk the DOM of elements yourself, and issue canvas context drawing commands:

    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;
        // ...
      }
    }
    

    See the SVG DOM reference for more information on the properties and methods available to you, or just use the DOM 2 Core methods to fetch properties. For simplicity, you might want to use the latter.

    For example, you can either access the current (non-SMIL animated) cx of the circle using the SVG DOM via var cx = kid.cx.baseVal.value; or you can more simply do var cx = kid.getAttribute('cx');.

    This is going to be simple where SVG and Canvas have similar commands (e.g. rect or line), a little bit of work where they don't match exactly (e.g. circle versus arcTo, polyline as a series of lineTo commands), and a lot of work for the path element and its many drawing commands.

  2. Per this answer and this paper, use the XMLSerializer interface to get the SVG back as markup, use that directly as the source of an img, and then drawImage that to the canvas. Using my above example:

    var svg_xml = (new XMLSerializer).serializeToString(svg);
    console.log(svg_xml);
    // "<svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" viewBox="-350 -250 700 500">
    // <circle r="200" class="face" fill="red"/>
    // <path fill="none" class="face" transform="translate(-396,-230)" d="M487.41,282.411c-15.07,36.137-50.735,61.537-92.333,61.537         c-41.421,0-76.961-25.185-92.142-61.076"/>
    // <circle cx="-60" cy="-50" r="20" fill="#000"/>
    // <circle cx="60" cy="-50" r="20" fill="#000"/>
    // </svg>"
    var ctx = myCanvas.getContext('2d');
    var img = new Image;
    img.onload = function(){ ctx.drawImage(img,0,0); };
    img.src = "data:image/svg+xml;base64,"+btoa(svg_xml);
    

    If you have SVG in XHTML (as in my example), the serialization will not capture styles defined outside of the SVG block (as in my example) and so they will not be applied in the image.

    Note that per this question/answer (mine), you must set the onload attribute before you set the src to the data URL if you want IE9 compatibility.

    Unfortunately, due to what may or may not be a bug, drawing a data-url image to a canvas causes the origin-clean flag to be set to false, which means that you will not be able to call toDataURL() on the canvas and get your PNG back. So...

  3. I suppose for your specific needs of Client-modified SVG->Canvas->PNG-on-server you will need to use the first step above to serialize the svg_xml and then pass that raw source to canvg.

Alternatively, you might consider serializing the SVG per the above and submitting that directly to your server and doing server-side SVG-to-PNG conversion.

这篇关于通过JavaScript访问SVG数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆