html2canvas
html2canvas copied to clipboard
SVG Element not rendered in html2Canvas
Please make sure you are testing with the latest release of html2canvas. Old versions are not supported and issues reported for them will be closed.
Please follow the general troubleshooting steps first:
- [ x] You are using the latest version
- [ x] You are testing using the non-minified version of html2canvas and checked any potential issues reported in the console
Bug reports:
I have a roadmap with svg elements to represent links between two items like this :
the svg code looks like :
each time that i try to print to png, my links are not rendered:
My generation code is :
html2canvas(
document.getElementById("roadmapPrint"),
{
backgroundColor:null,
}
).then(function(canvas) {
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
var a = document.createElement('a');
a.href = image ;
a.id = "tempAtoDelete"
a.download = "filename.png";
document.body.appendChild(a);
a.click();
let aToDelete = document.getElementById("tempAtoDelete");
document.body.removeChild(aToDelete);
})
Do you have some advices ? i read that your library is able to manage svg elements, is it the case ? Thank you a lot for your help,
Specifications:
- html2canvas version tested with: "^1.4.0"
- Browser & version: Google Chrome Version 96.0.4664.110 (Build officiel) (64 bits)
- Operating system: Windows
Facing same issue , any solution kindly suggest
hi @sandhya225, I have fixed my issue converting all svg elements to canvas before use html2canvas librairy. This was an old solution (6 years old) but it works fine. @niklasvh : there is another way to do that ?
See my steps below:
- install the version 1.5.3 of canvg librairy and import the canvg function (for information this version is dowloaded more than 140000 per week..) (there is no dependence vulnerability with the last version of node/npm/CRA)
npm install [email protected]
import canvg from 'canvg'
- get all your svg element and create a canvas for each (track them to an array to delete them after)
//FOR EACH SVG ELEMENT, A CANVAS WILL BE CREATED => AT THE END WE NEED TO DELETE THEM
var svgNodesToRemove = [];
//GET ALL SVG ELEMENT
let svgElements = document.body.querySelectorAll('svg');
//LOOP ON EACH ELEMENT
svgElements.forEach(function(item) {
//YOU CAN PROCEED TO ELEMENT TREATMENT BEFORE CONVERT TO CANVAS
let children = item.childNodes
children.forEach(function(child) {
//IN MY CASE I USE ANIMATION FOR MY SVG PATH AND NEED TO FIX THE OPACITY STYLE
child.style.opacity = 1;
})
//TRIM EACH ITEM IN THE LOOP
let svg = item.outerHTML.trim();
//CREATE CANVAS FOR YOUR CURRENT SVG
var canvas = document.createElement('canvas');
//UPDATE THE NEEDED ATTRIBUTE WITH AND HEIGHT
canvas.width = item.getBoundingClientRect().width;
canvas.height = item.getBoundingClientRect().height;
//CONVERT SVG TO CANVAS
canvg(canvas, svg);
//UPDATE THE CANVAS POSITION TO THE SVG ELEMENT
if (item.style.position) {
canvas.style.position += item.style.position;
canvas.style.left += item.style.left;
canvas.style.top += item.style.top;
}
//APPEND THE CANVAS TO THE DOM
item.parentNode.appendChild(canvas);
//TRACK CANVAS TO BE DELTED AFTER
svgNodesToRemove.push(canvas)
});
I did not hidde my current svg element in the dom because there are not rendered...
- now you are able to use html2canvas :
html2canvas(
document.getElementById("roadmapPrint"),
{
backgroundColor:null,
}
).then(function(canvas){
//YOUR LOGIC
//....
//DELETE SVG CANVAS
svgNodesToRemove.forEach(function(element){
element.remove();
})
}).catch((err)=>{
//DISPLAY ERROR
console.log(err)
//DELETE SVG CANVAS
svgNodesToRemove.forEach(function(element){
element.remove();
})
});
hope it helps
@julienlaurent-migso very good
If I use <use>
tag, the solution others mentioned is not worked
like:
<svg aria-hidden='true' className='example'> <use xlinkHref={item.icon} /> </svg>
So, I can not get TRUE outerHTML in svg
If I use
<use>
tag, the solution others mentioned is not worked like:<svg aria-hidden='true' className='example'> <use xlinkHref={item.icon} /> </svg>
So, I can not get TRUE outerHTML in svg
Your problem solved?