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> &mdash; play / pause</li>
            <li><span class="key">n</span> &mdash; make a new tree</li>
            <li><span class="key">m</span> &mdash; toggle mutuation</li>
            <li><span class="key">b</span> &mdash; toggle bloom</li>
            <li><span class="key">a</span> &mdash; 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...