|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.min.js" integrity="sha256-+9Mf3cAVmxxudDsr1XwXUeRZFtvdWVYdq5/vcgiYyNU=" crossorigin="anonymous"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js" integrity="sha256-HJ7j+71YYw6Kcs8THwQV9lXmPOcR0eXlg7n8KRTZsyA=" crossorigin="anonymous"></script> |
|
<style> |
|
canvas { |
|
display: block; |
|
margin: 0.5em auto; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
|
|
|
|
|
|
<canvas></canvas> |
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
var w = 800, h = 500, |
|
canvas = document.querySelector("canvas"), |
|
ctx = canvas.getContext("2d"); |
|
|
|
d3.select(canvas).attr("width", w).attr("height", h); |
|
|
|
function genCircles (n) { |
|
if (!n) { n = 100; } |
|
return d3.range(n) |
|
.map(function (d, i) { |
|
return { |
|
x: Math.random() * w, |
|
y: Math.random() * h, |
|
r: Math.random() * 10 + 3 |
|
}; |
|
}); |
|
} |
|
|
|
var customNode = document.createElement("custom:cc"), |
|
dataContainer = d3.select(customNode), |
|
p = { |
|
num: 200, |
|
data: genCircles(this.num) |
|
}; |
|
|
|
var gui = new dat.GUI(); |
|
gui.add(p, "num", 100, 10000) |
|
.step(100) |
|
.onChange(function (n) { |
|
p.data = genCircles(n); |
|
drawCustom(); |
|
}); |
|
|
|
function drawCustom () { |
|
var u = dataContainer.selectAll("c").data(p.data); |
|
u.enter() |
|
.append("c") |
|
.attr("r", d => d.r) |
|
.attr("x", Math.random() * w) |
|
.attr("y", Math.random() * h) |
|
.merge(u) |
|
.transition() |
|
.duration(2000) |
|
.attr("x", d => d.x) |
|
.attr("y", d => d.y) |
|
.attr("r", d => d.r); |
|
|
|
u.exit().transition() |
|
.duration(2000) |
|
.attr("r", 0) |
|
.remove(); |
|
} |
|
|
|
function drawCanvas () { |
|
ctx.save(); |
|
ctx.clearRect(0, 0, w, h); |
|
ctx.lineWidth = 1; |
|
ctx.strokeStyle = "#335"; |
|
ctx.beginPath(); |
|
dataContainer.selectAll("c").each(function (d) { |
|
var x = +this.getAttribute("x"), |
|
y = +this.getAttribute("y"), |
|
r = +this.getAttribute("r"); |
|
ctx.moveTo(x + r, y); |
|
ctx.arc(x, y, r, 0, Math.PI * 2, false); |
|
}); |
|
ctx.stroke(); |
|
ctx.restore(); |
|
//window.requestAnimationFrame(drawCanvas); |
|
} |
|
|
|
drawCustom(); |
|
//d3.timer(drawCanvas); |
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver |
|
var config = { attributes: true, childList: true, subtree: true }; |
|
var callback = function (mutationsList, observer) { |
|
drawCanvas(); |
|
}; |
|
var observer = new MutationObserver(callback); |
|
observer.observe(customNode, config); |
|
|
|
</script> |
|
</body> |