2017-01-10 2 views
2

Umwandlung Ich habe ein einfaches SVG elment erstellt, den png dowbloaded werden, wenn auf einer Schaltfläche klicken, meine Lösung ist ähnlich zu hereWie CSS-Stil einschließen, wenn SVG png


Die Grundidee ist:
1.svg auf die Leinwand
2.canvas zu DataURL
3.trigger herunterladen von DataURL

das Problem ist, dass, wenn die pNG-Datei herunterzuladen es muß nicht die CSS-Stil auf dem sVG-Anwendung umfassen my solution result

HINWEIS - ich weiß, dass es eine workingaround Lösung ist durch die Stile „inline“ auf den Elementen wie here oder die rekursive Lösung zu bewegen, indem Sie den DOM-Baum zu graben und mit getComputedStyle (Elemente, null);

Fragen:
1.what der wahre Grund ist, und die Lösung für dieses Problem.
(ist die GPU-Beschleunigung in irgendeiner Weise im Zusammenhang?)
2.how ich immer noch dieses Problem überwinden, wenn eine benutzerdefinierte Schriftart mit Fontface mit

<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> 

mein CSS: mein Code

/*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; 
    }); 

Antwort

3

Frage 1 (f rste Hälfte):was der wahre Grund ist (die Beschleunigung GPU in ohnehin bezogen)

Nein, hat die GPU-Beschleunigung nichts damit zu tun.
Der breiteste Grund ist Privatsphäre.

Um Ihre Svg mit drawImage zu zeichnen, müssen Sie Ihre Svg als externes Dokument in einem <img> Tag laden. SVG kann ein recht komplexes Bildformat zum Laden von Ressourcen sein (es kann buchstäblich jede Art von Ressource erfordern, die von jedem HTML-Dokument benötigt wird). So hat sich in der Spezifikationen angegeben, dass die gleiche Sicherheit wie die für Elemente oder <object> oder ähnliche zu <img> Inhalt gelten sollte und noch strenger:

<img> Inhalte keine externen Ressourcen erfordern kann, noch Zugang zu den wichtigsten Dokument.

Frage 1 (zweite Hälfte): und die Lösung für dieses Problem

Sie bereits einige SO Fragen darauf beantworten es, könnten Sie auch alle nur sind die Stylesheets aus dem Hauptdokument innerhalb eines <style> Markieren Sie das Tag in Ihrem analysierten Svg-Knoten, bevor Sie das Blob daraus erstellen. dumb implementation here

Frage 2:„wie ich dieses Problem weiterhin überwinden, wenn eine benutzerdefinierte Schriftart mit Fontface mit“

Für externe Ressourcen, müssen Sie es als dataURI kodieren, und schließen Sie es in Ihrem svg Knoten bevor Sie den Blob erstellen. Speziell für die Schriftart würden Sie eine font-face-Eigenschaft in einem <style>-Element festlegen.

So am Ende, würde Ihr svg etwas wie

<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> 

in sich haben, bevor Sie seine Markup extrahieren kann.