export default { NS: 'http://www.w3.org/2000/svg', // svgOrg: svg element // allCss : true includes all svg css styles, false includes only matched styles export (svgOrg, allCss) { let svg = null if (this.isSvgData(svgOrg)) { svg = svgOrg.cloneNode(true) let childs = svgOrg.parentNode.querySelectorAll('*') let cssStyle = {} let rules = this.getcssRules() for (let child of childs) { let elRules = rules if (!allCss) { elRules = rules.filter((rule) => { return child.matches(rule.selectorText) }) } for (let rule of elRules) { cssStyle[rule.selectorText] = rule.cssText } } let css = Object.values(cssStyle).join('\n') if (css) { let style = document.createElementNS(this.NS, 'style') style.type = 'text/css' svg.insertBefore(style, svg.childNodes[0]) style.innerHTML = css svg.appendChild(style) } } return svg }, makeCanvas (width, height, background) { let canvas = document.createElement('canvas') canvas.width = width canvas.height = height let ctx = canvas.getContext('2d') ctx.fillStyle = background || 'white' ctx.fillRect(0, 0, canvas.width, canvas.height) return canvas }, serialize (svg) { return (new XMLSerializer()).serializeToString(svg) }, svgToImg (svg, canvas, cb) { let xml = this.serialize(svg) let img = new Image() let ctx = canvas.getContext('2d') img.onload = function () { ctx.drawImage(this, 0, 0) let png = canvas.toDataURL('image/png') cb(null, png, ctx) } img.onerror = function (err) { cb(err) } img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(xml))) }, save (svg) { return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(this.serialize(svg)) }, getcssRules () { let rules = [] for (let styles of document.styleSheets) { let styleRules = this.readRules(styles) for (let rule of styleRules) { if (rule && rule.cssText) { rules.push(rule) } } } return rules }, readRules (styles) { try { if (!styles.cssRules) return styles.rules || [] } catch (e) { // Firefox returns Security Error if stylesheet originates from different domain if (e.name !== 'SecurityError') throw e return [] } return styles.cssRules }, toDom (svgData) { let div = document.createElement('div') div.innerHTML = svgData return div.firstChild || null }, toObject (svg) { if (svg) { let attrs = {} if (svg.attributes) { for (let i = svg.attributes.length; i >= 0; i--) { let a = svg.attributes[i] if (a) attrs[a.name] = a.value } } let data = svg.innerHTML if (data) return { attrs, data } } return null }, svgElFromString (svgData) { let svgEl = this.toDom(svgData) if (!this.isSvgData(svgEl)) return svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg') return svgEl }, svgDataToUrl (svgData, attrs) { if (typeof (attrs) === 'object') { for (let a in attrs) { let attribute = (attrs[a]) ? (attrs[a]) : '' svgData.setAttribute(a, attribute) } } let svg = this.export(svgData) if (svg) return this.svgToUrl(this.serialize(svg)) return null }, isSvgData (svgData) { if (!svgData.firstChild) return false return (svgData.firstChild.parentNode.nodeName === 'svg') }, svgToUrl (svg) { let xml = new Blob([svg], { type: 'image/svg+xml' }) let url = URL.createObjectURL(xml) return url } }