Javascript convert svg image to html svg tag
SVG files still only display inline elements and not tags EDIT: The way you create an svg like this is actually by converting the image tag into Base64 and the setting that as the xlink:href in the image attributes like this: and then triggering the download on the whole svg url like this: you can convert pngs like this here: then setting the attribute it’s small and convenient Solution 1: I don’t know if this is the right way to do but you can directly fetch that svg and render it to the DOM using or something like with react Solution 2: If you used , it already uses package, so you can do this, which will cause the image to load inline as React components containing the SVG elements directly, instead of by a link: If you are not using create-react-app so not using svgr yet, you can add it to your project (see docs)
How to convert image (svg) to rendered svg in javascript?
Using an img tag with a src in essentially makes an HTTP request to the server for you. In this case you have to make the request yourself. You can do that with the Fetch API which is native to JavaScript.
// This should be the path to your SVG file. // Modify if incorrect. const svgFilePath = 'public/images/my_image.svg'; // Select the current image. const image = document.querySelector('.svg'); // Create a new dom parser to turn the SVG string into an element. const parser = new DOMParser(); // Fetch the file from the server. fetch(svgFilePath) .then(response => response.text()) .then(text => < // Turn the raw text into a document with the svg element in it. const parsed = parser.parseFromString(text, 'text/html'); // Select the element from that document. const svg = parsed.querySelector('svg'); // If both the image and svg are found, replace the image with the svg. if (image !== null && svg !== null) < image.replaceWith(svg); >>);
And with handling multiple files. In this case I’ve used an array with objects that hold the id of the image element you want to get and the src of the svg file.
// Array of object containing the id of the image you want to replace // and the src of the SVG that takes it's place. const svgFiles = [ < id: 'image1', src: 'public/images/my_image_1.svg' >, < id: 'image2', src: 'public/images/my_image_2.svg' >, < id: 'image3', src: 'public/images/my_image_3.svg' >, ]; // Create a new dom parser to turn the SVG string into an element. const parser = new DOMParser(); // Loop over each object in the array and use the id and src // with a destructuring assignment. for (const < id, src >of svgFiles) < // Find the image. If it is not there, continue with the // loop to the next iteration. let image = document.getElementById(id); if (image === null) continue; // Fetch the file from the server. fetch(src) .then(response =>response.text()) .then(text => < // Turn the raw text into a document with the svg element in it. const parsed = parser.parseFromString(text, 'text/html'); // Select the element from that document. const svg = parsed.querySelector('svg'); // If the svg is found, replace the image with the svg. // Otherwise, continue the loop. if (svg === null) continue; image.replaceWith(svg); >); >
I noticed that you are using asset() function so I’m guessing you don’t necessary want it to be JS
You can use Laravel SVG package which provides @svg() blade directive.
it’s small and convenient
SVG Element — GeeksforGeeks, SVG stands for Scalable Vector Graphic. It can be used to make graphics and animations like in HTML canvas. The
How to Convert svg link into svg tag
I don’t know if this is the right way to do but you can directly fetch that svg and render it to the DOM using innerHTML or something like dangerouslySetInnerHTML with react
let svgUrl = 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/hackerrank.svg' function getTheSvg(url) < return fetch(url).then(res =>res.text()); > getTheSvg(svgUrl).then(res => < let svgDiv = document.querySelector('.svg') svgDiv.innerHTML = res >)
If you used create-react-app , it already uses @svgr/webpack package, so you can do this, which will cause the image to load inline as React components containing the SVG elements directly, instead of by a link:
import < ReactComponent as RectangleIcon >from './rectangle.svg'; export const MyComponent = () => < return >
If you are not using create-react-app so not using svgr yet, you can add it to your project (see docs)
How to convert image (svg) to rendered svg in javascript?, const image = document.querySelector(‘.svg’); // Create a new dom parser to turn the SVG string into an element. const
Save inline SVG as JPEG/PNG/SVG
Nowadays this is pretty simple.
it actually works outside of the Stack Overflow snippet
var btn = document.querySelector('button'); var svg = document.querySelector('svg'); var canvas = document.querySelector('canvas'); 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); > btn.addEventListener('click', function () < var canvas = document.getElementById('canvas'); 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], ); 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; >);
Regarding the downloading part, you can set up a filename and etc etc (although not in this example). Some days ago I answered a question on how to download a specific portion of HTML from the given page. It might be useful regarding the downloading part: https://stackoverflow.com/a/28087280/2178180
update : now letting you specify the filename
Here’s a solution that works in IE11 as well.
I just did a bunch of testing of various methods of this and while the above answer by Ciro Costa is fantastic in that it works in Firefox and Chrome it does not work in IE11. IE11 fails due to a security issue with rendering an svg to the canvas which requires a canvas implementation, canvg. Here’s a solution using canvg that’s pretty terse and works in the latest versions of Chrome, Firefox, Edge, and IE11.
Fiddle: https://jsfiddle.net/StefanValentin/9mudw0ts/
var svg = document.querySelector('#my-svg'); var data = (new XMLSerializer()).serializeToString(svg); // We can just create a canvas element inline so you don't even need one on the DOM. Cool! var canvas = document.createElement('canvas'); canvg(canvas, data, < renderCallback: function() < canvas.toBlob(function(blob) < download('MyImageName.png', blob); >); > >);
The download function above could be whatever you want to do, as there are many ways to trigger a download via JavaScript. Here’s the one we use that works in all the browsers I’ve tested.
// Initiate download of blob function download( filename, // string blob // Blob ) < if (window.navigator.msSaveOrOpenBlob) < window.navigator.msSaveBlob(blob, filename); >else < const elem = window.document.createElement('a'); elem.href = window.URL.createObjectURL(blob); elem.download = filename; document.body.appendChild(elem); elem.click(); document.body.removeChild(elem); >>
Working off @CiroCosta. 1 option if you are having trouble exporting an element you could just draw the image to the canvas before drawing the svg image
btn.addEventListener('click', function () < var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var data = (new XMLSerializer()).serializeToString(svg); var DOMURL = window.URL || window.webkitURL || window; // get the raw image from the DOM var rawImage = document.getElementById('yourimageID'); var img = new Image(); var svgBlob = new Blob([data], ); var url = DOMURL.createObjectURL(svgBlob); img.onload = function () < ctx.drawImage(rawImage, 0, 0); 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; >);
Worked for me but only for png and jpeg. SVG files still only display inline elements and not tags
EDIT: The way you create an svg like this is actually by converting the image tag into Base64 and the setting that as the xlink:href in the image attributes like this:
and then triggering the download on the whole svg url like this:
btn.addEventListener('click', function () < var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var data = (new XMLSerializer()).serializeToString(svg); var DOMURL = window.URL || window.webkitURL || window; var rawImage = document.getElementById('yourimageID'); var img = new Image(); var svgBlob = new Blob([data], ); var url = DOMURL.createObjectURL(svgBlob); img.onload = function () < ctx.drawImage(img, 0, 0); triggerDownload(url); DOMURL.revokeObjectURL(url); >>;
you can convert pngs like this here:
function getDataUri(url, callback) < var image = new Image(); image.onload = function () < var canvas = document.createElement('canvas'); canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size canvas.getContext('2d').drawImage(this, 0, 0); // Get raw image data callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '')); // . or get as Data URI callback(canvas.toDataURL('image/png')); >; image.src = url; >
then setting the attribute
getDataUri('localImagepath', function (dataUri) < image.setAttribute('xlink:href', dataUri); >);
Javascript — convert HTML div with SVG to image, I saw several examples here using html2canvas. When I tried using it, the Highcharts’ SVG element wansn’t included in the output image. Does
Getting started
Create a basic Html markup and include the svg.js script:
Or just import svg.js in your javascript application:
import < SVG >from '@svgdotjs/svg.js'
Note: All properties that were former available on the global SVG object need to be imported now, see example below:
import < SVG, extend as SVGextend, Element as SVGElement >from '@svgdotjs/svg.js'
Create an SVG document
Next, use the SVG() function to create an SVG document and add it to the html page:
var draw = SVG().addTo('body').size(300, 300) var rect = draw.rect(100, 100).attr(< fill: '#f06' >)
You can pass any css selector to addTo or simply a node.
SVG.js does not set a size for the document automatically. So make sure to call size() with appropriate values.
E.g. to set the size to the dimensions of its parent use this:
var draw = SVG().addTo('#someId').size('100%', '100%')
Wait for DOM to be loaded
This might seem obvious to many but it’s still worth mentioning. If you include your js files in the head of your document, make sure to wait for the DOM to be loaded:
SVG.on(document, 'DOMContentLoaded', function() < var draw = SVG().addTo('body') >)
This is not an issue if you include your js at the bottom.
Pure SVG
SVG.js also works outside of the HTML DOM, inside an SVG document for example:
The SVG() function
This function does not only create new documents, it can also retrieve svg.js objects from the dom or create new ones from an svg fragment:
// new document var draw = SVG() // get rect from dom var rect = SVG('#myRectId') // or var rect = SVG('rect') // any css selector will do var path = SVG('#group1 path.myClass') // create new object from fragment var circle = SVG('') // convert node to svg.js object var obj = SVG(node)
Playground
Just to get you going, here is a basic setup. Everything is present to start fiddling.
SVG.js © 2012-2021 Wout Fierens — SVG.js is released under the terms of the MIT license.