Paankey56
Paankey56

Reputation: 125

How to Download and SVG element as an SVG file

Over the past few months, I have been working on this code that deals with ellipsoidal earth and just recently I have finished it. My professor now wants me to send him pictures of the diagrams I made as an SVG file. I know in Python you can put a few lines of code into your project to have it download the image, but I am unsure how it works in JavaScript. How can I do this in JavaScript, or is there another easier way?

Upvotes: 5

Views: 6519

Answers (1)

Alex L
Alex L

Reputation: 4241

Check out this demo: https://codepen.io/Alexander9111/pen/VwLaaPe?editors=1010

Code (modified from https://stackoverflow.com/a/19885344/9792594):

function downloadSVGasTextFile() {
  const base64doc = btoa(unescape(encodeURIComponent(document.querySelector('svg').outerHTML)));
  const a = document.createElement('a');
  const e = new MouseEvent('click');

  a.download = 'download.svg';
  a.href = 'data:text/html;base64,' + base64doc;
  a.dispatchEvent(e);
}

downloadSVGasTextFile();

You encode your svg as a 64bit string and then use that as the href of an anchor tag and then dispatch a click event to download the svg text file as download.svg

If you want to save an image, such as .png then you can first draw svg image into a cnavas then download that as .png,

UPDATE

I modified the answer and the demo to now include both download as text file .svg or download as image file .png https://codepen.io/Alexander9111/pen/VwLaaPe:

HTML:

<svg>
 ...
</svg>
<br/>
<button id="downloadPNG">Download .png</button>
<button id="downloadSVG">Download .svg</button>

JS:

function downloadSVGAsText() {
  const svg = document.querySelector('svg');
  const base64doc = btoa(unescape(encodeURIComponent(svg.outerHTML)));
  const a = document.createElement('a');
  const e = new MouseEvent('click');
  a.download = 'download.svg';
  a.href = 'data:image/svg+xml;base64,' + base64doc;
  a.dispatchEvent(e);
}

function downloadSVGAsPNG(e){
  const canvas = document.createElement("canvas");
  const svg = document.querySelector('svg');
  const base64doc = btoa(unescape(encodeURIComponent(svg.outerHTML)));
  const w = parseInt(svg.getAttribute('width'));
  const h = parseInt(svg.getAttribute('height'));
  const img_to_download = document.createElement('img');
  img_to_download.src = 'data:image/svg+xml;base64,' + base64doc;
  console.log(w, h);
  img_to_download.onload = function () {    
    canvas.setAttribute('width', w);
    canvas.setAttribute('height', h);
    const context = canvas.getContext("2d");
    //context.clearRect(0, 0, w, h);
    context.drawImage(img_to_download,0,0,w,h);
    const dataURL = canvas.toDataURL('image/png');
    if (window.navigator.msSaveBlob) {
      window.navigator.msSaveBlob(canvas.msToBlob(), "download.png");
      e.preventDefault();
    } else {
      const a = document.createElement('a');
      const my_evt = new MouseEvent('click');
      a.download = 'download.png';
      a.href = dataURL;
      a.dispatchEvent(my_evt);
    }
    //canvas.parentNode.removeChild(canvas);
  }  
}

const downloadSVG = document.querySelector('#downloadSVG');
downloadSVG.addEventListener('click', downloadSVGAsText);
const downloadPNG = document.querySelector('#downloadPNG');
downloadPNG.addEventListener('click', downloadSVGAsPNG);

Upvotes: 6

Related Questions