我已经创建了一个简单的SVG元素,当点击一个按钮时可以下载到png,我的解决方案类似于此处
基本思想是:
1.svg to canvas
2.canvas to dataUrl
3.trigger从dataUrl下载
问题是,当下载png文件时,它不包括应用于svg my solution结果的css样式
注意-我知道有一个workingaround解决方案通过在移动元素的样式"内联"像这里或通过下挖DOM树,并使用递归解决方案的getComputedStyle(元素,NULL);
问题:
1.这个问题的真正原因和解决方案是什么.
(无论如何,GPU加速度是相关的吗?)
2.在使用Fontface的自定义字体时,我仍然可以解决这个问题
我的CSS:
/*adding exo2 font*/ @font-face { font-family: 'exo_2black'; src: url('./exo2font/Exo2-Black-webfont.eot'); src: url('./exo2font/Exo2-Black-webfont.eot?#iefix') format('embedded-opentype'), url('./exo2font/Exo2-Black-webfont.woff') format('woff'), url('./exo2font/Exo2-Black-webfont.ttf') format('truetype'), url('./exo2font/Exo2-Black-webfont.svg#exo_2black') format('svg'); font-weight: normal; font-style: normal; } /*change circle color depends on window size*/ @media screen and (min-width: 480px) { svg circle { fill: lightgreen; } } /*style on the svg text*/ .svgTxt{ font-family: 'exo_2black'; font-size: 30px; fill: red; }
我的代码:
//reference to elements var btn = document.querySelector('#btn'); var svg = document.getElementById('svg'); var svgTexts = svg.getElementsByTagName('text'); var canvas = document.getElementById('canvas'); //Style definitions for svg elements defined in stylesheets are not applied to the generated canvas. This can be patched by adding style definitions to the svg elements before calling canvg. //3.trigger download from dataUrl function triggerDownload(imgURI) { var evt = new MouseEvent('click', { view: window, bubbles: false, cancelable: true }); var a = document.createElement('a'); a.setAttribute('download', 'hen_saved_image.png'); a.setAttribute('href', imgURI); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); } //btn click event btn.addEventListener('click', function () { // 1.svg to canvas var ctx = canvas.getContext('2d'); var data = (new XMLSerializer()).serializeToString(svg);//serialize the svg element to string var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });//A blob object represents a chuck of bytes that holds data of a file. var url = DOMURL.createObjectURL(svgBlob);//creates a DOMString containing an URL representing the object given in paramete $('svg').append(deletedSVGText); img.onload = function () { ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); // 2.canvas to dataUrl var imgURI = canvas .toDataURL('image/png') .replace('image/png', 'image/octet-stream');// returns a data URI containing a representation of the image in the format specified by the type parameter triggerDownload(imgURI); }; img.src = url; });
Kaiido.. 5
问题1(上半部分): 真正的原因是什么(无论如何GPU加速相关?)
不,GPU加速与它无关.
最广泛的原因是隐私.
要绘制svg,drawImage
必须将svg作为外部文档加载到标记内.SVG对于资源加载来说可能是一种非常复杂的图像格式(它实际上可能需要任何HTML文档都需要的任何资源).因此,规范中已经指出,与
元素
或类似元素相同的安全性应该适用于
内容甚至更严格:
内容不能要求任何外部资源,也不能访问主文档.
问题1(下半部分):以及此问题的解决方案
您已经指出了一些已经回答它的SO问题,您还可以在解析的svg节点内的标记内包含主文档中的所有样式表,然后再从中创建Blob.这里愚蠢的实施
问题2: "在使用Fontface的自定义字体时,我仍然如何解决这个问题"
对于外部资源,您必须将其编码为dataURI,并在创建Blob之前将其包含在svg节点中.特别是对于字体,您需要font-face
在元素中设置属性.
所以最后,你的svg会有类似的东西
在你提取其标记之前本身.
问题1(上半部分): 真正的原因是什么(无论如何GPU加速相关?)
不,GPU加速与它无关.
最广泛的原因是隐私.
要绘制svg,drawImage
必须将svg作为外部文档加载到标记内.SVG对于资源加载来说可能是一种非常复杂的图像格式(它实际上可能需要任何HTML文档都需要的任何资源).因此,规范中已经指出,与
元素
或类似元素相同的安全性应该适用于
内容甚至更严格:
内容不能要求任何外部资源,也不能访问主文档.
问题1(下半部分):以及此问题的解决方案
您已经指出了一些已经回答它的SO问题,您还可以在解析的svg节点内的标记内包含主文档中的所有样式表,然后再从中创建Blob.这里愚蠢的实施
问题2: "在使用Fontface的自定义字体时,我仍然如何解决这个问题"
对于外部资源,您必须将其编码为dataURI,并在创建Blob之前将其包含在svg节点中.特别是对于字体,您需要font-face
在元素中设置属性.
所以最后,你的svg会有类似的东西
在你提取其标记之前本身.