Skip to content

Instantly share code, notes, and snippets.

@proclamo-zz
Last active November 21, 2016 06:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save proclamo-zz/bd38273f0d72dce46b6f to your computer and use it in GitHub Desktop.
Save proclamo-zz/bd38273f0d72dce46b6f to your computer and use it in GitHub Desktop.
d3.js Mandelbrot's fractal experiment

Little experiment with fractals. One day I founded the Mandelbrot's algorithm and I wanted to play with. Now it is written with d3 painting on canvas, pixel to pixel. Maybe I will try others implementations to improve performance.

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.info {
color: red;
padding: 3px;
position: absolute;
top: 10px;
left: 10px;
}
.info:hover {
background-color: rgba(255, 255, 255, .7);
border-radius: 5px;
}
.msg {
text-align: left;
}
</style>
</head>
<body>
<div class="info"></div>
<div class="container"></div>
<div class="msg">
Click for zoom In
</div>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
(function() {
var width = 533,
height = 400,
iterations = 150,
radious = 2,
factor = 2,
step = 1,
x1 = -1.7,
y1 = -1,
x2 = 1,
y2 = 1,
bounds
;
var color = d3.scale.category20c();
var canvas = d3.select(".container")
.append("canvas")
.attr({width: width, height: height})
.on("click", clicked)
.node().getContext("2d");
var center = [width / 2, height / 2];
rescale();
calculateBounds(center);
draw();
function calculateBounds(center) {
var p = [center[0] - (width / factor), center[1] - (height / factor), center[0] + (width / factor), center[1] + (height / factor)];
x1 = x(p[0]);
y1 = y(p[1]);
x2 = x(p[2]);
y2 = y(p[3]);
}
function rescale() {
bounds = [x1, x2, y1, y2];
x = d3.scale.linear()
.domain([0, width])
.range([bounds[0], bounds[1]]);
y = d3.scale.linear()
.domain([0, height])
.range([bounds[2], bounds[3]]);
}
function clicked() {
var center = [d3.event.x, d3.event.y];
/* zoom out (Shift + click) but it has bugs
if (d3.event.shiftKey) {
factor -= .2;
}
else {
factor += .2;
}
*/
factor += .2; // zomIn
factor = Math.round(factor * 10) / 10;
calculateBounds(center);
rescale();
draw();
}
function draw() {
canvas.fillStyle = "rgb(0, 0, 0)";
canvas.fillRect(-1, -1, width, height);
mandelbrot();
showInfo();
}
function mandelbrot() {
var p0, q0, z, esc, _x, _y;
var dp = (x2 - x1)/(width - 1);
var dq = (y2 - y1)/(height - 1);
for (var i = 0; i < width; i += step) {
for (var j = 0; j < height; j += step) {
p0 = x1 + i * dp;
q0 = y1 + j * dq;
z = { re: p0, im: q0 };
c = z;
esc = 0;
for (var k = 1; k < iterations; k++) {
_x = z.re * z.re - z.im * z.im + c.re;
_y = 2 * z.re * z.im + c.im;
z = { re: _x, im: _y };
esc++;
if (Math.sqrt(Math.pow(z.re, 2) + Math.pow(z.im, 2)) > radious) {
canvas.fillStyle = color(esc);
canvas.fillRect(i, j, step, step);
break;
}
}
}
}
}
function showInfo() {
d3.select(".info")
.text("Zoom: " + factor + "x");
}
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment