简体   繁体   English

SVG to Canvas with canvg不尊重css

[英]SVG to Canvas with canvg not respecting css

I'm attempting to convert my SVG to canvas to get a png. 我正在尝试将我的SVG转换为画布以获得png。 everything is working great except for the css positioning. 除了css定位,一切都很好。

please see this jsfiddle 请看这个jsfiddle

you can see the top section which is the SVG. 你可以看到顶部是SVG。

I am using canvg to render the svg on the canvas element. 我正在使用canvg在canvas元素上呈现svg。

the 2 svgs overlap each other, one is 100% size, the other 80%. 2个svgs相互重叠,一个是100%大小,另一个是80%。 I am rendering these with Raphael. 我和拉斐尔一起渲染这些。

I have tried to insert inline styles as suggested in various place like: 我试图在各种地方插入内联样式,如:

<style type='text/css'>![CDATA[svg{ margin: 0 auto; }]]></style>

however canvg only returns: 然而canvg只返回:

Cannot read property 'split' of undefined

I need the canvas to be identical to the SVG. 我需要画布与SVG相同。

*note changing both to 100% size and changin radius of circles is not an option, this is a very simplified version as illustration. *注意将两者都改为100%大小和圆的半径不是一个选项,这是一个非常简化的插图版本。

While it's less than ideal, one option is to inline all of the styles before you render. 虽然它不太理想,但一种选择是在渲染之前内联所有样式。 Here's what I used to deal with the same issue on this project : 以下是我在此项目中用于处理相同问题的内容:

function inlineAllStyles() {
    var svg_style, selector, cssText;

    for (var i = 0; i <= document.styleSheets.length - 1; i++) {
        //loop through your stylesheets
        if (document.styleSheets[i].href && document.styleSheets[i].href.indexOf('style.css') != -1) {
            //pull out the styles from the one you want to use
            if (document.styleSheets[i].rules != undefined) {
                svg_style = document.styleSheets[i].rules
            } else {
                svg_style = document.styleSheets[i].cssRules
            }
        }
    }

    if (svg_style != null && svg_style != undefined) {
        for (var i = 0; i < svg_style.length; i++) {
            if (svg_style[i].type == 1) {

                selector = svg_style[i].selectorText;

                styles = makeStyleObject(svg_style[i]);

                // Apply the style directly to the elements that match the selctor
                // (this requires to not have to deal with selector parsing)
                d3.selectAll(selector).style(styles)
            }
        };
    }
}

 function makeStyleObject(rule) {
    var styleDec = rule.style;
    var output = {};
    var s;

    for (s = 0; s < styleDec.length; s++) {
        output[styleDec[s]] = styleDec[styleDec[s]];
        if(styleDec[styleDec[s]] === undefined) {
            //firefox being firefoxy
            output[styleDec[s]] = styleDec.getPropertyValue(styleDec[s])
        }
    }

    return output;
}

inlineAllStyles()

If your css rules are not too much complicated, you can do the following steps: 如果您的css规则不是太复杂,您可以执行以下步骤:

  1. Read the .css file, which contains all the css rule. 阅读.css文件,其中包含所有css规则。 If required, you can use a different css file and put it on the server, which you can only use for this purpose. 如果需要,您可以使用不同的css文件并将其放在服务器上,您只能将其用于此目的。

     function readTextFile(file) { var rawFile = new XMLHttpRequest(); var allText = ''; rawFile.open("GET", file, false); rawFile.onreadystatechange = function () { if(rawFile.readyState === 4) { if(rawFile.status === 200 || rawFile.status == 0) { allText = rawFile.responseText; } } }; rawFile.send(null); return allText; } var svg_style = readTextFile(base_url + '/css/svg_sm_dashboard.css'); 
  2. Now apply the style on all the svg elements 现在在所有svg元素上应用样式

     var all_style = svg_style.replace(/\\r?\\n|\\r/g,'').split('}'); all_style.forEach(function(el) { if (el.trim() != '') { var full_rule_string = el.split('{'); var selector = full_rule_string[0].trim(); var all_rule = full_rule_string[1].split(';'); all_rule.forEach(function (elem) { if (elem.trim() != '') { var attr_value = elem.split(':'); d3.selectAll(selector).style(attr_value[0].trim() + '', attr_value[1].trim() + ''); } }); } }); 
  3. Now use canvg to convert it 现在使用canvg来转换它

     $('body').after('<canvas id="sm_canvas" style="display=none;"></canvas>'); var canvas = document.getElementById('sm_canvas'); canvg(canvas, $("<div>").append($('svg').clone()).html()); 

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

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