SVG到PNG,没有宽度属性

时间:2019-06-13 09:59:50

标签: javascript svg png

哦,嗨。我有一个SVG,我正在将其转换为png并上传到服务器。只要我在SVG标签中明确给出宽度和高度值,一切就可以正常工作。我正在使用viewBox =“”为SVG提供宽高比,而没有width和height属性,则svg可以很好地缩放到浏览器窗口中。因此,我不想在标签中包含宽度和高度。

这是代码的相关部分:

var svg = document.querySelector( "svg" );
var svgData = new XMLSerializer().serializeToString( svg );
var nzs ="";
var canvas = document.createElement( "canvas" );
canvas.width = $('#mainSVG').width();// I tried giving the canvas a size, but it doesn't help 
canvas.height = $('#mainSVG').height();
console.log(canvas.width +" " + canvas.height);
var ctx = canvas.getContext( "2d" );
var img = document.createElement( "img" );
img.setAttribute( "src", "data:image/svg+xml;base64," + btoa( svgData ) );
img.onload = function() {
	ctx.drawImage( img, 0, 0);
//	ctx.drawImage( img, 0, 0, $('#mainSVG').width(), $('#mainSVG').height() ); // I tried setting the image size in this line but it didn't work either.
	nzs= canvas.toDataURL( "image/png" ); 
	$.ajax({
	  url:"hidden.php",
	  data:{base64: nzs},
	  type:"post",
	  complete:function(){
		console.log("Ready");
	  }
	});
	};
<svg id="mainSVG" clasxmlns="http://www.w3.org/2000/svg" viewBox="0 0 2800 1600">
<!-- <svg id="mainSVG" clasxmlns="http://www.w3.org/2000/svg" viewBox="0 0 2800 1600" width="800" height="1000"> If i use this tag everything works --!>

如何将动态创建的宽度和高度插入SVG标签?我曾想过要处理svgData字符串以包括width和height属性,但这并不是最简单的方法。预先谢谢你。

2 个答案:

答案 0 :(得分:1)

这可以做到,但是很麻烦。

首先,您必须获取svg元素的externalHTML

var mySvg = document.getElementById("mySvg").outerHTML;

这将返回类似的内容

<svg id="mySvg" viewBox="0 0 2800 1600"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"></circle> </svg>

现在,我们需要“注入”宽度和高度属性。不幸的是,Javascript的String对象没有提供在特定位置插入文本的内置方法-因此,我们需要使用自己的函数来做到这一点。

String.prototype.splice = function(index, charsToRemove, str) {
  return this.slice(0, index) + str + this.slice(index + Math.abs(charsToRemove));
};

var width = 200;
var height = 300;

mySvg = mySvg.splice(mySvg.indexOf("svg") + 3, 0, ' width="' + width + '" height="' + height + '"');

这就是之后的样子

<svg width="200" height="300" id="mySvg" viewBox="0 0 2800 1600">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"></circle>
</svg>

最后,让我们摆脱 viewBox 属性。为此,我们需要在mySvg中获取它的起始索引,然后从中获取第一个和最后一个的索引。通过start-和endindex,我们可以再次使用splice()方法。

var startIndex = mySvg.indexOf("viewBox");
var endIndex = startIndex;
var occurences = 0;
do {
  if (mySvg.charAt(endIndex) == '"') {
    occurences++;
  }
  endIndex++;
}
while (occurences < 2);

mySvg = mySvg.splice(startIndex,endIndex-startIndex,'');

并更改svg元素的externalHTML

document.getElementById("mySvg").outerHTML = mySvg;

这是完整的示例:

String.prototype.splice = function(index, charsToRemove, str) {
  return this.slice(0, index) + str + this.slice(index + Math.abs(charsToRemove));
};

function modify(width, height) {
  var mySvg = document.getElementById("mySvg").outerHTML;

  mySvg = mySvg.splice(mySvg.indexOf("svg") + 3, 0, ' width="' + width + '" height="' + height + '"');

  var startIndex = mySvg.indexOf("viewBox");
  var endIndex = startIndex;
  var occurences = 0;
  do {
    if (mySvg.charAt(endIndex) == '"') {
      occurences++;
    }
    endIndex++;
  }
  while (occurences < 2);

  mySvg = mySvg.splice(startIndex, endIndex - startIndex, '');
  document.getElementById("mySvg").outerHTML = mySvg;
}
<button onclick="modify(400,300)">modify</button>
<svg id="mySvg" viewBox="0 0 2800 1600">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>

答案 1 :(得分:1)

var svg = document.querySelector( "svg" ).cloneNode(true); 
svg.setAttribute("width", "whatever");
svg.setAttribute("height", "something else");

然后照原样继续。 cloneNode creates a deep copy,然后您就可以根据需要在副本中设置属性。