Skip to content

Instantly share code, notes, and snippets.

@lixiaoyan
Created September 29, 2013 13:51
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 lixiaoyan/6752696 to your computer and use it in GitHub Desktop.
Save lixiaoyan/6752696 to your computer and use it in GitHub Desktop.
<!--
name: Mandelbrot set
coder: gameloftyou
version: v1.0.0
-->
<!DOCTYPE html>
<html>
<head>
<title>Mandelbrot Set</title>
<style type="text/css">
html
{
overflow-x: hidden;
overflow-y: hidden;
}
body
{
margin: 0;
background-color:black;
}
</style>
</head>
<body onload="load()">
<canvas id="cvs" width="800" height="600" onclick="onMouseClick(event)"></canvas>
<script>
var cvs,ctx;
var NUM_COLORS = 300;
var colors = [];
var bx=-2.8,by=-1.25,ex=0.7,ey=1.25;
var MAX_TIMES = 300;
//CODE_BEGIN: transform between rgb and hsl
var PCS = 1E-15;
function RGB()
{
this.r = 0;
this.g = 0;
this.b = 0;
}
function HSL()
{
this.h = 0.0;
this.s = 0.0;
this.l = 0.0;
}
function RGBtoHSL(rgb)
{
var r = rgb.r/255.0;
var g = rgb.g/255.0;
var b = rgb.b/255.0;
var maxcolor, mincolor, l, s, h;
var hsl = new HSL();
if(r>g)
{
if(r>b)
{
maxcolor = r;
if(g>b) mincolor = b;
else mincolor = g;
}
else
{
maxcolor = b;
mincolor = g;
}
}
else
{
if(g>b)
{
maxcolor = g;
if(r>b) mincolor = b;
else mincolor = r;
}
else
{
maxcolor = b;
mincolor = r;
}
}
l = (maxcolor+mincolor)/2;
if((maxcolor-mincolor)<PCS)
{
s = 0;
h = 0;
}
else
{
if(l<0.5) s = (maxcolor-mincolor)/(maxcolor+mincolor);
else s = (maxcolor-mincolor)/(2.0-maxcolor-mincolor);
if(maxcolor==r) h = (g-b)/(maxcolor-mincolor);
else if(maxcolor==g) h = 2.0+(b-r)/(maxcolor-mincolor);
else h = 4.0+(r-g)/(maxcolor-mincolor);
h *= 60.0;
if(h<0) h += 360.0;
}
hsl.h = h;
hsl.s = s;
hsl.l = l;
return hsl;
}
function HSL2RGB(temp1,temp2,temp3)
{
if(temp3<0) temp3+=1.0;
else if(temp3>1) temp3-=1.0;
if(6.0*temp3<1) return temp1+(temp2-temp1)*6.0*temp3;
else if(2.0*temp3<1) return temp2;
else if(3.0*temp3<2) return temp1+(temp2-temp1)*(2.0/3.0-temp3)*6.0;
return temp1;
}
function HSLtoRGB(hsl)
{
var h = hsl.h;
var s = hsl.s;
var l = hsl.l;
var temp1,temp2;
var r,g,b;
var rgb = new RGB();
if(s<PCS)
{
r = g = b = parseInt(l*255);
}
else
{
if(l<0.5) temp2 = l*(1.0+s);
else temp2 = l+s-l*s;
temp1 = 2.0*l-temp2;
h /= 360.0;
r = parseInt(255*HSL2RGB(temp1,temp2,h+1.0/3.0));
g = parseInt(255*HSL2RGB(temp1,temp2,h));
b = parseInt(255*HSL2RGB(temp1,temp2,h-1.0/3.0));
}
rgb.r = r;
rgb.g = g;
rgb.b = b;
return rgb;
}
//CODE_END: transform between rgb and hsl
//CODE_BEGIN: rgb to hex
function toHex(n)
{
var hexs = "0123456789ABCDEF";
return hexs.charAt((n-n%16)/16)+hexs.charAt(n%16);
}
function rgbToHex(r,g,b)
{
return "#"+toHex(r)+toHex(g)+toHex(b);
}
//CODE_END: rgb to hex
//CODE_BEGIN: deal with mouse event
function onMouseClick(e)
{
var x = e.clientX;
var y = e.clientY;
var oleft = bx,otop = by,oright = ex,obottom = ey;
var oincx = (oright-oleft)/800,oincy = (obottom-otop)/600;
bx = oleft+oincx*(x-24);
ex = oleft+oincx*(x+24);
by = otop+oincy*(y-18);
ey = otop+oincy*(y+18);
clear();
draw();
}
//CODE_END: deal with mouse event
//clear the canvas
function clear()
{
ctx.fillStyle = "#000000";
ctx.fillRect(0,0,800,600);
}
//draw mandelbrot set
function draw()
{
var col=0,row=0;
var incx=(ex-bx)/800.0,incy=(ey-by)/600.0;
var times;
var model,oldx,x,y;
var cx=bx,cy=by;
while(row<600)
{
cx = bx;
col = 0;
while(col<800)
{
times = 0;
model = 0.0;
oldx = 0.0;
x = 0.0;
y = 0.0;
while(times<=MAX_TIMES&&model<4.0)
{
oldx = x;
x = x*x-y*y+cx;
y = 2*oldx*y+cy;
model = x*x+y*y;
++times;
}
if(model>4.0)
{
ctx.beginPath();
ctx.lineWidth = 1;
ctx.strokeStyle = colors[times%300];
ctx.moveTo(col-1,row);
ctx.lineTo(col,row);
ctx.stroke();
ctx.closePath();
}
cx += incx;
++col;
}
cy += incy;
++row;
}
}
//onload
function load()
{
cvs = document.getElementById("cvs");
ctx = cvs.getContext("2d");
var rgb,hsl = new HSL();
var half = parseInt(NUM_COLORS/2);
hsl.s = 1.0;
for(var i=0;i<half;++i)
{
hsl.h = 240.0;
hsl.l = i/half;
rgb = HSLtoRGB(hsl);
colors[i] = rgbToHex(rgb.r,rgb.g,rgb.b);
hsl.h = 330.0;
rgb = HSLtoRGB(hsl);
colors[NUM_COLORS-1-i] = rgbToHex(rgb.r,rgb.g,rgb.b);
}
clear();
draw();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment