如何将SVG的背景颜色正确转换为Canvas

时间:2016-04-09 21:29:20

标签: javascript canvas d3.js svg

我将使用canvg库的d3 svg对象转换为画布并将其显示为图像(png)。

生成的图像具有透明背景,这不是我想要的。我需要白色背景。

所以我试着设置svg元素的背景颜色。查看svg元素时它很好,但转换后的图像仍然是透明的。 我也试过,改变画布对象的背景,但这也行不通。

第一种方法(svg):

var svg = d3.select(".chart").append("svg").attr("style","background: white;")...

第二个方法(画布):

canvg(document.getElementById('canvas'), $("#chart").html());

var canvas = document.getElementById('canvas');
canvas.style.background = 'white';
var img = canvas.toDataURL('image/png');
document.write('<img src="' + img + '"/>');  

有谁知道,我必须在哪个对象上设置背景颜色,以便在png图像中正确转换?

编辑:根据ThisOneGuys答案中提到的信息,我找到了这个解决方案。

var svg = d3.select(".chart").append("svg") ...

svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "white"); 

使用附加的rect,我得到了我需要的东西:)

3 个答案:

答案 0 :(得分:3)

要附加<rect>是一种解决方案,另一种解决方案是在调用`canvg'方法后渲染背景颜色。

您可以从画布API调用每个绘图操作来绘制光栅化版本,这样就可以使用ctx.fillRect填充背景。要使新图纸显示在后台,您只需将globalCompositeOperation属性设置为destination-over

var $container = $('#svg-container'),
      content = $container.html().trim(),
      canvas = document.getElementById('svg-canvas');

     // Since we will edit the canvas afterward, we need to remove that #!~$^ default mouseEvent listener
    canvg(canvas, content, {ignoreMouse: true});
     // now you've rendered your svg, you can draw the background on the canvas
    var ctx = canvas.getContext('2d');

     // all drawings will be made behind the already painted pixels
    ctx.globalCompositeOperation = 'destination-over'
      // set the color
    ctx.fillStyle = $container.find('svg').css('background-color');
     // draw the background
    ctx.fillRect(0, 0, canvas.width, canvas.height);


    var theImage = canvas.toDataURL('image/png');
    $('#svg-img').attr('src', theImage);
svg {
  background-color: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<section>
  <header>
    <h1>SVG:</h1>
  </header>
  <div id='svg-container'>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
      <circle cx="60" cy="70" r=50 style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" />
    </svg>
  </div>
</section>
<section>
  <header>
    <h1>Canvas:</h1>
  </header>
  <canvas id="svg-canvas"></canvas>
</section>
<section>
  <header>
    <h1>PNG:</h1>
  </header>
  <img id="svg-img" />
</section>

答案 1 :(得分:1)

之前我曾经遇到过这个问题。如你所知,CSS没有通过get放入DOM中,因此转换不会读取它。所以你必须改为内联样式。但你目前的做法是不正确的。

所以不要使用:

drawRect:

您必须设置如下样式:

.attr("style","background: white;").

应该可以正常工作:)

答案 2 :(得分:1)

我使用rect

“绘制”svg中的背景

<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <script data-require="jquery@2.2.0" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
  <script src="https://rawgit.com/gabelerner/canvg/master/canvg.js"></script>
</head>

<body>
  <div class="chart" id="chart" style="width: 50%; margin: 0 auto;"></div>
  <!-- d3 code -->
  <script type="text/javascript">
    var svg = d3.select(".chart").append("svg")
    .attr("id", "mysvg")
    .attr("width", 500)
    .attr("height", 500);
    
    svg.append('rect')
      .attr('width', 500)
      .attr('height', 500)
      .style("fill", "red");
    
    svg.selectAll('.bar')
      .data([1,2,3,4])
      .enter()
      .append('rect')
      .attr('y', function(d,i){
        return d * 50;
      })
      .attr('height', function(d,i){
        return 500 - (d * 50);
      })
      .attr('width', 50)
      .attr('x', function(d,i){
        return i * 100;
      })
      .style('fill', 'steelblue');
    
  </script>
  <canvas id="canvas" width="200" height="200"></canvas>
  <script type="text/javascript">    
    var canvas = document.getElementById('canvas');
    canvg(document.getElementById('canvas'), $('#chart').html());
    var img = canvas.toDataURL('image/png');
    document.write('<img src="' + img + '"/>');
  </script>
</body>

</html>