Skip to content

Instantly share code, notes, and snippets.

@gitawego
Last active August 29, 2015 14:01
Show Gist options
  • Save gitawego/c313c80633dcc439d6cf to your computer and use it in GitHub Desktop.
Save gitawego/c313c80633dcc439d6cf to your computer and use it in GitHub Desktop.
define(function(){
var supportsCSSText = getComputedStyle(document.body).cssText !== "";
return {
/**
* @method domToImage
* @param {HTMLElement} origElem
* @param {function(Error,Image)} callback
* @param {Object|String} style
* @param {String} style.href
* @param {Number} style.width
* @param {Number} style.height
* @param {Number} style.top
* @param {Number} style.left
*/
domToImage: function (origElem, callback, style) {
style = style || {};
if (typeof(style) === 'string') {
style = {
href: style
};
}
var left = (style.left || 0);
var top = (style.top || 0);
var elem = origElem.cloneNode(true);
Array.prototype.slice.call(elem.querySelectorAll('script')).forEach(function (s) {
s.parentNode.removeChild(s);
});
this.inlineStyles(elem, origElem);
elem.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
// serialize the DOM node to a String
var serialized = new XMLSerializer().serializeToString(elem);
// Create well formed data URL with our DOM string wrapped in SVG
var dataUri = "data:image/svg+xml;charset=utf-8," +
(style.href ? '<?xml-stylesheet type="text/css" href="' + style.href + '"?>' : '') +
"<svg xmlns='http://www.w3.org/2000/svg' width='" + ((style.width || origElem.offsetWidth) + left) +
"' height='" + ((style.height || origElem.offsetHeight) + top) + "'>" +
"<foreignObject width='100%' height='100%' x='" + left + "' y='" + top + "'>" +
serialized +
"</foreignObject>" +
"</svg>";
// create new, actual image
var img = new Image();
// when loaded, fire onload callback with actual image node
img.onload = function () {
callback && callback(null, this);
};
img.onerror = function (error) {
callback && callback(error);
};
img.src = dataUri;
},
inlineStyles: function inlineStyles(elem, origElem) {
var children = elem.querySelectorAll('*');
var origChildren = origElem.querySelectorAll('*');
var self = this;
// copy the current style to the clone
this.copyCSS(elem, origElem);
// collect all nodes within the element, copy the current style to the clone
Array.prototype.forEach.call(children, function (child, i) {
self.copyCSS(child, origChildren[i]);
});
// strip margins from the outer element
elem.style.margin = elem.style.marginLeft = elem.style.marginTop = elem.style.marginBottom = elem.style.marginRight = '';
elem.style.left = elem.style.top = elem.style.bottom = elem.style.right = '';
return elem;
},
copyCSS: function copyCSS(elem, origElem) {
var computedStyle = getComputedStyle(origElem);
if (supportsCSSText) {
elem.style.cssText = computedStyle.cssText;
} else {
// Really, Firefox?
for (var prop in computedStyle) {
if (isNaN(parseInt(prop, 10)) && typeof computedStyle[prop] !== 'function' && !(/^(cssText|length|parentRule)$/).test(prop)) {
elem.style[prop] = computedStyle[prop];
}
}
}
}
}
});
@gitawego
Copy link
Author

gitawego commented May 5, 2014

example:

var targetNode = document.getElementById('testNode');
domToImage(targetNode,function(error,img){
     if(error){ return console.error(error); }
    document.body.appendChild(img);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment