Extension:EmbedScript/Mandelbrot set



var width = 640, height = 480, zoom = 4, cx = -1, cy = 0, maxIters = 2000, $canvas = $(' '), ctx = $canvas[0].getContext('2d'), runTimeout = null;

function mandelbrot(x, y, maxIters) { var zx = 0, zy = 0, zxtemp, zr2;

for (var i = 0; i < maxIters; i++) { // z[n+1] = z[n]^2 + c

zxtemp = zx * zx - zy * zy + x;       zy = 2 * zx * zy + y;        zx = zxtemp;

zr2 = zx * zx + zy * zy; if (zr2 > 4) { return i;       } }   return -1; }

function runStripe(start, end) { for (var y = start; y <= end; y++) { var iters = []; for (var x = 0; x < width; x++) { iters[x] = mandelbrot(               (x - width / 2) * (zoom / width) + cx,                (height / 2 - y) * (zoom * 0.75 / height) + cy,                maxIters            ); }       var row = ctx.createImageData(width, 1), data = row.data, i = 0; for (var x = 0; x < width; x++) { iter = iters[x]; if (iter < 0) { data[i++] = 0; data[i++] = 0; data[i++] = 0; } else { data[i++] = iter % 128; data[i++] = 64 + iter % 128; data[i++] = 128 + iter % 128; }           data[i++] = 255; }       ctx.putImageData(row, 0, y); } }

function runMandelbrot { // Stop any currently running job if (runTimeout) { clearTimeout(runTimeout); runTimeout = null; }	ctx.clearRect(0, 0, width, height);

var chunkSize = 2, position = 0; function runChunk { runStripe(position, Math.min(position + chunkSize - 1, height - 1)); position += chunkSize; if (position < height) { runTimeout = setTimeout(runChunk, 0); } else { runTimeout = null; }   }    runChunk; }

// Avoid scrollbars $('body').css('overflow', 'hidden');

$canvas .attr('width', width) .attr('height', height) .css('position', 'absolute') .css('top', 0) .css('left', 0) .css('right', 0) .css('bottom', 0) .appendTo('body');

// Zoom buttons $(' ')   .text('+') .css('width', 32) .css('height', 32) .css('position', 'absolute') .css('top', 8) .css('left', 8) .click(function {       zoom /= 2;        runMandelbrot;    }) .appendTo('body');

$(' ')   .text('-') .css('width', 32) .css('height', 32) .css('position', 'absolute') .css('top', 48) .css('left', 8) .click(function {       zoom *= 2;        runMandelbrot;    }) .appendTo('body');

// Event handler for dragging! // Moves the canvas around under the mouse cursor to simulate drag... // After completion of dragging, we'll re-render the entire view. $canvas.mousedown(function(event) {	event.preventDefault;	var origX = event.clientX,		origY = event.clientY,		dx = 0,		dy = 0;	$canvas		.bind('mousemove.dragging', function(event) { dx = event.clientX - origX; dy = event.clientY - origY; $canvas .css('left', dx + 'px') .css('top', dy + 'px'); })		.bind('mouseup.dragging', function(event) { $canvas .unbind('mousemove.dragging') .unbind('mouseup.dragging') .css('left', '0') .css('top', '0'); cx -= (dx * zoom / width); cy += (dy * zoom * 0.75 / height); runMandelbrot; }); });

runMandelbrot;