【问题标题】:svg export to png only exports small part/fraction of rendered svg in JavaScript using Angularsvg 导出到 png 仅使用 Angular 导出 JavaScript 中渲染的 svg 的一小部分/一小部分
【发布时间】:2017-06-28 09:50:23
【问题描述】:

我需要一些关于将渲染的 svg 词云导出为 png 的建议。

我的设置可以正常工作,但它只导出渲染词云的一小部分。

我认为这可能与我需要设置的尺寸有关。我不知道。

这是我的 Angular/JavaScript 导出函数:

scope.exportToPNG2 = function () {

  var svg = document.querySelector('#wordCloudSVG');

  var canvas = document.getElementById('WordCloudCanvas');

  var ctx = canvas.getContext('2d');
  var data = (new XMLSerializer()).serializeToString(svg);
  var DOMURL = window.URL || window.webkitURL || window;

  var img = new Image();
  var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });
  var url = DOMURL.createObjectURL(svgBlob);

  img.onload = function () {
      ctx.drawImage(img, 0, 0);
      DOMURL.revokeObjectURL(url);

      var imgURI = canvas
          .toDataURL('image/png')
          .replace('image/png', 'image/octet-stream');

      triggerDownload(imgURI);
  };

  img.src = url;
}


function triggerDownload(imgURI) {
  var evt = new MouseEvent('click', {
      view: window,
      bubbles: false,
      cancelable: true
  });

  var a = document.createElement('a');
  a.setAttribute('download', 'MY_COOL_IMAGE.png');
  a.setAttribute('href', imgURI);
  a.setAttribute('target', '_blank');

  a.dispatchEvent(evt);
}

这是我的词云渲染到的模板:

<div id="wordCloud">
    <button class="basicButton" ng-click="exportToPNG2()">Export to .PNG</button>
    <div id="wordCloudVisualisation"></div>
    <canvas id="WordCloudCanvas"></canvas>
</div>

这张图片显示了我的&lt;div&gt; 我的词云被渲染到的地方。黄色突出显示的块是词云中被重新绘制为 png 并导出的部分:

var svg = document.querySelector('#wordCloudSVG'); 中的元素 id 我在我的 Chrome 开发工具中得到了这个:

我必须改变什么来导出整个词云?

【问题讨论】:

    标签: javascript angularjs svg


    【解决方案1】:

    感谢这篇文章,我对导出功能做了一些小改动:https://gist.github.com/gustavohenke/9073132

    我正在根据svg.getBoundingClientRect() 设置画布大小

    这是我的工作解决方案(参见代码中的 cmets):

    scope.exportToPNG2 = function () {
    
      var svg = document.querySelector('#wordCloudSVG');
    
      //create a canvas
      var canvas = document.createElement("canvas");
    
      //set size for the canvas
      var svgSize = svg.getBoundingClientRect();
      canvas.width = svgSize.width;
      canvas.height = svgSize.height;
    
      var ctx = canvas.getContext('2d');
    
      var data = new XMLSerializer().serializeToString(svg);
    
      var DOMURL = window.URL || window.webkitURL || window;
    
      var img = new Image();
      var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });
      var url = DOMURL.createObjectURL(svgBlob);
    
      img.onload = function () {
          ctx.drawImage(img, 0, 0);
          DOMURL.revokeObjectURL(url);
    
          var imgURI = canvas
              .toDataURL('image/png')
              .replace('image/png', 'image/octet-stream');
    
          triggerDownload(imgURI);
      };
    
      img.src = url;
    }
    

    【讨论】:

      【解决方案2】:

      您需要将您的画布widthheight 属性设置为您的svg 图像的natural..

      img.onload = function () {
          canvas.width = this.naturalWidth;
          canvas.heigh = this.naturalHeight;
          ctx.drawImage(this, 0,0);
          ...
      

      但是请注意,当 img 指向 svg 文档时,IE 不会设置它们的宽度/高度,因此您必须从文档的元素中解析它。由于在这里您将 svg 的 widthheight 属性设置为默认像素,因此您可以轻松获得它。
      (但请注意,无论如何使用这种方法你会遇到更多的 IE 问题......)

      【讨论】:

      • 感谢您的回复!我能够修复它,根据我的 svg 的大小设置画布的宽度和高度。
      • @onmyway ,是的,我看到了。很高兴你自己解决了。但请注意,您所做的并不完全相同,因为您可以在 svg 元素上有一些 CSS 规则,这会使 getBoundingClientRect 返回其他值(基本上您将使用您的方法获得显示的大小)。由于我们谈论的是矢量图形,两者都是可以接受的,但你必须知道区别才能知道你想要哪一个。
      • 谢谢你的解释:)。注意。
      猜你喜欢
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 2015-06-29
      • 2020-03-17
      • 2015-02-26
      • 2013-07-01
      • 2017-06-27
      • 1970-01-01
      相关资源
      最近更新 更多