|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title>fractal</title> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<style> body: { margin: 0px }</style> |
|
</head> |
|
<body> |
|
<svg width="960" height="500"></svg> |
|
<script> |
|
|
|
var svg = d3.select("svg"), |
|
width = svg.attr("width"), |
|
height = svg.attr("height"), |
|
elementCount = svg.append("text") |
|
.attr("x", width / 2) |
|
.attr("y", height - 20) |
|
.attr("text-anchor", "middle") |
|
.attr("fill", "gray"), |
|
format = d3.format(","), |
|
nMax = 100, |
|
mouseX = 800, |
|
mouseY = 200, |
|
scaleFactor = 0.96; |
|
|
|
function redraw (){ |
|
var scale = 14, |
|
angle = -mouseY / height * Math.PI / 8, |
|
n = Math.floor(nMax * mouseX / width), |
|
up = Math.PI; |
|
render(fractal(width/2, height - 136, up, scale, angle, 0, n, false)); |
|
} |
|
|
|
function fractal(x, y, direction, scale, angle, i, n, flip){ |
|
|
|
var circle = [{ |
|
x: x, |
|
y: y, |
|
radius: scale / 2 |
|
}]; |
|
|
|
if(i < n){ |
|
if(i % 11 === 0){ |
|
return circle |
|
.concat(fractal(x, y, direction, scale, angle, i+1, n, flip)) |
|
.concat(fractal(x, y, direction, scale, angle, i+1, n, !flip)); |
|
} else { |
|
return circle.concat( |
|
fractal( |
|
x + Math.sin(direction) * scale, |
|
y + Math.cos(direction) * scale, |
|
direction + angle * (flip ? 1 : -1), |
|
scale * scaleFactor, |
|
angle, |
|
i+1, |
|
n, |
|
flip |
|
) |
|
); |
|
} |
|
} |
|
return circle; |
|
} |
|
|
|
function r(){ |
|
return Math.floor(Math.random()*255); |
|
} |
|
|
|
function render(data){ |
|
var circles = svg.selectAll("circle").data(data); |
|
circles |
|
.enter() |
|
.append("circle") |
|
.merge(circles) |
|
.attr("cx", function (d){ return d.x; }) |
|
.attr("cy", function (d){ return d.y; }) |
|
.attr("r", function (d){ return d.radius; }) |
|
.attr("fill", function (){ |
|
return [ |
|
"rgb(", |
|
r(), ",", |
|
r(), ",", |
|
r(), |
|
")"].join("");}) |
|
circles.exit() |
|
.remove(); |
|
|
|
elementCount.text(format(data.length) + " SVG Circle elements"); |
|
} |
|
|
|
redraw(); |
|
document.addEventListener("mousemove",function(e){ |
|
mouseX = e.x; |
|
mouseY = e.y; |
|
redraw(); |
|
}); |
|
</script> |
|
</body> |
|
</html> |