diff --git a/src/ReactNativeSVG.web.ts b/src/ReactNativeSVG.web.ts index 0552854f..7e951204 100644 --- a/src/ReactNativeSVG.web.ts +++ b/src/ReactNativeSVG.web.ts @@ -449,8 +449,67 @@ export class Stop extends WebShape { tag = 'stop' as const; } +/* Taken from here: https://gist.github.com/jennyknuth/222825e315d45a738ed9d6e04c7a88d0 */ +function encodeSvg(svgString: string) { + return svgString + .replace( + '/g, '%3E') + .replace(/\s+/g, ' '); +} + export class Svg extends WebShape { tag = 'svg' as const; + toDataURL( + callback: (data: string) => void, + options: { width?: number; height?: number } = {}, + ) { + const ref = this.elementRef.current; + + if (ref == null) { + return; + } + + const rect = getBoundingClientRect(ref); + + const width = Number(options.width) || rect.width; + const height = Number(options.height) || rect.height; + + // @ts-expect-error "DOM" is not part of `compilerOptions.lib` + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.setAttribute('viewBox', `0 0 ${rect.width} ${rect.height}`); + svg.setAttribute('width', String(width)); + svg.setAttribute('height', String(height)); + // @ts-expect-error "DOM" is not part of `compilerOptions.lib` + svg.appendChild(ref.cloneNode(true)); + + // @ts-expect-error "DOM" is not part of `compilerOptions.lib` + const img = new window.Image(); + img.onload = () => { + // @ts-expect-error "DOM" is not part of `compilerOptions.lib` + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const context = canvas.getContext('2d'); + context?.drawImage(img, 0, 0); + callback(canvas.toDataURL().replace('data:image/png;base64,', '')); + }; + + img.src = `data:image/svg+xml;utf8,${encodeSvg( + // @ts-expect-error "DOM" is not part of `compilerOptions.lib` + new window.XMLSerializer().serializeToString(svg), + )}`; + } } export class Symbol extends WebShape {