繁体   English   中英

CANVG不支持CSS

[英]Canvg not supporting css

我有内联svg,是从服务器动态加载的。 我希望使用内嵌CSS处理或修改该svg。 我搜索了将修改后的svg转换为png或base64图像。 经过长时间的搜索,我决定坚持使用Canvg。

现在的问题是,它渲染了内联样式属性,例如背景和边框半径。

这是我的SVG。

<svg height="550" width="550" viewBox="0 0 512 512" id="svg">
<path d="m309 139c0-111-32-139-53-139-21 0-53 28-53 139l-173 122c-2 1-4 4-4 7l0 46c0 6 5 10 11 9l166-37c6 49 16 93 23 139l-63 49c-2 1-4 4-4 6l0 23c0 7 6 11 12 8l85-38 85 38c6 3 12-1 12-8l0-23c0-2-2-5-4-6l-63-49c7-46 17-90 23-139l166 37c6 1 11-3 11-9l0-46c0-3-2-6-4-7z m-53-88c-11 0-21 3-30 7 3-13 15-22 30-22 15 0 27 9 30 22-9-4-19-7-30-7z"></path>
</svg>

看起来像这样:

Raw Svg Preivew

请记住,路径是从服务器动态加载的。 因此无法修改它。

现在,我想操纵像这样的东西。

<svg style="background: grey none repeat scroll 0% 0%; fill: white; padding: 70px; border-radius: 98px;" height="550" width="550" viewBox="0 0 512 512" id="svg">
      <path d="m309 139c0-111-32-139-53-139-21 0-53 28-53 139l-173 122c-2 1-4 4-4 7l0 46c0 6 5 10 11 9l166-37c6 49 16 93 23 139l-63 49c-2 1-4 4-4 6l0 23c0 7 6 11 12 8l85-38 85 38c6 3 12-1 12-8l0-23c0-2-2-5-4-6l-63-49c7-46 17-90 23-139l166 37c6 1 11-3 11-9l0-46c0-3-2-6-4-7z m-53-88c-11 0-21 3-30 7 3-13 15-22 30-22 15 0 27 9 30 22-9-4-19-7-30-7z"></path>      </svg>

看起来像这样:

操纵图像

但是使用canvg脚本渲染之后。 它呈现为原始文件。 它仅包括填充颜色。 没有其他的。

还有其他方法可以做到这一点。 使用canvas或svg元素。

请帮忙!!! 提前致谢

大多数svg到canvas的库不支持外部资源(xlink属性,图像和CSS)。

我发现这样做的唯一方法是将这些外部资源附加到svg节点中,然后使用canvas.toDataURL()方法将svg绘制到画布上。

我正在编写一个处理此问题的小脚本 ,这是我制作的CSS解析器的转储,它将循环遍历所有文档的样式表,并仅附加对内部元素有影响的样式表。

var parseStyles = function() {
    var styleSheets = [],
        i;
    // get the stylesheets of the document (ownerDocument in case svg is in <iframe> or <object>)
    var docStyles = svg.ownerDocument.styleSheets;
    // transform the live StyleSheetList to an array to avoid endless loop
    for (i = 0; i < docStyles.length; i++) {
        styleSheets.push(docStyles[i]);
    }
    if (styleSheets.length) {
        // getDef() will return an svg <defs> element if already into the node, or will create it otherwise
        getDef();
        svg.matches = svg.matches || svg.webkitMatchesSelector || svg.mozMatchesSelector || svg.msMatchesSelector || svg.oMatchesSelector;
    }

    // iterate through all document's stylesheets
    for (i = 0; i < styleSheets.length; i++) {
        // create a new style element
        var style = document.createElement('style');
        // some stylesheets can't be accessed and will throw a security error
        try {
            var rules = styleSheets[i].cssRules,
                l = rules.length;
            // iterate through each cssRules of this stylesheet
            for (var j = 0; j < l; j++) {
                // get the selector of this cssRules
                var selector = rules[j].selectorText;
                // is it our svg node or one of its children ?
                if ((svg.matches && svg.matches(selector)) || svg.querySelector(selector)) {
                    // append it to our <style> node
                    style.innerHTML += rules[j].cssText + '\n';
                }
            }
            // if we got some rules
            if (style.innerHTML) {
                // append the style node to the clone's defs
                defs.appendChild(style);
            }
        } catch (e) {
            console.warn('unable to get some cssRules : ', e);
        }
    }
    // small hack to avoid border and margins being applied inside the <img>
    var s = clone.style;
    s.border = s.padding = s.margin = 0;
    s.transform = 'initial';
};

 var svg = document.querySelector('svg'); var doSomethingWith = function(canvas) { document.body.appendChild(canvas) }; var parseStyles = function() { var styleSheets = [], i; // get the stylesheets of the document (ownerDocument in case svg is in <iframe> or <object>) var docStyles = svg.ownerDocument.styleSheets; // transform the live StyleSheetList to an array to avoid endless loop for (i = 0; i < docStyles.length; i++) { styleSheets.push(docStyles[i]); } if (styleSheets.length) { // getDef() will return an svg <defs> element if already into the node, or will create it otherwise getDef(); svg.matches = svg.matches || svg.webkitMatchesSelector || svg.mozMatchesSelector || svg.msMatchesSelector || svg.oMatchesSelector; } // iterate through all document's stylesheets for (i = 0; i < styleSheets.length; i++) { // create a new style element var style = document.createElement('style'); // some stylesheets can't be accessed and will throw a security error try { var rules = styleSheets[i].cssRules, l = rules.length; // iterate through each cssRules of this stylesheet for (var j = 0; j < l; j++) { // get the selector of this cssRules var selector = rules[j].selectorText; // is it our svg node or one of its children ? if ((svg.matches && svg.matches(selector)) || svg.querySelector(selector)) { // append it to our <style> node style.innerHTML += rules[j].cssText + '\\n'; } } // if we got some rules if (style.innerHTML) { // append the style node to the clone's defs defs.appendChild(style); } } catch (e) { console.warn('unable to get some cssRules : ', e); } } // small hack to avoid border and margins being applied inside the <img> var s = svg.style; s.border = s.padding = s.margin = 0; s.transform = 'initial'; exportDoc(); }; var defs; var getDef = function() { // Do we have a `<defs>` element already ? defs = svg.querySelector('defs') || document.createElementNS('http://www.w3.org/2000/svg', 'defs'); if (!defs.parentNode) { svg.insertBefore(defs, svg.firstElementChild); } }; var exportDoc = function() { // check if our svgNode has width and height properties set to absolute values // otherwise, canvas won't be able to draw it var bbox = svg.getBoundingClientRect(); if (svg.width.baseVal.unitType !== 1) svg.setAttribute('width', bbox.width); if (svg.height.baseVal.unitType !== 1) svg.setAttribute('height', bbox.height); // serialize our node var svgData = (new XMLSerializer()).serializeToString(svg); // remember to encode special chars var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData); var svgImg = new Image(); svgImg.onload = function() { var canvas = document.createElement('canvas'); // IE11 doesn't set a width on svg images... canvas.width = this.width || bbox.width; canvas.height = this.height || bbox.height; canvas.getContext('2d').drawImage(svgImg, 0, 0, canvas.width, canvas.height); doSomethingWith(canvas) }; svgImg.src = svgURL; }; parseStyles(); 
 rect { fill: red; padding: 25em; border: 25px solid yellow; } canvas { border: 1px solid green; } svg{ background-color: skyblue; } 
 <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"> <rect x="0" y="0" width="100" height="100" /> </svg> 

您可以使用Javascript和DOM修改当前页面中的任何元素。 无论服务器是生成文件还是其他文件。 http://www.i-programmer.info/programming/graphics-and-imaging/3254-svg-javascript-and-the-dom.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM