mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Only use foreignObject rendering if browser is capable of rendering images
This commit is contained in:
@ -19,36 +19,48 @@ export default class ForeignObjectRenderer {
|
||||
this.ctx.scale(this.options.scale, this.options.scale);
|
||||
|
||||
options.logger.log(`ForeignObject renderer initialized with scale ${this.options.scale}`);
|
||||
const svg = createForeignObjectSVG(
|
||||
options.bounds.width,
|
||||
options.bounds.height,
|
||||
this.element
|
||||
);
|
||||
|
||||
const xmlns = 'http://www.w3.org/2000/svg';
|
||||
const svg = document.createElementNS(xmlns, 'svg');
|
||||
const foreignObject = document.createElementNS(xmlns, 'foreignObject');
|
||||
svg.setAttributeNS(null, 'width', options.bounds.width);
|
||||
svg.setAttributeNS(null, 'height', options.bounds.height);
|
||||
|
||||
foreignObject.setAttributeNS(null, 'width', '100%');
|
||||
foreignObject.setAttributeNS(null, 'height', '100%');
|
||||
foreignObject.setAttributeNS(null, 'externalResourcesRequired', 'true');
|
||||
svg.appendChild(foreignObject);
|
||||
|
||||
foreignObject.appendChild(this.element);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
if (options.backgroundColor) {
|
||||
this.ctx.fillStyle = options.backgroundColor.toString();
|
||||
this.ctx.fillRect(0, 0, options.bounds.width, options.bounds.height);
|
||||
}
|
||||
this.ctx.drawImage(img, 0, 0);
|
||||
resolve(this.canvas);
|
||||
};
|
||||
|
||||
img.onerror = reject;
|
||||
|
||||
img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(
|
||||
new XMLSerializer().serializeToString(svg)
|
||||
)}`;
|
||||
return loadSerializedSVG(svg).then(img => {
|
||||
if (options.backgroundColor) {
|
||||
this.ctx.fillStyle = options.backgroundColor.toString();
|
||||
this.ctx.fillRect(0, 0, options.bounds.width, options.bounds.height);
|
||||
}
|
||||
this.ctx.drawImage(img, 0, 0);
|
||||
return this.canvas;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const createForeignObjectSVG = (width: number, height: number, node: Node) => {
|
||||
const xmlns = 'http://www.w3.org/2000/svg';
|
||||
const svg = document.createElementNS(xmlns, 'svg');
|
||||
const foreignObject = document.createElementNS(xmlns, 'foreignObject');
|
||||
svg.setAttributeNS(null, 'width', width);
|
||||
svg.setAttributeNS(null, 'height', height);
|
||||
|
||||
foreignObject.setAttributeNS(null, 'width', '100%');
|
||||
foreignObject.setAttributeNS(null, 'height', '100%');
|
||||
foreignObject.setAttributeNS(null, 'externalResourcesRequired', 'true');
|
||||
svg.appendChild(foreignObject);
|
||||
|
||||
foreignObject.appendChild(node);
|
||||
|
||||
return svg;
|
||||
};
|
||||
|
||||
export const loadSerializedSVG = (svg: Node) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = () => resolve(img);
|
||||
img.onerror = reject;
|
||||
|
||||
img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(
|
||||
new XMLSerializer().serializeToString(svg)
|
||||
)}`;
|
||||
});
|
||||
};
|
||||
|
Reference in New Issue
Block a user