fractal zoomer
by ian_smithz
HTML
<div id="my_container" style="display: none;">
<canvas id="my_canvas"></canvas>
<div id="control">
<div>
<a id="tog_play" class="play" href="#" onclick="return toggle('play');">play</a>
</div>
<div>
<a id="tog_flower" class="toggle" href="#" onclick="return toggle('flower');">bloom</a>
<a id="tog_mutate" class="toggle" href="#" onclick="return toggle('mutate');">mutate</a>
</div>
<div>
<a id="reset" href="#" onclick="return reset();">new</a>
</div>
<div class="left">
</div>
</div>
</div>
<div id="about" style="display: none;">
<ul>
<li><span class="key">space / p</span> — play / pause</li>
<li><span class="key">n</span> — make a new tree</li>
<li><span class="key">m</span> — toggle mutuation</li>
<li><span class="key">b</span> — toggle bloom</li>
<li><span class="key">a</span> — show / hide this about box</li>
</ul>
</div>
CSS
body {
margin: 0;
padding: 0;
background-color: #000;
color: #000;
font: 14px Helvetica, Arial, sans-serif;
}
h1 {
font-size: 30px;
font-weight: bold;
margin: 0;
letter-spacing: -3px;
}
p {
margin: 12px 0 0 0;
}
a {
text-decoration: none;
outline: none;
}
a:hover {
color: #fff;
}
canvas {
cursor: crosshair;
}
img {
border: none;
}
#my_container {
position: absolute;
left: 0px;
top: 0px;
}
#control, #my_canvas {
-webkit-user-select: none;
-moz-user-select: none;
}
#control {
margin-top: 4px;
}
#control div {
float: right;
margin-left: 4px;
}
#control div.left {
float: left;
margin-left: 0px;
}
#control a {
color: #bebebe;
display: block;
float: left;
padding: 6px 7px 6px 7px;
font-size: 20px;
background-color: #0d0d0d;
}
#control a:hover {
background-color: #323232;
}
#control a.selected {
background-color: #235fa1;
color: #000;
}
#control a:first-letter {
color: #fff;
}
#control a.selected:first-letter {
color: #000;
}
#control a.toggle {
padding-left: 31px;
background: #0d0d0d url(img/check.png) no-repeat;
}
#control a.toggle:hover {
background-color: #323232;
}
#control a.toggle.selected {
background: #39a02f url(img/check.png) no-repeat 0 -35px;
}
#control a.play {
padding-left: 31px;
background: #0d0d0d url(img/playpause.png) no-repeat;
}
#control a.play:hover {
background-color: #323232;
}
#control a.play.selected {
background: #8bf200 url(img/playpause.png) no-repeat 0 -35px;
}
#aboutclear {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
cursor: pointer;
}
JavaScript
// Just A Grip of Code Compiled From Various Files
// Check http://code.google.com/p/chrome-canopy/source/browse/#svn/trunk/www/js for something more human readable ;)
function lerp(a,b,u)
{return a+(b-a)*u;}
function map(v,in_min,in_max,out_min,out_max)
{return out_min+(out_max-out_min)*((v-in_min)/(in_max-in_min));}
function randInt(max)
{return Math.floor(Math.random()*max);}
function randInt2(min,max)
{return Math.floor(min+Math.random()*(max-min));}
function rand(max)
{return Math.random()*max;}
function rand2(min,max)
{return min+Math.random()*(max-min);}
function clamp(v,min,max)
{return v<min?min:(v>max?max:v);}
function wrap(v,min,max)
{if(v<min)return max-(min-v)%(max-min);else if(v>=max)return(v-min)%(max-min)+min;else return v;}
function distSq(x1,y1,x2,y2)
{var xo=x2-x1;var yo=y2-y1;return xo*xo+yo*yo;}
function dist(x1,y1,x2,y2)
{return Math.sqrt(distSq(x1,y1,x2,y2));}
function rotx(x,angle)
{return x*Math.cos(angle);}
function roty(y,angle)
{return y*Math.sin(angle);}
function bezierPoint(a,b,c,d,t)
{var t1=1.0-t;return a*t1*t1*t1+3*b*t*t1*t1+3*c*t*t*t1+d*t*t*t;}
function segIntersection(p1,p2,p3,p4)
{var bx=p2.x-p1.x;var by=p2.y-p1.y;var dx=p4.x-p3.x;var dy=p4.y-p3.y;var b_dot_d_perp=bx*dy-by*dx;if(b_dot_d_perp==0)return null;var cx=p3.x-p1.x;var cy=p3.y-p1.y;var t=(cx*dy-cy*dx)/b_dot_d_perp;if(t<0||t>1)return null;var u=(cx*by-cy*bx)/b_dot_d_perp;if(u<0||u>1)return null;return new Vec2(p1.x+t*bx,p1.y+t*by);}
function segCircIntersects(l1,l2,cp,cr)
{var u=((cp.x-l1.x)*(l2.x-l1.x)+(cp.y-l1.y)*(l2.y-l1.y))/((l2.x-l1.x)*(l2.x-l1.x)+(l2.y-l1.y)*(l2.y-l1.y));if(u<0)return Vec2.distSq(l1,cp)<cr*cr;if(u>1)return Vec2.distSq(l2,cp)<cr*cr;var ox=l1.x+(l2.x-l1.x)*u-cp.x;var oy=l1.y+(l2.y-l1.y)*u-cp.y;return ox*ox+oy*oy<=cr*cr;}
function curveSegmentBez(v1,v2,v3,v4,s)
{return[new Vec2(v2.x+(s*v3.x-s*v1.x)/6,v2.y+(s*v3.y-s*v1.y)/6),new Vec2(v3.x+(s*v2.x-s*v4.x)/6,v3.y+(s*v2.y-s*v4.y)/6),new Vec2(v3.x,v3.y)];}
function...