Last active
December 31, 2020 21:44
-
-
Save remarkablemark/2450678b4118701c2c2231a6358bccb3 to your computer and use it in GitHub Desktop.
SVG to Image: https://remarkablemark.org/blog/2020/12/30/svg-to-image/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> | |
<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> | |
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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