d3-svg-to-png
Advanced tools
Comparing version 0.1.8 to 0.2.0
122
index.js
@@ -1,26 +0,19 @@ | ||
const inlineStyles = target => { | ||
const selfCopyCss = elt => { | ||
const computed = window.getComputedStyle(elt); | ||
const css = {}; | ||
for (let i = 0; i < computed.length; i++) { | ||
css[computed[i]] = computed.getPropertyValue(computed[i]); | ||
} | ||
function inlineStyles (source, target) { | ||
// inline style from source element to the target (detached) one | ||
const computed = window.getComputedStyle(source); | ||
for (const styleKey of computed) { | ||
target.style[styleKey] = computed[styleKey] | ||
} | ||
for (const key in css) { | ||
elt.style[key] = css[key]; | ||
} | ||
return css; | ||
}; | ||
// recursively call inlineStyles for the element children | ||
for (let i = 0; i < source.children.length; i++) { | ||
inlineStyles(source.children[i], target.children[i]) | ||
} | ||
} | ||
const root = document.querySelector(target); | ||
selfCopyCss(root); | ||
root.querySelectorAll('*').forEach(elt => selfCopyCss(elt)); | ||
}; | ||
function copyToCanvas ({ source, target, scale, format, quality }) { | ||
let svgData = new XMLSerializer().serializeToString(target); | ||
let canvas = document.createElement('canvas'); | ||
let svgSize = source.getBoundingClientRect(); | ||
const copyToCanvas = ({ target, scale, format, quality }) => { | ||
var svg = document.querySelector(target); | ||
var svgData = new XMLSerializer().serializeToString(svg); | ||
var canvas = document.createElement('canvas'); | ||
var svgSize = svg.getBoundingClientRect(); | ||
//Resize can break shadows | ||
@@ -32,6 +25,7 @@ canvas.width = svgSize.width * scale; | ||
var ctxt = canvas.getContext('2d'); | ||
let ctxt = canvas.getContext('2d'); | ||
ctxt.scale(scale, scale); | ||
var img = document.createElement('img'); | ||
let img = document.createElement('img'); | ||
img.setAttribute( | ||
@@ -44,14 +38,9 @@ 'src', | ||
ctxt.drawImage(img, 0, 0); | ||
const file = canvas.toDataURL( | ||
`image/${format}`, | ||
(format = 'png'), | ||
quality | ||
); | ||
resolve(file); | ||
resolve(canvas.toDataURL(`image/${format === 'jpg' ? 'jpeg' : format}`, quality)); | ||
}; | ||
}); | ||
}; | ||
} | ||
const downloadImage = ({ file, name, format }) => { | ||
var a = document.createElement('a'); | ||
function downloadImage ({ file, name, format }) { | ||
let a = document.createElement('a'); | ||
a.download = `${name}.${format}`; | ||
@@ -61,6 +50,7 @@ a.href = file; | ||
a.click(); | ||
}; | ||
document.body.removeChild(a); | ||
} | ||
module.exports = async ( | ||
target, | ||
module.exports = async function ( | ||
source, | ||
name, | ||
@@ -73,24 +63,36 @@ { | ||
ignore = null, | ||
cssinline = 1 | ||
cssinline = 1, | ||
background = null | ||
} = {} | ||
) => { | ||
const elt = document.querySelector(target); | ||
//Remember all HTML and CSS, as we will modify the styles | ||
const rememberHTML = elt.innerHTML; | ||
var rememberCSS; | ||
) { | ||
// Accept a selector or directly a DOM Element | ||
source = (source instanceof Element) ? source : document.querySelector(source); | ||
// Create a new SVG element similar to the source one to avoid modifying the | ||
// source element. | ||
const target = document.createElementNS('http://www.w3.org/2000/svg', 'svg') | ||
target.innerHTML = source.innerHTML; | ||
for (const attr of source.attributes) { | ||
target.setAttribute(attr.name, attr.value); | ||
} | ||
// Set all the css styles inline on the target element based on the styles | ||
// of the source element | ||
if (cssinline === 1) { | ||
inlineStyles(source, target); | ||
} | ||
if (background) { | ||
target.style.background = background | ||
} | ||
//Remove unwanted elements | ||
if (ignore != null) { | ||
const elt = document.querySelector(ignore); | ||
const elt = target.querySelector(ignore); | ||
elt.parentNode.removeChild(elt); | ||
} | ||
//Set all the css styles inline | ||
if (cssinline === 1) { | ||
rememberCSS = elt.style.cssText; | ||
inlineStyles(target, ignore); | ||
} | ||
//Copy all html to a new canvas | ||
return await copyToCanvas({ | ||
const file = await copyToCanvas({ | ||
source, | ||
target, | ||
@@ -100,14 +102,8 @@ scale, | ||
quality | ||
}) | ||
.then(file => { | ||
//Download if necessary | ||
if (download) downloadImage({ file, name, format }); | ||
//Undo the changes to inline styles | ||
elt.innerHTML = rememberHTML; | ||
if (cssinline === 1) { | ||
elt.style.cssText = rememberCSS; | ||
} | ||
return file; | ||
}) | ||
.catch(console.error); | ||
}; | ||
}); | ||
if (download) { | ||
downloadImage({ file, name, format }); | ||
} | ||
return file; | ||
} |
{ | ||
"name": "d3-svg-to-png", | ||
"version": "0.1.8", | ||
"version": "0.2.0", | ||
"description": "Converts SVG elements to PNG and other image formats while keeping CSS styles", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -20,3 +20,3 @@ # d3-svg-to-png | ||
- **Selector** (String): Commonly 'svg'. | ||
- **Selector** (String): Commonly 'svg' or DOM Element. | ||
- **Name** (String): Name for the file output, without extension. | ||
@@ -35,3 +35,4 @@ | ||
download: false, | ||
ignore: '.ignored' | ||
ignore: '.ignored', | ||
background: 'white' | ||
}).then(fileData => { | ||
@@ -48,2 +49,3 @@ //do something with the data | ||
- **ignore** (string): A CSS selector that, the matched elements of which will not be added to the output. Default: _null_ | ||
- **background** (string): A style to be added to the svg element. The value will be added as the _background_ shorthand css property, so it can be a single color, an image a gradient or any thing that is a valid background. Default: _null_ | ||
@@ -50,0 +52,0 @@ ## Notes |
7329
71
102