Zai*_*ain 11 javascript html5 svg canvas
我正在使用SVG和JS开发Web应用程序.事情进展顺利,但我对数据处理有点困惑.
用户创建的对象的数据会动态附加到SVG根目录.存储此SVG数据的位置和方式,以及如何访问它?我想要阅读它的原因是我想将这个SVG数据转换为HTML5画布(使用Google的canvg),最后将其转换为png图像以存储在我们的数据库中以供参考.
任何指导都将非常感谢.
Phr*_*ogz 20
当Web浏览器加载SVG文件时,它(粗略地)解析字节流并在内存中为SVG文件创建DOM结构.当脚本动态创建新元素并将其附加到文档时,会修改此内存中表示.
你可以在这里看到一个非常简单的例子:
http://phrogz.net/svg/svg_in_xhtml5.xhtml
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;
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
有关可用的属性和方法的更多信息,请参阅SVG DOM参考,或者仅使用DOM 2 Core方法获取属性.为简单起见,您可能希望使用后者.
例如,您可以cx使用SVG DOM 访问圆圈的当前(非SMIL动画),var cx = kid.cx.baseVal.value;或者您可以更简单地访问var cx = kid.getAttribute('cx');.
这将是简单的,其中SVG和Canvas也有类似的命令(例如rect或line),工作一点点,他们不完全匹配(例如circle对arcTo,polyline为一系列的lineTo命令),并为大量的工作path元素,它的许多绘图命令.
根据这个答案和本文,使用XMLSerializer接口将SVG作为标记返回,直接将其用作a的源img,然后drawImage将其用于画布.使用我上面的例子:
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);
Run Code Online (Sandbox Code Playgroud)
如果您在XHTML中使用SVG(如我的示例所示),序列化将不会捕获在SVG块之外定义的样式(如我的示例中所示),因此它们将不会应用于图像中.
请注意,根据此问题/答案(我的),如果您想要IE9兼容性,则必须在设置数据URL 之前设置onload属性.src
不幸的是,由于可能存在或可能不存在错误,将数据网址图像绘制到画布会导致原始清理标记设置为false,这意味着您将无法toDataURL()在画布上调用并获取PNG背部.所以...
我想根据客户端修改的SVG-> Canvas-> PNG-on-server的特定需求,您需要使用上面的第一步来序列化svg_xml然后将该原始源传递给canvg.
或者,您可以考虑按照上述顺序对SVG进行序列化,并将其直接提交给您的服务器并进行服务器端SVG到PNG的转换.