Skip to content

Instantly share code, notes, and snippets.

@remarkablemark
Last active Dec 31, 2020
Embed
What would you like to do?
<link rel="stylesheet" href="style.css">
<h1>SVG to Image</h1>
<!--
Load SVG.
-->
<form id="load-svg">
<p>
<textarea
placeholder="SVG markup..."
rows="5"
cols="50"
autofocus
required
></textarea>
</p>
<button type="submit">
Load SVG
</button>
</form>
<!--
SVG container.
-->
<p>
<div id="svg-container"></div>
</p>
<hr>
<!--
Save image.
-->
<form id="save-image">
<p>
<label>
Width:
<input
placeholder="Pixels..."
name="width"
type="number"
min="1"
max="999999"
required
>
</label>&nbsp;
<label>
Height:
<input
placeholder="Pixels..."
name="height"
type="number"
min="1"
max="999999"
required
>
</label>
</p>
<p>
<label>
Filename:
<input
placeholder="Name without extension..."
name="filename"
size="25"
required
>
</label>
</p>
<p>
Extension:
<label>
<input type="radio" name="extension" value="png" checked>PNG
</label>&nbsp;
<label>
<input type="radio" name="extension" value="jpeg">JPEG
</label>
</p>
<p>
<button type="submit">Save Image</button>
</p>
</form>
<canvas></canvas>
<a id="download-link"></a>
<script src="script.js"></script>
/**
* Elements.
*/
var textarea= document.querySelector('textarea');
var svgContainer = document.querySelector('#svg-container');
var loadSVGForm = document.querySelector('#load-svg');
var saveImageForm = document.querySelector('#save-image');
var loadButton = loadSVGForm.querySelector('button');
var saveButton = saveImageForm.querySelector('button');
var widthInput = saveImageForm.elements.width;
var heightInput = saveImageForm.elements.height;
var filenameInput = saveImageForm.elements.filename;
var canvas = document.querySelector('canvas');
var downloadLink = document.querySelector('#download-link');
var svg;
/**
* Resizes SVG element.
*
* @param {object} dimensions
* @param {number} [dimensions.width]
* @param {number} [dimensions.height]
*/
function resizeSVG(dimensions) {
if (!svg) {
return
}
if (dimensions.width) {
svg.setAttribute('width', dimensions.width);
}
if (dimensions.height) {
svg.setAttribute('height', dimensions.height);
}
}
/**
* Load SVG.
*/
loadSVGForm.addEventListener('submit', function loadSVG(event) {
event.preventDefault();
svgContainer.innerHTML= textarea.value;
svg = svgContainer.querySelector('svg');
widthInput.value = svg.clientWidth || svg.getBoundingClientRect().width;
heightInput.value = svg.clientHeight || svg.getBoundingClientRect().height;
filenameInput.value = svg.getAttribute('aria-label') || svg.id || 'untitled';
});
/**
* Resize SVG.
*/
widthInput.addEventListener('input', function(event) {
resizeSVG({ width: event.target.value });
});
heightInput.addEventListener('input', function(event) {
resizeSVG({ height: event.target.value });
});
/**
* Save image.
*/
saveImageForm.addEventListener('submit', function saveImage(event) {
event.preventDefault();
var width = widthInput.value;
var height = heightInput.value;
resizeSVG({
width: width,
height: height
});
canvas.width = width;
canvas.height = height;
var xml = new XMLSerializer().serializeToString(svg);
var img = new Image();
var blob = new Blob([xml], { type: 'image/svg+xml' });
var url = URL.createObjectURL(blob);
window.form = event.target;
img.addEventListener('load', function drawImageAndDownload() {
URL.revokeObjectURL(url);
canvas.getContext('2d').drawImage(img, 0, 0);
var extension = saveImageForm.elements.extension.value;
var mimeType = 'image/' + extension;
var uri = canvas.toDataURL(mimeType).replace(mimeType, 'octet/stream');
downloadLink.href = uri;
downloadLink.download = filenameInput.value + '.' + extension;
downloadLink.click();
// cleanup
URL.revokeObjectURL(uri);
img.removeEventListener('load', drawImageAndDownload);
});
img.src = url;
});
body {
font-family: "Lucida Grande", Helvetica, Arial, sans-serif;
}
#download-link {
display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment