Slightly bugged game of life.
authorEugen Sawin <sawine@me73.com>
Thu, 05 Jan 2012 03:22:15 +0100
changeset 781e4ba37124e3
parent 77 9c443a61358c
child 79 72b5c635d6df
Slightly bugged game of life.
books.html
dark.css
experiments.html
factory/v2012/dark.css
factory/v2012/frame.html
factory/v2012/script.js
howiwork.html
index.html
links.html
linksend.html
personalwork.html
resume.html
script.js
     1.1 --- a/books.html	Tue Dec 20 03:01:50 2011 +0100
     1.2 +++ b/books.html	Thu Jan 05 03:22:15 2012 +0100
     1.3 @@ -28,7 +28,9 @@
     1.4        <div id="header">
     1.5          <canvas id="logo">
     1.6            FIND A BETTER BROWSER
     1.7 -        </canvas>        
     1.8 +        </canvas>
     1.9 +        <canvas id="sim">
    1.10 +        </canvas>
    1.11        </div>
    1.12        <div id="content-wrap">
    1.13          <div id="main">
     2.1 --- a/dark.css	Tue Dec 20 03:01:50 2011 +0100
     2.2 +++ b/dark.css	Thu Jan 05 03:22:15 2012 +0100
     2.3 @@ -109,11 +109,25 @@
     2.4      padding: 0;
     2.5      color: #F8F8F8;    
     2.6      /* change the values of top and left to adjust the position of the logo*/
     2.7 -    top: 40px; left: 25px;
     2.8 +    top: 40px; 
     2.9 +    left: 25px;
    2.10      height: 100px;
    2.11      width: 670px;
    2.12  }
    2.13  
    2.14 +#sim {
    2.15 +    border-style: none; 
    2.16 +    position: relative;
    2.17 +    margin: 0; 
    2.18 +    padding: 0;
    2.19 +    color: #F8F8F8;    
    2.20 +    /* change the values of top and left to adjust the position of the logo*/
    2.21 +    top: 37px;
    2.22 +    left: 25px;
    2.23 +    height: 30px;
    2.24 +    width: 670px;
    2.25 +}
    2.26 +
    2.27  code {
    2.28      margin: 5px 0;
    2.29      padding: 15px;
     3.1 --- a/experiments.html	Tue Dec 20 03:01:50 2011 +0100
     3.2 +++ b/experiments.html	Thu Jan 05 03:22:15 2012 +0100
     3.3 @@ -28,7 +28,9 @@
     3.4        <div id="header">
     3.5          <canvas id="logo">
     3.6            FIND A BETTER BROWSER
     3.7 -        </canvas>        
     3.8 +        </canvas>
     3.9 +        <canvas id="sim">
    3.10 +        </canvas>
    3.11        </div>
    3.12        <div id="content-wrap">
    3.13          <div id="main">
     4.1 --- a/factory/v2012/dark.css	Tue Dec 20 03:01:50 2011 +0100
     4.2 +++ b/factory/v2012/dark.css	Thu Jan 05 03:22:15 2012 +0100
     4.3 @@ -109,11 +109,25 @@
     4.4      padding: 0;
     4.5      color: #F8F8F8;    
     4.6      /* change the values of top and left to adjust the position of the logo*/
     4.7 -    top: 40px; left: 25px;
     4.8 +    top: 40px; 
     4.9 +    left: 25px;
    4.10      height: 100px;
    4.11      width: 670px;
    4.12  }
    4.13  
    4.14 +#sim {
    4.15 +    border-style: none; 
    4.16 +    position: relative;
    4.17 +    margin: 0; 
    4.18 +    padding: 0;
    4.19 +    color: #F8F8F8;    
    4.20 +    /* change the values of top and left to adjust the position of the logo*/
    4.21 +    top: 37px;
    4.22 +    left: 25px;
    4.23 +    height: 30px;
    4.24 +    width: 670px;
    4.25 +}
    4.26 +
    4.27  code {
    4.28      margin: 5px 0;
    4.29      padding: 15px;
     5.1 --- a/factory/v2012/frame.html	Tue Dec 20 03:01:50 2011 +0100
     5.2 +++ b/factory/v2012/frame.html	Thu Jan 05 03:22:15 2012 +0100
     5.3 @@ -28,7 +28,9 @@
     5.4        <div id="header">
     5.5          <canvas id="logo">
     5.6            FIND A BETTER BROWSER
     5.7 -        </canvas>        
     5.8 +        </canvas>
     5.9 +        <canvas id="sim">
    5.10 +        </canvas>
    5.11        </div>
    5.12        <div id="content-wrap">
    5.13          <div id="main">
     6.1 --- a/factory/v2012/script.js	Tue Dec 20 03:01:50 2011 +0100
     6.2 +++ b/factory/v2012/script.js	Thu Jan 05 03:22:15 2012 +0100
     6.3 @@ -1,8 +1,9 @@
     6.4  var QUOTES_NUMBER = 39;
     6.5 -var port = 8080;
     6.6 -var SERVER = "http://" + window.location.hostname + ":" + port;
     6.7 +var SERVER = "http://" + window.location.hostname + ":" + window.location.port;
     6.8 +var simulation;
     6.9  
    6.10 -$(document).ready(function() {     
    6.11 +$(document).ready(function() {   
    6.12 +    simulation = new Simulation(document.getElementById("sim"));  
    6.13      var image = new Image();
    6.14      image.onload = init_logo;
    6.15      image.src = "images/logobase.png";
    6.16 @@ -12,10 +13,29 @@
    6.17      }, function() {
    6.18          $(this).css("cursor", "auto");
    6.19      });
    6.20 +    $("#sim").mousemove(function(event) { simulation.mouse_moved(mouse_pos(event, "#sim"));});
    6.21 +    var onEachFrame;
    6.22 +    if (window.webkitRequestAnimationFrame) {
    6.23 +        onEachFrame = function(cb) {
    6.24 +            var _cb = function() { cb(); webkitRequestAnimationFrame(_cb); }
    6.25 +            _cb();
    6.26 +        };
    6.27 +    } else if (window.mozRequestAnimationFrame) {
    6.28 +        onEachFrame = function(cb) {
    6.29 +            var _cb = function() { cb(); mozRequestAnimationFrame(_cb); }
    6.30 +            _cb();
    6.31 +        };
    6.32 +    } else {
    6.33 +        onEachFrame = function(cb) {
    6.34 +            setInterval(cb, 1000 / 30);
    6.35 +        }
    6.36 +    }    
    6.37 +    window.onEachFrame = onEachFrame;   
    6.38 +    window.onEachFrame(update);    
    6.39  });
    6.40  
    6.41 -$(document).keypress( function(event) {
    6.42 -    if (event.which == 13) {            
    6.43 +$(document).keypress(function(event) {
    6.44 +    if (event.which == 13) {      
    6.45  	event.preventDefault();
    6.46          update_logo();	    
    6.47      }
    6.48 @@ -56,14 +76,14 @@
    6.49  click_events["logo"][3]["func"] = switch_page;
    6.50  click_events["logo"][3]["args"] = new Array("links.html", "linksend.html");
    6.51  
    6.52 -function mouse_pos(event) { 
    6.53 -    var offset = $("#logo").offset();   
    6.54 +function mouse_pos(event, id) { 
    6.55 +    var offset = $(id).offset();   
    6.56      return new Array(event.pageX - offset.left, 
    6.57                       event.pageY - offset.top);
    6.58  }
    6.59  
    6.60  function handle_click(event) {
    6.61 -    var xy = mouse_pos(event);
    6.62 +    var xy = mouse_pos(event, "#logo");
    6.63      var x = xy[0];
    6.64      var y = xy[1];
    6.65      for (var i in click_events[event.target.id]) {
    6.66 @@ -101,12 +121,7 @@
    6.67      canvas.width = menu_width;
    6.68      canvas.height = menu_height;
    6.69      context.drawImage(event.target, 0, 0);
    6.70 -    var image = context.getImageData(0, 0, menu_width, menu_height);
    6.71 -    var white = new Colour(255, 255, 255);
    6.72 -    var black = new Colour(0, 0, 0);
    6.73 -    var orange = new Colour(201, 87, 35);
    6.74 -    var green = new Colour(90, 215, 21);
    6.75 -    var found = false;
    6.76 +    var image = context.getImageData(0, 0, menu_width, menu_height);    
    6.77      for (var i in click_events["logo"]) {
    6.78          var p = click_events["logo"][i]; 
    6.79          var min_x = p["min_x"];
    6.80 @@ -117,18 +132,17 @@
    6.81          var page = document.location.href.substr(pos);        
    6.82          for (var j in p["args"]) {
    6.83              if (page == p["args"][j]) {         
    6.84 -                colour_area(image, min_x, max_x, 0, 60, orange);
    6.85 -                colour_area(image, min_x, max_x, 60, max_y, white);                        
    6.86 -                found = p;
    6.87 +                colour_area(image, min_x, max_x, 0, 60, black);
    6.88 +                colour_area(image, min_x, max_x, 60, max_y, white);
    6.89                  break;
    6.90              }
    6.91 -        }
    6.92 -        if (!found) {
    6.93 -            colour_area(image, min_x, max_x, 0, 60, white);
    6.94 -            colour_area(image, min_x, max_x, 60, max_y,  orange);          
    6.95 -        }
    6.96 +            else {
    6.97 +                colour_area(image, min_x, max_x, 0, 60, white);
    6.98 +                colour_area(image, min_x, max_x, 60, max_y,  orange);  
    6.99 +            }
   6.100 +        }       
   6.101      } 
   6.102 -    context.putImageData(image, 0, 0);        
   6.103 +    context.putImageData(image, 0, 0);      
   6.104      // context.fillStyle = green.str();
   6.105      // console.log((found["max_x"] - found["min_x"]) / 2 + found["min_x"] - 2);
   6.106      // context.fillRect((found["max_x"]-found["min_x"])/2+found["min_x"]-1, 95, 2, 5);  
   6.107 @@ -246,6 +260,12 @@
   6.108      return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
   6.109  }
   6.110  
   6.111 +var white = new Colour(255, 255, 255);
   6.112 +var black = new Colour(0, 0, 0);
   6.113 +var orange = new Colour(201, 87, 35);
   6.114 +var green = new Colour(90, 215, 21);
   6.115 +var background = new Colour(34, 34, 34);
   6.116 +
   6.117  function setPixel(image, x, y, colour) {
   6.118      var index = 4 * (x + y * image.width);
   6.119      image.data[index] = colour.r;
   6.120 @@ -458,14 +478,167 @@
   6.121      obj.pageLeft = left; 
   6.122  }
   6.123   
   6.124 -function draw2(evt)
   6.125 -{
   6.126 -	var iter = 0;
   6.127 -	var res = 0;
   6.128 -	var x = (getEventOffsetX(evt) - 335) / 167.5;
   6.129 +function draw2(evt) {
   6.130 +    var iter = 0;
   6.131 +    var res = 0;
   6.132 +    var x = (getEventOffsetX(evt) - 335) / 167.5;
   6.133      var y = (getEventOffsetY(evt) - 140) / 70;
   6.134 -	var z = 0;
   6.135 -	draw(iter, x, y, z, res);
   6.136 +    var z = 0;
   6.137 +    draw(iter, x, y, z, res);
   6.138  }
   6.139  
   6.140 +function update() {
   6.141 +    simulation.update();
   6.142 +    simulation.draw();
   6.143 +}
   6.144  
   6.145 +function Grid(width, height, cell_size) {
   6.146 +    this.width = parseInt(width / cell_size);
   6.147 +    this.height = parseInt(height / cell_size);
   6.148 +    this.canvas_width = width;
   6.149 +    this.canvas_height = height;
   6.150 +    this.cell_size = cell_size;  
   6.151 +    this.cells = new Array();
   6.152 +    for (var y = 0; y < this.height; ++y) { 
   6.153 +        this.cells[y] = new Array();
   6.154 +        for (var x = 0; x < this.width; ++x) {
   6.155 +            this.cells[y][x] = new Cell(x, y, 0, this);
   6.156 +        }
   6.157 +    }
   6.158 +}
   6.159 +Grid.prototype.cell = function(x, y) {   
   6.160 +    return this.cells[y][x];
   6.161 +}
   6.162 +Grid.prototype.pick_cell = function(x, y) {
   6.163 +    var lx = parseInt(x / this.cell_size);
   6.164 +    var ly = parseInt(y / this.cell_size);
   6.165 +    return this.cells[ly][lx];
   6.166 +}
   6.167 +
   6.168 +function Cell(x, y, value, grid) {
   6.169 +    this.x = x;
   6.170 +    this.y = y;  
   6.171 +    this.canvas_x = x * grid.cell_size;
   6.172 +    this.canvas_y = y * grid.cell_size;
   6.173 +    this.value = value;
   6.174 +    this.grid = grid;
   6.175 +    this._neighbours = new Array();
   6.176 +    this.last_mod = 0;
   6.177 +}
   6.178 +Cell.prototype.hash = function() {
   6.179 +    return this.x + ", " + this.y;
   6.180 +}
   6.181 +Cell.prototype.set_value = function(value) {
   6.182 +    this.value = value;
   6.183 +    this.last_mod = $.now();
   6.184 +}
   6.185 +Cell.prototype.neighbours = function() {
   6.186 +    if (this._neighbours.length) {
   6.187 +        return this._neighbours;
   6.188 +    }
   6.189 +    if (this.x > 0) {
   6.190 +        this._neighbours.push(this.grid.cell(this.x-1, this.y));
   6.191 +        if (this.y > 0) {
   6.192 +            this._neighbours.push(this.grid.cell(this.x-1, this.y-1));
   6.193 +            this._neighbours.push(this.grid.cell(this.x, this.y-1));
   6.194 +        }
   6.195 +        if (this.y + 1 < this.grid.height) {
   6.196 +            this._neighbours.push(this.grid.cell(this.x-1, this.y+1));
   6.197 +        }
   6.198 +    }
   6.199 +    if (this.x + 1 < this.grid.width) {
   6.200 +        this._neighbours.push(this.grid.cell(this.x+1, this.y));
   6.201 +        if (this.y + 1 < this.grid.height) {
   6.202 +            this._neighbours.push(this.grid.cell(this.x+1, this.y+1));
   6.203 +            this._neighbours.push(this.grid.cell(this.x, this.y+1));
   6.204 +        }
   6.205 +        if (this.y > 0) {
   6.206 +            this._neighbours.push(this.grid.cell(this.x+1, this.y-1));
   6.207 +        }
   6.208 +    }
   6.209 +    return this._neighbours;
   6.210 +}
   6.211 +Cell.prototype.density = function() {
   6.212 +    var d = 0;
   6.213 +    var neighbours = this.neighbours();
   6.214 +    for (var n in neighbours) {
   6.215 +        d += neighbours[n].value;
   6.216 +    }
   6.217 +    return d;
   6.218 +}
   6.219 +
   6.220 +function Simulation(canvas) {
   6.221 +    this.last_update = 0;
   6.222 +    this.last_draw = 0;
   6.223 +    this.last_mouse_moved = 0;
   6.224 +    this.redraw = new Array();   
   6.225 +    this.canvas = canvas;
   6.226 +    this.canvas.width = 670;
   6.227 +    this.canvas.height = 30;
   6.228 +    this.context = canvas.getContext("2d");    
   6.229 +    this.pos_queue = new Array();
   6.230 +    this.cell_queue = new Array();  
   6.231 +    var cell_size = 3;
   6.232 +    this.grid = new Grid(this.canvas.width, this.canvas.height, cell_size);
   6.233 +}
   6.234 +Simulation.prototype.draw = function() {
   6.235 +    var now = $.now();
   6.236 +    while (this.redraw.length) {
   6.237 +        var cell = this.redraw.pop();
   6.238 +        this.context.fillStyle = cell.value == 1 ? green.str() : background.str();
   6.239 +        this.context.fillRect(cell.canvas_x, cell.canvas_y, 
   6.240 +                              this.grid.cell_size, this.grid.cell_size);
   6.241 +        this.last_draw = $.now();
   6.242 +    }
   6.243 +}
   6.244 +Simulation.prototype.update = function() {
   6.245 +    var now = $.now();
   6.246 +    if (this.pos_queue.length) {
   6.247 +        var pos = this.pos_queue.pop();
   6.248 +        if (pos[0] < this.canvas.width
   6.249 +            && pos[1] < this.canvas.height) {
   6.250 +            var cell = this.grid.pick_cell(pos[0], pos[1]);
   6.251 +            cell.set_value(1);
   6.252 +            this.cell_queue.push(cell);
   6.253 +            this.cell_queue.concat(cell.neighbours()); 
   6.254 +            this.redraw.push(cell);          
   6.255 +        }
   6.256 +    }
   6.257 +    if (this.last_update + 300 > now) {
   6.258 +        return;
   6.259 +    }
   6.260 +    var changed = new Array();
   6.261 +    if (this.cell_queue.length) {
   6.262 +        var cell = this.cell_queue.pop();
   6.263 +        if (changed[cell.hash()]) {
   6.264 +            console.log(cell)
   6.265 +            console.log(changed[cell.hash()]);
   6.266 +            return;
   6.267 +        }
   6.268 +        var d = cell.density();
   6.269 +        if (d == 3 && cell.value == 0) {           
   6.270 +            changed[cell.hash()] = cell;
   6.271 +            this.cell_queue.concat(cell.neighbours());               
   6.272 +        } else if (cell.value == 1) {
   6.273 +            if (d < 2 || d > 3) {              
   6.274 +                changed[cell.hash()] = cell;                
   6.275 +                this.cell_queue.concat(cell.neighbours());                    
   6.276 +            }
   6.277 +        }       
   6.278 +    }
   6.279 +    for (var pos in changed) {
   6.280 +        var cell = changed[pos];      
   6.281 +        cell.set_value(1 - cell.value);
   6.282 +        this.redraw.push(cell);
   6.283 +    }
   6.284 +    this.last_update = now;  
   6.285 +}
   6.286 +Simulation.prototype.mouse_moved = function(pos) {
   6.287 +    var now = $.now();    
   6.288 +    if (this.last_mouse_moved + 50 < now) {
   6.289 +        this.pos_queue.push(pos);
   6.290 +        this.last_mouse_moved = now;       
   6.291 +    }
   6.292 +}
   6.293 +
   6.294 +
     7.1 --- a/howiwork.html	Tue Dec 20 03:01:50 2011 +0100
     7.2 +++ b/howiwork.html	Thu Jan 05 03:22:15 2012 +0100
     7.3 @@ -28,7 +28,9 @@
     7.4        <div id="header">
     7.5          <canvas id="logo">
     7.6            FIND A BETTER BROWSER
     7.7 -        </canvas>        
     7.8 +        </canvas>
     7.9 +        <canvas id="sim">
    7.10 +        </canvas>
    7.11        </div>
    7.12        <div id="content-wrap">
    7.13          <div id="main">
     8.1 --- a/index.html	Tue Dec 20 03:01:50 2011 +0100
     8.2 +++ b/index.html	Thu Jan 05 03:22:15 2012 +0100
     8.3 @@ -28,7 +28,9 @@
     8.4        <div id="header">
     8.5          <canvas id="logo">
     8.6            FIND A BETTER BROWSER
     8.7 -        </canvas>        
     8.8 +        </canvas>
     8.9 +        <canvas id="sim">
    8.10 +        </canvas>
    8.11        </div>
    8.12        <div id="content-wrap">
    8.13          <div id="main">
     9.1 --- a/links.html	Tue Dec 20 03:01:50 2011 +0100
     9.2 +++ b/links.html	Thu Jan 05 03:22:15 2012 +0100
     9.3 @@ -28,7 +28,9 @@
     9.4        <div id="header">
     9.5          <canvas id="logo">
     9.6            FIND A BETTER BROWSER
     9.7 -        </canvas>        
     9.8 +        </canvas>
     9.9 +        <canvas id="sim">
    9.10 +        </canvas>
    9.11        </div>
    9.12        <div id="content-wrap">
    9.13          <div id="main">
    10.1 --- a/linksend.html	Tue Dec 20 03:01:50 2011 +0100
    10.2 +++ b/linksend.html	Thu Jan 05 03:22:15 2012 +0100
    10.3 @@ -28,7 +28,9 @@
    10.4        <div id="header">
    10.5          <canvas id="logo">
    10.6            FIND A BETTER BROWSER
    10.7 -        </canvas>        
    10.8 +        </canvas>
    10.9 +        <canvas id="sim">
   10.10 +        </canvas>
   10.11        </div>
   10.12        <div id="content-wrap">
   10.13          <div id="main">
    11.1 --- a/personalwork.html	Tue Dec 20 03:01:50 2011 +0100
    11.2 +++ b/personalwork.html	Thu Jan 05 03:22:15 2012 +0100
    11.3 @@ -28,7 +28,9 @@
    11.4        <div id="header">
    11.5          <canvas id="logo">
    11.6            FIND A BETTER BROWSER
    11.7 -        </canvas>        
    11.8 +        </canvas>
    11.9 +        <canvas id="sim">
   11.10 +        </canvas>
   11.11        </div>
   11.12        <div id="content-wrap">
   11.13          <div id="main">
    12.1 --- a/resume.html	Tue Dec 20 03:01:50 2011 +0100
    12.2 +++ b/resume.html	Thu Jan 05 03:22:15 2012 +0100
    12.3 @@ -28,7 +28,9 @@
    12.4        <div id="header">
    12.5          <canvas id="logo">
    12.6            FIND A BETTER BROWSER
    12.7 -        </canvas>        
    12.8 +        </canvas>
    12.9 +        <canvas id="sim">
   12.10 +        </canvas>
   12.11        </div>
   12.12        <div id="content-wrap">
   12.13          <div id="main">
    13.1 --- a/script.js	Tue Dec 20 03:01:50 2011 +0100
    13.2 +++ b/script.js	Thu Jan 05 03:22:15 2012 +0100
    13.3 @@ -1,8 +1,9 @@
    13.4  var QUOTES_NUMBER = 39;
    13.5 -var port = 8080;
    13.6 -var SERVER = "http://" + window.location.hostname + ":" + port;
    13.7 +var SERVER = "http://" + window.location.hostname + ":" + window.location.port;
    13.8 +var simulation;
    13.9  
   13.10 -$(document).ready(function() {     
   13.11 +$(document).ready(function() {   
   13.12 +    simulation = new Simulation(document.getElementById("sim"));  
   13.13      var image = new Image();
   13.14      image.onload = init_logo;
   13.15      image.src = "images/logobase.png";
   13.16 @@ -12,10 +13,29 @@
   13.17      }, function() {
   13.18          $(this).css("cursor", "auto");
   13.19      });
   13.20 +    $("#sim").mousemove(function(event) { simulation.mouse_moved(mouse_pos(event, "#sim"));});
   13.21 +    var onEachFrame;
   13.22 +    if (window.webkitRequestAnimationFrame) {
   13.23 +        onEachFrame = function(cb) {
   13.24 +            var _cb = function() { cb(); webkitRequestAnimationFrame(_cb); }
   13.25 +            _cb();
   13.26 +        };
   13.27 +    } else if (window.mozRequestAnimationFrame) {
   13.28 +        onEachFrame = function(cb) {
   13.29 +            var _cb = function() { cb(); mozRequestAnimationFrame(_cb); }
   13.30 +            _cb();
   13.31 +        };
   13.32 +    } else {
   13.33 +        onEachFrame = function(cb) {
   13.34 +            setInterval(cb, 1000 / 30);
   13.35 +        }
   13.36 +    }    
   13.37 +    window.onEachFrame = onEachFrame;   
   13.38 +    window.onEachFrame(update);    
   13.39  });
   13.40  
   13.41 -$(document).keypress( function(event) {
   13.42 -    if (event.which == 13) {            
   13.43 +$(document).keypress(function(event) {
   13.44 +    if (event.which == 13) {      
   13.45  	event.preventDefault();
   13.46          update_logo();	    
   13.47      }
   13.48 @@ -56,14 +76,14 @@
   13.49  click_events["logo"][3]["func"] = switch_page;
   13.50  click_events["logo"][3]["args"] = new Array("links.html", "linksend.html");
   13.51  
   13.52 -function mouse_pos(event) { 
   13.53 -    var offset = $("#logo").offset();   
   13.54 +function mouse_pos(event, id) { 
   13.55 +    var offset = $(id).offset();   
   13.56      return new Array(event.pageX - offset.left, 
   13.57                       event.pageY - offset.top);
   13.58  }
   13.59  
   13.60  function handle_click(event) {
   13.61 -    var xy = mouse_pos(event);
   13.62 +    var xy = mouse_pos(event, "#logo");
   13.63      var x = xy[0];
   13.64      var y = xy[1];
   13.65      for (var i in click_events[event.target.id]) {
   13.66 @@ -101,12 +121,7 @@
   13.67      canvas.width = menu_width;
   13.68      canvas.height = menu_height;
   13.69      context.drawImage(event.target, 0, 0);
   13.70 -    var image = context.getImageData(0, 0, menu_width, menu_height);
   13.71 -    var white = new Colour(255, 255, 255);
   13.72 -    var black = new Colour(0, 0, 0);
   13.73 -    var orange = new Colour(201, 87, 35);
   13.74 -    var green = new Colour(90, 215, 21);
   13.75 -    var found = false;
   13.76 +    var image = context.getImageData(0, 0, menu_width, menu_height);    
   13.77      for (var i in click_events["logo"]) {
   13.78          var p = click_events["logo"][i]; 
   13.79          var min_x = p["min_x"];
   13.80 @@ -117,18 +132,17 @@
   13.81          var page = document.location.href.substr(pos);        
   13.82          for (var j in p["args"]) {
   13.83              if (page == p["args"][j]) {         
   13.84 -                colour_area(image, min_x, max_x, 0, 60, orange);
   13.85 -                colour_area(image, min_x, max_x, 60, max_y, white);                        
   13.86 -                found = p;
   13.87 +                colour_area(image, min_x, max_x, 0, 60, black);
   13.88 +                colour_area(image, min_x, max_x, 60, max_y, white);
   13.89                  break;
   13.90              }
   13.91 -        }
   13.92 -        if (!found) {
   13.93 -            colour_area(image, min_x, max_x, 0, 60, white);
   13.94 -            colour_area(image, min_x, max_x, 60, max_y,  orange);          
   13.95 -        }
   13.96 +            else {
   13.97 +                colour_area(image, min_x, max_x, 0, 60, white);
   13.98 +                colour_area(image, min_x, max_x, 60, max_y,  orange);  
   13.99 +            }
  13.100 +        }       
  13.101      } 
  13.102 -    context.putImageData(image, 0, 0);        
  13.103 +    context.putImageData(image, 0, 0);      
  13.104      // context.fillStyle = green.str();
  13.105      // console.log((found["max_x"] - found["min_x"]) / 2 + found["min_x"] - 2);
  13.106      // context.fillRect((found["max_x"]-found["min_x"])/2+found["min_x"]-1, 95, 2, 5);  
  13.107 @@ -246,6 +260,12 @@
  13.108      return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
  13.109  }
  13.110  
  13.111 +var white = new Colour(255, 255, 255);
  13.112 +var black = new Colour(0, 0, 0);
  13.113 +var orange = new Colour(201, 87, 35);
  13.114 +var green = new Colour(90, 215, 21);
  13.115 +var background = new Colour(34, 34, 34);
  13.116 +
  13.117  function setPixel(image, x, y, colour) {
  13.118      var index = 4 * (x + y * image.width);
  13.119      image.data[index] = colour.r;
  13.120 @@ -458,14 +478,167 @@
  13.121      obj.pageLeft = left; 
  13.122  }
  13.123   
  13.124 -function draw2(evt)
  13.125 -{
  13.126 -	var iter = 0;
  13.127 -	var res = 0;
  13.128 -	var x = (getEventOffsetX(evt) - 335) / 167.5;
  13.129 +function draw2(evt) {
  13.130 +    var iter = 0;
  13.131 +    var res = 0;
  13.132 +    var x = (getEventOffsetX(evt) - 335) / 167.5;
  13.133      var y = (getEventOffsetY(evt) - 140) / 70;
  13.134 -	var z = 0;
  13.135 -	draw(iter, x, y, z, res);
  13.136 +    var z = 0;
  13.137 +    draw(iter, x, y, z, res);
  13.138  }
  13.139  
  13.140 +function update() {
  13.141 +    simulation.update();
  13.142 +    simulation.draw();
  13.143 +}
  13.144  
  13.145 +function Grid(width, height, cell_size) {
  13.146 +    this.width = parseInt(width / cell_size);
  13.147 +    this.height = parseInt(height / cell_size);
  13.148 +    this.canvas_width = width;
  13.149 +    this.canvas_height = height;
  13.150 +    this.cell_size = cell_size;  
  13.151 +    this.cells = new Array();
  13.152 +    for (var y = 0; y < this.height; ++y) { 
  13.153 +        this.cells[y] = new Array();
  13.154 +        for (var x = 0; x < this.width; ++x) {
  13.155 +            this.cells[y][x] = new Cell(x, y, 0, this);
  13.156 +        }
  13.157 +    }
  13.158 +}
  13.159 +Grid.prototype.cell = function(x, y) {   
  13.160 +    return this.cells[y][x];
  13.161 +}
  13.162 +Grid.prototype.pick_cell = function(x, y) {
  13.163 +    var lx = parseInt(x / this.cell_size);
  13.164 +    var ly = parseInt(y / this.cell_size);
  13.165 +    return this.cells[ly][lx];
  13.166 +}
  13.167 +
  13.168 +function Cell(x, y, value, grid) {
  13.169 +    this.x = x;
  13.170 +    this.y = y;  
  13.171 +    this.canvas_x = x * grid.cell_size;
  13.172 +    this.canvas_y = y * grid.cell_size;
  13.173 +    this.value = value;
  13.174 +    this.grid = grid;
  13.175 +    this._neighbours = new Array();
  13.176 +    this.last_mod = 0;
  13.177 +}
  13.178 +Cell.prototype.hash = function() {
  13.179 +    return this.x + ", " + this.y;
  13.180 +}
  13.181 +Cell.prototype.set_value = function(value) {
  13.182 +    this.value = value;
  13.183 +    this.last_mod = $.now();
  13.184 +}
  13.185 +Cell.prototype.neighbours = function() {
  13.186 +    if (this._neighbours.length) {
  13.187 +        return this._neighbours;
  13.188 +    }
  13.189 +    if (this.x > 0) {
  13.190 +        this._neighbours.push(this.grid.cell(this.x-1, this.y));
  13.191 +        if (this.y > 0) {
  13.192 +            this._neighbours.push(this.grid.cell(this.x-1, this.y-1));
  13.193 +            this._neighbours.push(this.grid.cell(this.x, this.y-1));
  13.194 +        }
  13.195 +        if (this.y + 1 < this.grid.height) {
  13.196 +            this._neighbours.push(this.grid.cell(this.x-1, this.y+1));
  13.197 +        }
  13.198 +    }
  13.199 +    if (this.x + 1 < this.grid.width) {
  13.200 +        this._neighbours.push(this.grid.cell(this.x+1, this.y));
  13.201 +        if (this.y + 1 < this.grid.height) {
  13.202 +            this._neighbours.push(this.grid.cell(this.x+1, this.y+1));
  13.203 +            this._neighbours.push(this.grid.cell(this.x, this.y+1));
  13.204 +        }
  13.205 +        if (this.y > 0) {
  13.206 +            this._neighbours.push(this.grid.cell(this.x+1, this.y-1));
  13.207 +        }
  13.208 +    }
  13.209 +    return this._neighbours;
  13.210 +}
  13.211 +Cell.prototype.density = function() {
  13.212 +    var d = 0;
  13.213 +    var neighbours = this.neighbours();
  13.214 +    for (var n in neighbours) {
  13.215 +        d += neighbours[n].value;
  13.216 +    }
  13.217 +    return d;
  13.218 +}
  13.219 +
  13.220 +function Simulation(canvas) {
  13.221 +    this.last_update = 0;
  13.222 +    this.last_draw = 0;
  13.223 +    this.last_mouse_moved = 0;
  13.224 +    this.redraw = new Array();   
  13.225 +    this.canvas = canvas;
  13.226 +    this.canvas.width = 670;
  13.227 +    this.canvas.height = 30;
  13.228 +    this.context = canvas.getContext("2d");    
  13.229 +    this.pos_queue = new Array();
  13.230 +    this.cell_queue = new Array();  
  13.231 +    var cell_size = 3;
  13.232 +    this.grid = new Grid(this.canvas.width, this.canvas.height, cell_size);
  13.233 +}
  13.234 +Simulation.prototype.draw = function() {
  13.235 +    var now = $.now();
  13.236 +    while (this.redraw.length) {
  13.237 +        var cell = this.redraw.pop();
  13.238 +        this.context.fillStyle = cell.value == 1 ? green.str() : background.str();
  13.239 +        this.context.fillRect(cell.canvas_x, cell.canvas_y, 
  13.240 +                              this.grid.cell_size, this.grid.cell_size);
  13.241 +        this.last_draw = $.now();
  13.242 +    }
  13.243 +}
  13.244 +Simulation.prototype.update = function() {
  13.245 +    var now = $.now();
  13.246 +    if (this.pos_queue.length) {
  13.247 +        var pos = this.pos_queue.pop();
  13.248 +        if (pos[0] < this.canvas.width
  13.249 +            && pos[1] < this.canvas.height) {
  13.250 +            var cell = this.grid.pick_cell(pos[0], pos[1]);
  13.251 +            cell.set_value(1);
  13.252 +            this.cell_queue.push(cell);
  13.253 +            this.cell_queue.concat(cell.neighbours()); 
  13.254 +            this.redraw.push(cell);          
  13.255 +        }
  13.256 +    }
  13.257 +    if (this.last_update + 300 > now) {
  13.258 +        return;
  13.259 +    }
  13.260 +    var changed = new Array();
  13.261 +    if (this.cell_queue.length) {
  13.262 +        var cell = this.cell_queue.pop();
  13.263 +        if (changed[cell.hash()]) {
  13.264 +            console.log(cell)
  13.265 +            console.log(changed[cell.hash()]);
  13.266 +            return;
  13.267 +        }
  13.268 +        var d = cell.density();
  13.269 +        if (d == 3 && cell.value == 0) {           
  13.270 +            changed[cell.hash()] = cell;
  13.271 +            this.cell_queue.concat(cell.neighbours());               
  13.272 +        } else if (cell.value == 1) {
  13.273 +            if (d < 2 || d > 3) {              
  13.274 +                changed[cell.hash()] = cell;                
  13.275 +                this.cell_queue.concat(cell.neighbours());                    
  13.276 +            }
  13.277 +        }       
  13.278 +    }
  13.279 +    for (var pos in changed) {
  13.280 +        var cell = changed[pos];      
  13.281 +        cell.set_value(1 - cell.value);
  13.282 +        this.redraw.push(cell);
  13.283 +    }
  13.284 +    this.last_update = now;  
  13.285 +}
  13.286 +Simulation.prototype.mouse_moved = function(pos) {
  13.287 +    var now = $.now();    
  13.288 +    if (this.last_mouse_moved + 50 < now) {
  13.289 +        this.pos_queue.push(pos);
  13.290 +        this.last_mouse_moved = now;       
  13.291 +    }
  13.292 +}
  13.293 +
  13.294 +