2017-01-10 6 views
2

я создал простой SVG elment, которые получают dowbloaded в формате PNG при нажатии на кнопку, мое решение похож на hereКак включить стиль CSS при преобразовании SVG в PNG


Основная идея:
1.svg на холст
2.canvas в dataUrl
3.trigger скачать с dataUrl

проблема заключается в том, что при загрузке файла PNG он не включает стиль CSS применяется на SVG my solution result

ВНИМАНИЕ - Я знаю, что есть workingaround решение, перемещая стили «инлайн» на элементах как here или рекурсивного решения, выкопав дерево DOM и используя getComputedStyle (элемент, нуль);

Вопросы:
1.what реальная причина и решение этой проблемы.
(ускорение GPU связаны так или иначе?)
2.how я до сих пор преодолеть эту проблему при использовании пользовательских шрифтов с Fontface

<button id="btn">svg to png</button> 

    <svg id="svg" width="200" height="200"> 
    <circle cx="50" cy="50" r="30" /> 
    <text class="svgTxt" x="0" y="100">Hen's SVG Image</text> 
    </svg> 
    <canvas id="canvas" width="200" height="200"></canvas> 

мой 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; 
    }); 

ответ

3

Вопрос 1 (f рвая половина):что реальная причина (ускорение GPU, связанное в любом случае)

Нет, ускорение GPU не имеет ничего общего с ним.
Самая широкая причина: конфиденциальность.

Чтобы нарисовать ваш svg с помощью drawImage, вам необходимо загрузить свой svg в качестве внешнего документа внутри тега <img>. SVG может быть довольно сложным форматом изображений для загрузки ресурсов (он может буквально потребовать любой вид ресурса, который может потребоваться в любом документе HTML). Таким образом, это было указано в спецификации, что такой же безопасности, как и для элементов или <object> или аналогичных должны применяться к <img> содержанию и еще строже:

<img> содержание не может требовать каких-либо внешних ресурсов, ни доступа к основным документ.

Вопрос 1 (вторая половина): и решение этой проблемы

Вы указали на некоторые SO вопросы уже ответить на него, вы также можете просто включить все таблицы стилей из основного документа внутри <style> тег внутри вашего проанализированного узла svg, прежде чем вы создадите Blob из него. dumb implementation here

Вопрос 2:«как я до сих пор решить эту проблему при использовании пользовательских шрифтов с Fontface»

Для внешних ресурсов, вы должны кодировать его, как dataURI и включить его в SVG узле прежде чем вы создадите Blob. Для шрифта, в частности, вы должны установить свойство font-face в элементе <style>.

Таким образом, в конце концов, ваш будет иметь SVG-то вроде

<defs> 
    <style> 
    /* all your parsed styles in here */ 
    @font-face { 
    font-family: foo; 
    src: url('data:application/font-woff;charset=utf-8;base64,...') 
    } 
    </style> 
</defs> 

в себе, прежде чем вы извлечь его разметку.

Смежные вопросы