Skip to content

Instantly share code, notes, and snippets.

@biovisualize
Forked from vectorsize/README.md
Last active December 31, 2015 18:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biovisualize/8026810 to your computer and use it in GitHub Desktop.
Save biovisualize/8026810 to your computer and use it in GitHub Desktop.

Mouseover to draw circles!

This is a quick proof-of-concept example demonstrating how to create a canvas scenegraph in the DOM using document fragments. The scenegraph in this example consists of a simple container svg element and a number of child circle elements.

The content positions and sizes are calculated offline and the actual DOM tree doesn't even need to be aware of out svg. To render them, we use a timer that iterates over the child elements and draws them to a canvas element.

This is a modification of the original DOM-to-Canvas using D3 proof of conncept.

<!DOCTYPE html>
<html>
<head>
<title>Custom Elements</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.3.2"></script>
<style type="text/css">
body {
margin: 0;
}
</style>
</head>
<body>
<canvas id="container"></canvas>
<script type="text/javascript">
var w = 960,
h = 500;
// creare a document fragment to draw "offline"
var sketchFrag = document.createDocumentFragment();
// var sketch = d3.select(sketchFrag).append("svg")
var sketch = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
var circ = sketch.selectAll("circle")
.data(d3.range(50000))
.enter().append("circle")
.attr({
x:function(d, i){ return ~~(Math.random()*w); },
y: function(d, i){ return ~~(Math.random()*h); },
radius: function(d, i){ return ~~(Math.random()*100)+10; },
strokeStyle: "red"
});
sketch.call(custom);
function custom(selection) {
var canvas = document.getElementById('container');
var context = canvas.getContext("2d");
selection.each(function() {
var root = this;
canvas.style.position = "absolute";
canvas.style.top = root.offsetTop + "px";
canvas.style.left = root.offsetLeft + "px";
// It'd be nice to use DOM Mutation Events here instead.
// However, they appear to arrive irregularly, causing choppy animation.
// d3.timer(redraw);
redraw();
// Clear the canvas and then iterate over child elements.
function redraw() {
canvas.width = root.getAttribute("width");
canvas.height = root.getAttribute("height");
sketch.selectAll('circle')
.each(function(){
var d = d3.select(this);
context.strokeStyle = d.attr("strokeStyle");
context.beginPath();
context.arc(d.attr("x"), d.attr("y"), d.attr("radius"), 0, 2 * Math.PI);
context.stroke();
});
}
});
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment