-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
body { | ||
font-family: Open Sans, sans-serif; | ||
font-size: 0.9em; | ||
color: #333; | ||
|
||
|
||
background-image: url(data:image/png;base64,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); | ||
} | ||
|
||
section { | ||
max-width: 710px; | ||
margin: 0 auto; | ||
} | ||
|
||
.sub { | ||
height: 210px; | ||
} | ||
|
||
.sub > * { | ||
float: left; | ||
} | ||
|
||
pre { | ||
background: #333; | ||
color: #eee; | ||
padding: 10px; | ||
} | ||
|
||
canvas { | ||
background: #eee; | ||
} | ||
|
||
h1 { | ||
border-bottom: 1px solid #fff; | ||
clear: both; | ||
margin-top: 1em; | ||
text-shadow: 1px 1px 0px white; | ||
} | ||
|
||
p { | ||
color: #555; | ||
line-height: 1.4em; | ||
} | ||
|
||
strong { | ||
font-weight: 600; | ||
} | ||
|
||
h1::after { | ||
content: ''; | ||
width: 100%; | ||
display: block; | ||
border-bottom: 1px solid rgba(30,30,30,0.4); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | ||
<title>Domvas!</title> | ||
|
||
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600,300' rel='stylesheet' type='text/css'> | ||
<link rel="stylesheet" href="css/main.css"> | ||
|
||
<style type="text/css"> | ||
|
||
#dom { | ||
font-family: Arial; | ||
border: 5px solid rgba(0,0,0,0.2); | ||
border-radius: 10px; | ||
width: 260px; | ||
padding: 5px 20px; | ||
background: #4f8eff; | ||
|
||
text-shadow: 1px 1px 0 #264782; | ||
line-height: 1.4em; | ||
|
||
margin: 20px; | ||
} | ||
|
||
#dom p { | ||
color: rgba(255,255,255,0.8); | ||
} | ||
|
||
#dom strong { | ||
color: #fff; | ||
font-style: italic; | ||
} | ||
|
||
</style> | ||
</head> | ||
<body> | ||
|
||
<section> | ||
|
||
<h1>Domvas!</h1> | ||
|
||
<p><strong>Domvas implements the missing piece that connects the DOM and Canvas</strong>. It gives to the ability to take arbitrary DOM content and paint it to a Canvas of your choice.</p> | ||
|
||
<p>That dialog that is a pain to layout in Canvas but needs to be animated? Yep. Always wanted to use CSS transforms in Canvas? Yep. I think you get the idea.</p> | ||
|
||
<h1>Demo</h1> | ||
|
||
<div class="sub"> | ||
|
||
<div style='font-size:30px' id="dom"> | ||
<p>EHRMAGERD <strong>DOM IN CANVAS</strong>!</p> | ||
</div> | ||
|
||
<canvas id="test" width="350" height="206"></canvas> | ||
|
||
</div> | ||
|
||
<h1>Usage</h1> | ||
|
||
<pre> | ||
var canvas = document.getElementById("test"); | ||
var context = canvas.getContext('2d'); | ||
|
||
domvas.toImage(document.getElementById("dom"), function() { | ||
context.drawImage(this, 20, 20); | ||
}); | ||
</pre> | ||
|
||
<p>Extended documentation:</p> | ||
|
||
<pre> | ||
domvas.toImage(domElement, readyCallback, width, height, left, top); | ||
</pre> | ||
|
||
<h1>How it works</h1> | ||
|
||
<p>Domvas uses a feature of SVG that allows you to embed XHTML content into the SVG – and as you might know, the actual SVG can be used as a data uri, and therefore behaves like a standard image.</p> | ||
|
||
<p>I have written about this technique in 2008 <a href="http://paulbakaus.com/2008/08/19/css-transforms-for-firefox/">when I brought CSS transforms to browsers that did not have them</a>. It took a little more experimentation to transform it into a reusable plugin: HTML content needs to be serialized to XML, and all styles have to be inlined.</p> | ||
|
||
<h1>Caveats</h1> | ||
|
||
<ul> | ||
<li><strong>Internet Explorer</strong> is not supported, at it doesn't support the foreignObject tag in SVG.</li> | ||
<li>SVG's foreignObject is subject to strong security – meaning any external content will likely fail (i.e. iframes, web fonts)</li> | ||
<li>The DOM object is <strong>not linked, but copied</strong> – if you change the style of the DOM object, it will not automatically update in Canvas</li> | ||
<li>Content outside the bounding box of the element will be cut of per default if painted to Canvas. Don't worry though, simply pass a more confortable offset to the toImage function (see above)</li> | ||
</ul> | ||
|
||
<h1>Credits / License</h1> | ||
|
||
<p>©2012 Paul Bakaus. Licensed under MIT. Reach out on <a href='http://twitter.com/pbakaus'>Twitter</a>!</p> | ||
|
||
|
||
</section> | ||
|
||
<script src="src/domvas.js"></script> | ||
<script> | ||
|
||
var canvas = document.getElementById("test"); | ||
var context = canvas.getContext('2d'); | ||
|
||
domvas.toImage(document.getElementById("dom"), function() { | ||
// Look ma, I just converted this element to an image and can now to funky stuff! | ||
context.drawImage(this, 20, 20); | ||
}); | ||
|
||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
"use strict"; | ||
|
||
(function() { | ||
|
||
var supportsCSSText = getComputedStyle(document.body).cssText !== ""; | ||
|
||
function copyCSS(elem, origElem, log) { | ||
|
||
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]; | ||
} | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
function inlineStyles(elem, origElem) { | ||
|
||
var children = elem.querySelectorAll('*'); | ||
var origChildren = origElem.querySelectorAll('*'); | ||
|
||
// copy the current style to the clone | ||
copyCSS(elem, origElem, 1); | ||
|
||
// collect all nodes within the element, copy the current style to the clone | ||
Array.prototype.forEach.call(children, function(child, i) { | ||
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 = ''; | ||
|
||
} | ||
|
||
window.domvas = { | ||
|
||
toImage: function(origElem, callback, width, height, left, top) { | ||
|
||
left = (left || 0); | ||
top = (top || 0); | ||
|
||
var elem = origElem.cloneNode(true); | ||
|
||
// inline all CSS (ugh..) | ||
inlineStyles(elem, origElem); | ||
|
||
// unfortunately, SVG can only eat well formed XHTML | ||
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," + | ||
"<svg xmlns='http://www.w3.org/2000/svg' width='" + ((width || origElem.offsetWidth) + left) + "' height='" + ((height || origElem.offsetHeight) + top) + "'>" + | ||
"<foreignObject width='100%' height='100%' x='" + left + "' y='" + top + "'>" + | ||
serialized + | ||
"</foreignObject>" + | ||
"</svg>"; | ||
|
||
// create new, actual image | ||
var img = new Image(); | ||
img.src = dataUri; | ||
|
||
// when loaded, fire onload callback with actual image node | ||
img.onload = function() { | ||
if(callback) { | ||
callback.call(this, this); | ||
} | ||
}; | ||
|
||
} | ||
|
||
}; | ||
|
||
})(); | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.