File: addon/utils/nf/svg-dom.js
/* globals getComputedStyle, Image, Blob, URL */
/**
@module utils/nf/svg-dom
*/
/**
Traverses an element and all of its descendants, setting their
inline style property to whatever the computed style is.
@method inlineAllStyles
@param element {Element} the dom element to traverse.
@private
*/
function inlineAllStyles(element) {
var styles = getComputedStyle(element);
for(var key in styles) {
if(styles.hasOwnProperty(key)) {
element.style[key] = styles[key];
}
}
for(var i = 0; i < element.childNodes.length; i++) {
var node = element.childNodes[i];
if(node.nodeType === 1) {
inlineAllStyles(node);
}
}
}
/**
Renders an SVG element to a Base64 encoded data URI.
@method svgToImageUrl
@param svg {SVGSVGElement} the svg element to render
*/
export function svgToImageUrl(svg, callback) {
var clone = svg.cloneNode(true);
var parent = svg.parentElement;
var canvas = document.createElement('canvas');
canvas.setAttribute('width', svg.getAttribute('width'));
canvas.setAttribute('height', svg.getAttribute('height'));
var context = canvas.getContext('2d');
parent.insertBefore(clone, svg);
clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
inlineAllStyles(clone);
var img = new Image();
var blob = new Blob([clone.outerHTML], { type: 'image/svg+xml;charset=utf-8' });
clone.remove();
var url = URL.createObjectURL(blob);
img.onload = function(){
context.drawImage(img, 0, 0);
URL.revokeObjectURL(url);
if(callback) {
callback(canvas.toDataURL());
}
canvas.remove();
};
img.src = url;
}
/**
Triggers a download of an image rendered from the passed svg document
@method downloadSvg
@param svg {SVGSVGElement} the svg document to render
*/
export function downloadSvg(svg) {
svgToImageUrl(svg, function(url) {
var dlUrl = url.replace('image/png', 'image/octet-stream');
location.href = dlUrl;
});
}
/**
@method getMousePoint
@param container {SVGElement} the container reference to get the mouse position from
@param e {MouseEvent} A DOM mouse event
@return {Object} the {x, y} data of the mouse position relative to the container
*/
export function getMousePoint(container, e) {
var x, y;
if(e && e.hasOwnProperty('clientX') && e.hasOwnProperty('clientY')) {
var svg = container.ownerSVGElement || container;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
point.x = e.clientX;
point.y = e.clientY;
point = point.matrixTransform(container.getScreenCTM().inverse());
x = point.x;
y = point.y;
} else {
var rect = container.getBoundingClientRect();
x = e.clientX - rect.left - container.clientLeft;
y = e.clientY - rect.top - container.clientTop;
}
}
return {
x: x,
y: y,
};
}
/**
Creates an SVG path string for a rectangle
@method getRectPath
@param x the x position of the rectangle
@param y {Number} the y position of the rectangle
@param w {Number} the width of the rectangle
@param h {Number} the height of the rectangle
@return {String} the svg path string for the rectangle
*/
export function getRectPath(x, y, w, h) {
x = +x || 0;
y = +y || 0;
w = +w || 0;
h = +h || 0;
var x2 = w + x;
var y2 = h + y;
return `M${x},${y} L${x},${y2} L${x2},${y2} L${x2},${y} L${x},${y}`;
}