Tengo un svg en una cadena, así:
const svgString = (color) => `<svg height="150" width="500"> <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:${color}" /> <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" /> <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" /> </svg>`;Considere que es un svg de ejemplo, el real es un poco más grande y más complejo, así que no preste mucha atención a ese ejemplo.
Lo que quiero es dibujar esa cadena SVG en un lienzo. He intentado algo como esto:
const canvas = document.createElement('canvas'); canvas.width = 18; canvas.height = 25; const ctx = canvas.getContext('2d'); const path = new Path2D(svgString('red')); ctx.drawImage(path, 0, 0, 18, 25);Pero eso falla con el siguiente error:
"<a class='gotoLine' href='#52:5'>52:5</a> Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'."Alguna idea de como resolver esto?
const svgString = (color) => `<svg height="150" width="500"> <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:${color}" /> <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" /> <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" /> </svg>`; const canvas = document.createElement('canvas'); canvas.width = 18; canvas.height = 25; const ctx = canvas.getContext('2d'); const path = new Path2D(svgString('red')); ctx.drawImage(path, 0, 0, 18, 25);Aquí tienes dos ejemplos. En ambos ejemplos, agregué el espacio de nombres SVG a la cadena, porque es un documento XML/SVG separado y no parte del HTML.
En el primer ejemplo, solo creo una URL de datos y la inserto como la fuente de un objeto de imagen. Aquí debe establecer el ancho y la altura.
En el segundo ejemplo, utilicé Blob y la función URL.createObjectURL() .
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); const svgString = (color) => `<svg xmlns="http://www.w3.org/2000/svg" height="150" width="500"> <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:${color}" /> <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" /> <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" /> </svg>`; var img = new Image(); img.width = 500; img.height = 150; img.addEventListener('load', e => { ctx.drawImage(e.target, 0, 0); }); img.src = `data:image/svg+xml,${svgString('red')}`; <canvas width="500" height="150" id="canvas"></canvas> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); const svgString = (color) => `<svg xmlns="http://www.w3.org/2000/svg" height="150" width="500"> <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:${color}" /> <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" /> <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" /> </svg>`; var svg = new Blob([svgString('red')], { type: "image/svg+xml;charset=utf-8" }); var url = URL.createObjectURL(svg); var img = new Image(); img.addEventListener('load', e => { ctx.drawImage(e.target, 0, 0); URL.revokeObjectURL(url); }); img.src = url; <canvas width="500" height="150" id="canvas"></canvas>