I'm working with the vis.js library, and rendering nodes with custom HTML via the svg
tag.
My online project is at: https://stackblitz.com/edit/visjs-with-angular
The problem I'm having is when I attempt to add an image to the div
, which is inside an svg
.
You can see the vis.component.ts
in the 'app\app\vis' folder of my project, and its associated HTML view file.
In the drawSvgNetwork()
function you will see where I build out the SVG. I figured I'd be able to add a <i>
tag with a background-image url
, but it doesn't seem to be rendering when vis.js renders the nodes:
var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="390" height="65">' +
'<rect x="0" y="0" width="100%" height="100%" fill="#7890A7" stroke-width="20" stroke="#ffffff" ></rect>' +
'<foreignObject x="15" y="10" width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-family:Arial; font-size:30px">' +
' <em>I</em> am' +
'<span style="color:white; text-shadow:0 0 20px #000000;">' +
' HTML in SVG!</span>' +
// * THIS IMAGE IS NOT RENDERING *
'<i style="background-image: url(https://openclipart.org/download/280615/July-4th-v2B.svg);"></i>' +
'</div>' +
'</foreignObject>' +
'</svg>';
i.e. Here is what you will see when running my online project.
.
*For reference:
The full online examples are at: https://visjs.github.io/vis-network/examples/ And the specific demo page is here (view source to see js code): https://visjs.github.io/vis-network/examples/network/nodeStyles/HTMLInNodes.html
Looks like with visjs
it's not possible to load an external image inside an SVG, nor in <foreignObject>
, neither in <Image>
tag.
Here is an open issue for the problem on github: Image tag is not loading inside the svg
The maintainer of the repository answered that it was not possible.
A workaround can be found in the same thread (but it may not be suitable for you): the idea is to load the image separately and render it as dataUrl
Loading the svg image and converting it to dataUrl:
loadImage(url) {
const img = new Image();
img.crossOrigin = "anonymous";
img.src = url;
return Observable.fromEvent(img, 'load')
.map((e: Event) => {
const canvas = document.createElement('canvas');
canvas.getContext('2d').drawImage(e.target as HTMLImageElement, 0, 0);
const dataURL = canvas.toDataURL();
return dataURL;
})
}
Using the acquired dataUrl as background instead of the direct svg file url:
'<i style="background-image: url(' + dataUrl + '); display: inline-block; width: 40px; height: 20px; background-size: contain;"></i>' +
Here is the corrected project https://stackblitz.com/edit/visjs-with-angular-m63jme (I also replaced the svg file, which was used in the original project and contained a US flag, with another arbitrary svg to avoid issues in FF, see below)
Firefox has some issues with rendering an svg file on canvas, when the file contains width
and height
attributes specified as percentages. See the SO questions for more details: 1, 2. So be sure to use an svg with width
and height
attributes that are not percentages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With