2017-07-07 1 views
5

Ich versuche, eine Svg in ein Bildformat zu konvertieren. Eigentlich funktioniert viel sehr gut und ich weiß, wie man von SVG zu Leinwand und von Leinwand zu img konvertiert. Mein Problem ist, dass die Svg CSS verwendet, die als CSS-Datei enthalten ist und durch Konvertierung in Canvas die Stile verloren gehen.Mit CSS in konvertierten SVG zu img

Hat jemand eine Idee, wie man die Stile in meine Svg oder Leinwand kopieren?

Hier ist mein Code: https://jsfiddle.net/DaWa/70w9db1d/

<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
    <title>SVG2IMG</title> 
    <link rel="stylesheet" href="./circle.css"> 
</head> 
<body> 
<svg width="100" height="100"> 
    <circle cx="50" cy="50" r="40"/> 
</svg> 

<script> 
    var svg = document.querySelector('svg'); 

    let xml = new XMLSerializer().serializeToString(svg); 
    let data = "data:image/svg+xml;base64," + btoa(xml); 
    let img = new Image(); 
    img.src = data; 
    document.body.appendChild(img) 

</script> 

</body> 
</html> 

Und mein css:

circle { 
    fill:red 
} 
+0

@JGFMK die Seite nicht die mit der OP Frage verknüpft hilft. –

Antwort

3

ich diesen Trick verwendet berechneten Stil jedes Knotens zu seinem Stil Attribut hinzufügen, und es funktioniert. vielleicht kann es dir helfen.

Update 1: einige Browser unterstützen nicht die cssText-Eigenschaft, so dass Sie den Code verwenden können, der ein bisschen mehr Cross-Browser ist.

Update 2: Firefox berechnet css zitiert Eigenschaft, die einige ungültige Zeichenfolge Zeichen enthalten, die Btoa nicht ordnungsgemäß codieren kann.

let addStyle = function(children) { 
 
    for (let i = 0; i < children.length; i++) { 
 
    let child = children[i]; 
 
    if (child instanceof Element) { 
 
     let cssText = ''; 
 
     let computedStyle = window.getComputedStyle(child, null); 
 
     for (let i = 0; i < computedStyle.length; i++) { 
 
     let prop = computedStyle[i]; 
 
     cssText += prop + ':' + computedStyle.getPropertyValue(prop) + ';'; 
 
     } 
 
     child.setAttribute('style', cssText); 
 
     addStyle(child.childNodes); 
 
    } 
 
    } 
 
} 
 

 
let svg = document.querySelector('svg'); 
 
addStyle(svg.childNodes); 
 
let xml = new XMLSerializer().serializeToString(svg); 
 
let data = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(xml))); 
 
let img = new Image(); 
 
img.src = data; 
 
document.body.appendChild(img);
circle { 
 
    fill: red 
 
}
<svg width="100" height="100"> 
 
    <circle cx="50" cy="50" r="40" /> 
 
</svg>

+2

Es gibt einige Cross-Browser-Probleme hier. Das Bild ist schwarz in meinem Hauptbrowser (Firefox/54.0.1 auf Win64) und rot in Chrome. (Edge stürzt bei "Object unterstützt keine Eigenschaft oder Methode für" ", aber ich denke, das ist ein ganz anderes Problem.) Netter Ansatz jedenfalls. –

+0

@ ÁlvaroGonzález ja computedStyle funktioniert nur auf Web-Kit, denke ich. Ich füge das zur Antwort hinzu. Danke für das Erinnern. –

+0

Noch [Caniuse] (http://caniuse.com/#search=getComputedStyle) zeigt eine recht breite Unterstützung. Vielleicht funktioniert es einfach nicht auf SVG. –