Fixed failed init of game of life.
1 var QUOTES_NUMBER = 39;
2 var SERVER = "http://" + window.location.hostname + ":" + window.location.port;
6 $(document).ready(function() {
7 simulation = new Simulation(document.getElementById("sim"),
8 670, 50, 6, green, background);
9 var image = new Image();
10 image.onload = init_logo;
11 image.src = "images/logobase.png";
12 $("#logo").click(handle_click);
13 $("#logo").hover(function() {
14 $(this).css("cursor", "pointer");
16 $(this).css("cursor", "auto");
18 $("#sim").mousemove(function(event) { simulation.mouse_moved(mouse_pos(event, "#sim")); });
20 if (window.webkitRequestAnimationFrame) {
21 onEachFrame = function(cb) {
22 var _cb = function() { cb(); webkitRequestAnimationFrame(_cb); }
25 } else if (window.mozRequestAnimationFrame) {
26 onEachFrame = function(cb) {
27 var _cb = function() { cb(); mozRequestAnimationFrame(_cb); }
31 onEachFrame = function(cb) {
32 setInterval(cb, 1000 / 30);
35 window.onEachFrame = onEachFrame;
36 window.onEachFrame(update);
37 var pos = document.location.href.lastIndexOf("/") + 1;
38 var page = document.location.href.substr(pos);
39 if (page == "mandelbrot.html") {
41 } else if (page == "" || page == "index.html") {
42 init_gameoflife("ME73");
43 } else if (page == "gameoflife.html") {
48 $(document).keypress(function(event) {
49 if (event.which == 13) {
50 event.preventDefault();
56 var menu_height = 100;
57 var menu_splits = new Array(180, 350, 505);
59 var click_events = new Array();
60 click_events["logo"] = new Array();
61 click_events["logo"][0] = new Object();
62 click_events["logo"][0]["min_x"] = 0;
63 click_events["logo"][0]["max_x"] = menu_splits[0];
64 click_events["logo"][0]["min_y"] = 0;
65 click_events["logo"][0]["max_y"] = menu_height;
66 click_events["logo"][0]["func"] = switch_page;
67 click_events["logo"][0]["args"] = new Array("personalwork.html");
68 click_events["logo"][1] = new Object();
69 click_events["logo"][1]["min_x"] = menu_splits[0] + 1;
70 click_events["logo"][1]["max_x"] = menu_splits[1];
71 click_events["logo"][1]["min_y"] = 0;
72 click_events["logo"][1]["max_y"] = menu_height;
73 click_events["logo"][1]["func"] = switch_page;
74 click_events["logo"][1]["args"] = new Array("howiwork.html");
75 click_events["logo"][2] = new Object();
76 click_events["logo"][2]["min_x"] = menu_splits[1] + 1;
77 click_events["logo"][2]["max_x"] = menu_splits[2];
78 click_events["logo"][2]["min_y"] = 0;
79 click_events["logo"][2]["max_y"] = menu_height;
80 click_events["logo"][2]["func"] = switch_page;
81 click_events["logo"][2]["args"] = new Array("books.html");
82 click_events["logo"][3] = new Object();
83 click_events["logo"][3]["min_x"] = menu_splits[2] + 1;
84 click_events["logo"][3]["max_x"] = menu_width - 1;
85 click_events["logo"][3]["min_y"] = 0;
86 click_events["logo"][3]["max_y"] = menu_height;
87 click_events["logo"][3]["func"] = switch_page;
88 click_events["logo"][3]["args"] = new Array("links.html", "linksend.html");
90 function mouse_pos(event, id) {
91 var offset = $(id).offset();
92 return new Array(event.pageX - offset.left,
93 event.pageY - offset.top);
96 function handle_click(event) {
97 var xy = mouse_pos(event, "#logo");
100 for (var i in click_events[event.target.id]) {
101 var ces = click_events[event.target.id][i];
102 if (ces && x >= ces["min_x"] && x <= ces["max_x"]
103 && y >= ces["min_y"] && y <= ces["max_y"]) {
104 ces["func"](event.target.id, ces);
110 function switch_page(id, params) {
111 var page = params["args"][0];
112 $("body").load(page);
113 document.location.href = page;
116 function colour_area(image, min_x, max_x, min_y, max_y, colour) {
117 var pixels = image.data;
118 for (var y = min_y; y <= max_y; y += 1) {
119 for (var x = min_x; x <= max_x; x += 1) {
120 var pix_colour = getPixel(image, x, y);
121 if (pix_colour.a > 0) {
122 colour.a = pix_colour.a;
123 setPixel(image, x, y, colour);
129 function init_logo(event) {
130 var canvas = document.getElementById("logo");
131 var context = canvas.getContext("2d");
132 canvas.width = menu_width;
133 canvas.height = menu_height;
134 context.drawImage(event.target, 0, 0);
135 var image = context.getImageData(0, 0, menu_width, menu_height);
136 for (var i in click_events["logo"]) {
137 var p = click_events["logo"][i];
138 var min_x = p["min_x"];
139 var max_x = p["max_x"];
140 var min_y = p["min_y"];
141 var max_y = p["max_y"];
142 var pos = document.location.href.lastIndexOf("/") + 1;
143 var page = document.location.href.substr(pos);
144 for (var j in p["args"]) {
145 if (page == p["args"][j]) {
146 colour_area(image, min_x, max_x, 0, 60, black);
147 colour_area(image, min_x, max_x, 60, max_y, white);
151 colour_area(image, min_x, max_x, 0, 60, white);
152 colour_area(image, min_x, max_x, 60, max_y, orange);
156 context.putImageData(image, 0, 0);
157 // context.fillStyle = green.str();
158 // console.log((found["max_x"] - found["min_x"]) / 2 + found["min_x"] - 2);
159 // context.fillRect((found["max_x"]-found["min_x"])/2+found["min_x"]-1, 95, 2, 5);
163 function draw_menu_lines() {
164 var canvas = document.getElementById("logo");
165 var context = canvas.getContext("2d");
166 var image = context.getImageData(0, 0, menu_width, menu_height);
167 var pixels = image.data;
168 context.lineCap = "round";
169 context.lineWidth = 1;
170 var colour1a = new Colour(0, 0, 0, 0.1);
172 context.moveTo(0, menu_height - 1);
173 context.lineTo(menu_width - 1, menu_height - 1);
175 context.strokeStyle = colour1a.str();
177 var colour1e = new Colour(0, 0, 0, 0.05);
179 context.moveTo(70, menu_height - 1);
180 context.lineTo(menu_width - 71, menu_height - 1);
182 context.strokeStyle = colour1e.str();
184 var colour1b = new Colour(0, 0, 0, 0.05);
186 context.moveTo(50, menu_height - 1);
187 context.lineTo(menu_width - 51, menu_height - 1);
189 context.strokeStyle = colour1b.str();
191 var colour1c = new Colour(0, 0, 0, 0.05);
193 context.moveTo(25, menu_height - 1);
194 context.lineTo(menu_width - 26, menu_height - 1);
196 context.strokeStyle = colour1c.str();
198 var colour1d = new Colour(0, 0, 0, 0.05);
200 context.moveTo(10, menu_height - 1);
201 context.lineTo(menu_width - 11, menu_height - 1);
203 context.strokeStyle = colour1d.str();
206 var colour2 = new Colour(0, 0, 0, 0.2);
208 context.moveTo(menu_splits[0], 0);
209 context.lineTo(menu_splits[0], menu_height - 1);
210 context.moveTo(menu_splits[1], 0);
211 context.lineTo(menu_splits[1], menu_height - 1);
212 context.moveTo(menu_splits[2], 0);
213 context.lineTo(menu_splits[2], menu_height - 1);
215 context.strokeStyle = colour2.str();
218 context.clearRect(menu_splits[0] - 1, menu_height - 1, 2, 2);
219 context.clearRect(menu_splits[1] - 1, menu_height - 1, 2, 2);
220 context.clearRect(menu_splits[2] - 1, menu_height - 1, 2, 2);
222 context.clearRect(menu_splits[0] - 1, menu_height - 2, 1, 1);
223 context.clearRect(menu_splits[1] - 1, menu_height - 2, 1, 1);
224 context.clearRect(menu_splits[2] - 1, menu_height - 2, 1, 1);
227 function clearMenuLines() {
228 var canvas = document.getElementById("logo");
229 var context = canvas.getContext("2d");
230 var image = context.getImageData(0, 0, menu_width, menu_height);
231 var pixels = image.data;
232 context.clearRect(0, menu_height - 2, menu_width - 1, 2);
233 context.clearRect(menu_splits[0] - 1, 0, 2, menu_height - 1);
234 context.clearRect(menu_splits[1] - 1, 0, 2, menu_height - 1);
235 context.clearRect(menu_splits[2] - 1, 0, 2, menu_height - 1);
238 function draw_sim_lines() {
241 var canvas = document.getElementById("sim");
242 var context = canvas.getContext("2d");
243 var image = context.getImageData(0, 0, w, h);
244 var pixels = image.data;
245 context.lineCap = "round";
246 context.lineWidth = 1;
247 var colour1a = new Colour(0, 0, 0, 0.1);
249 context.moveTo(0, h - 1);
250 context.lineTo(w - 1, h - 1);
252 context.strokeStyle = colour1a.str();
254 var colour1e = new Colour(0, 0, 0, 0.05);
256 context.moveTo(70, h - 1);
257 context.lineTo(w - 71, h - 1);
259 context.strokeStyle = colour1e.str();
261 var colour1b = new Colour(0, 0, 0, 0.05);
263 context.moveTo(50, h - 1);
264 context.lineTo(w - 51, h - 1);
266 context.strokeStyle = colour1b.str();
268 var colour1c = new Colour(0, 0, 0, 0.05);
270 context.moveTo(25, h - 1);
271 context.lineTo(w - 26, h - 1);
273 context.strokeStyle = colour1c.str();
275 var colour1d = new Colour(0, 0, 0, 0.05);
277 context.moveTo(10, h - 1);
278 context.lineTo(w - 11, h - 1);
280 context.strokeStyle = colour1d.str();
284 function update_logo() {
285 var canvas = document.getElementById("logo");
286 var context = canvas.getContext("2d");
287 var image = context.getImageData(0, 0, menu_width, menu_height);
288 var pixels = image.data;
289 var white = new Colour(255, 255, 255);
290 for (var y = 0; y < menu_height; y += 1) {
291 for (var x = 0; x < menu_width; x += 1) {
292 var pix_colour = getPixel(image, x, y);
293 if (pix_colour.a > 0) {
294 setPixel(image, x, y, new Colour(90, 215, 21, pix_colour.a));
298 context.putImageData(image, 0, 0);
301 var char_map = new Array();
302 char_map["A"] = new Array(new Array(0, 4), new Array(1, 3),
303 new Array(2, 2), new Array(3, 1),
304 new Array(4, 0), new Array(5, 1),
305 new Array(6, 2), new Array(7, 3),
306 new Array(8, 4), new Array(2, 3),
307 new Array(3, 3), new Array(4, 3),
308 new Array(5, 3), new Array(6, 3));
309 char_map["M"] = new Array(new Array(0, 4), new Array(0, 3),
310 new Array(0, 2), new Array(0, 1),
311 new Array(0, 0), new Array(0, 5),
312 new Array(5, 4), new Array(5, 3),
313 new Array(5, 2), new Array(5, 1),
314 new Array(5, 0), new Array(5, 5),
315 new Array(1, 1), new Array(2, 2),
316 new Array(4, 2), new Array(5, 1),
318 char_map["E"] = new Array(new Array(0, 4), new Array(0, 3),
319 new Array(0, 2), new Array(0, 1),
320 new Array(0, 0), new Array(0, 5),
321 new Array(1, 0), new Array(2, 0),
323 new Array(1, 3), new Array(2, 3),
324 new Array(1, 5), new Array(2, 5),
326 char_map["7"] = new Array(new Array(0, 0), new Array(1, 0),
328 new Array(0, 5), new Array(0, 4),
329 new Array(1, 3), new Array(2, 2));
330 char_map["3"] = new Array(new Array(2, 4), new Array(2, 3),
331 new Array(2, 2), new Array(2, 1),
332 new Array(0, 0), new Array(0, 5),
333 new Array(1, 0), new Array(2, 0),
334 new Array(1, 3), new Array(2, 3),
335 new Array(1, 5), new Array(2, 5))
337 function init_gameoflife(text) {
338 var canvas = document.getElementById("gameoflife");
341 gameoflife = new Simulation(canvas, 670, 670, cell_size,
343 $("#gameoflife").mousemove(function(event) {
344 gameoflife.mouse_moved(mouse_pos(event, "#gameoflife"));
346 var offset = new Array(13, 16);
347 for (var c in text) {
349 for (p in char_map[text[c]]) {
350 var x = char_map[text[c]][p][0];
351 var y = char_map[text[c]][p][1];
353 var pos = new Array((x + offset[0]) * cell_size,
354 (y + offset[1]) * cell_size);
355 gameoflife.activate_cell(pos);
362 function Colour(r, g, b, a) {
366 this.a = a == undefined ? 255 : a;
368 Colour.prototype.equals = function(rhs) {
370 if (typeof(rhs[p]) == undefined
371 || this[p] != rhs[p]) {
377 Colour.prototype.str = function() {
378 return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
381 var white = new Colour(255, 255, 255);
382 var black = new Colour(0, 0, 0);
383 var orange = new Colour(201, 87, 35);
384 var green = new Colour(90, 215, 21);
385 var background = new Colour(34, 34, 34);
387 function setPixel(image, x, y, colour) {
388 var index = 4 * (x + y * image.width);
389 image.data[index] = colour.r;
390 image.data[index + 1] = colour.g;
391 image.data[index + 2] = colour.b;
392 image.data[index + 3] = colour.a;
395 function getPixel(image, x, y) {
396 var index = 4 * (x + y * image.width);
397 var r = image.data[index];
398 var g = image.data[index + 1];
399 var b = image.data[index + 2];
400 var a = image.data[index + 3];
401 return new Colour(r, g, b, a);
404 function load_random_quote() {
405 var file = "/quotes/quote" + Math.floor(Math.random() * QUOTES_NUMBER + 1) + ".html";
406 $.ajax({url: SERVER + file,
407 success: write_quote});
410 function write_quote(data, status, xhr) {
411 $("#random_quote").html(data);
414 function load_footer()
416 var file = "/footer.html";
417 var currentFile = self.location.hostname + self.location.pathname;
418 var request = http_request_object();
419 var url = "http://" + self.location.hostname + file;
420 request.open("GET", url, false);
421 request.setRequestHeader("User-Agent", navigator.userAgent);
423 // if (oRequest.status == 200) alert(oRequest.responseText);
424 // else alert("Error executing XMLHttpRequest call!");
425 //document.write(url);
426 //document.write(request.responseText);
427 document.getElementById('footer').innerHTML = request.responseText;
432 // Mandelbrot functions
433 function Complex(real, imag)
439 var MIN_C = new Complex(-2.2, -1.4);
440 var MAX_C = new Complex(1.0, 1.4);
444 var max_iter = MIN_ITER;
449 function Result(z, iter)
455 function complex_quad(c)
457 return new Complex(Math.pow(c.real, 2) - Math.pow(c.imag, 2),
458 2.0 * c.real * c.imag);
461 function complex_quad_value(c)
463 return Math.pow(c.real, 2) + Math.pow(c.imag, 2);
466 function complex_add(c1, c2)
468 return new Complex(c1.real + c2.real, c1.imag + c2.imag);
471 function complex_equal(c1, c2)
473 return (c1.real == c2.real) && (c1.imag == c2.imag);
476 function iterate(z, c)
478 z_quad = complex_quad(z);
479 return new Complex(z_quad.real + c.real, z_quad.imag + c.imag);
482 function test(c, max_iter)
485 var z = new Complex(0.0, 0.0);
486 var last_z = new Complex(-1.0, 0.0);
487 var quad_z = complex_quad_value(z);
489 while (iter < max_iter
490 && !complex_equal(z, last_z)
491 && quad_z <= bailout)
495 quad_z = complex_quad_value(z);
498 return new Result(quad_z, iter);
501 function draw(diter, dx, dy, dz, dres)
503 var canvas = document.getElementById('mandelbrot');
505 if (canvas.getContext)
508 var ctx = canvas.getContext('2d');
512 resolution = Math.max(1, resolution + dres);
517 max_iter = Math.max(MIN_ITER, max_iter + diter);
520 var red = "rgb(255, 0, 0)";
521 var white = "rgb(255, 255, 255)";
522 var width = canvas.width;
523 var height = canvas.height;
524 var dim = Math.max(width, height);
525 var dim_ratio = Math.round(width / height);
526 var diff_c = new Complex(max_c.real - min_c.real,
527 max_c.imag - min_c.imag);
528 dx_min = diff_c.real / 100 * (dx + dz);
529 dx_max = diff_c.real / 100 * (dx - dz);
531 dy_min = diff_c.imag / 100 * (dy + dz);
532 dy_max = diff_c.imag / 100 * (dy - dz);
534 var min_inc = new Complex(dx_min * dim_ratio / 2.0, dy_min);
535 var max_inc = new Complex(dx_max * dim_ratio / 2.0, dy_max);
536 min_c = complex_add(min_c, min_inc);
537 max_c = complex_add(max_c, max_inc);
538 diff_c = new Complex(max_c.real - min_c.real,
539 max_c.imag - min_c.imag);
541 for (var y = 0; y < height; y += resolution)
543 for (var x = 0; x < width; x += resolution)
545 var c = new Complex(min_c.real + diff_c.real / dim * x,
546 min_c.imag + diff_c.imag / dim * y);
547 var result = test(c, max_iter);
548 var r = Math.min(255, Math.pow(Math.max(0,
549 (result.iter - max_iter / 20.0)), 2));
550 var g = Math.min(255, Math.pow(Math.max(0,
551 (result.iter - max_iter / 25.0)), 2));
552 var b = Math.min(255, Math.pow(Math.max(0,
553 (result.iter - max_iter / 20.0)), 2));
554 var colour = "rgb(" + r + "," + g + "," + b + ")";
555 ctx.fillStyle = colour;
556 ctx.fillRect(x, y, resolution, resolution);
562 function getEventOffsetX(evt)
564 if (evt.offsetX != null)
567 var obj = evt.target || evt.srcElement;
569 return (evt.clientX - obj.pageLeft);
572 function getEventOffsetY(evt)
574 if (evt.offsetY != null)
577 var obj = evt.target || evt.srcElement;
579 return (evt.clientY - obj.pageTop);
582 function setPageTopLeft( o )
588 while (o.offsetParent)
590 left += o.offsetLeft ;
599 function draw2(evt) {
602 var x = (getEventOffsetX(evt) - 335) / 167.5;
603 var y = (getEventOffsetY(evt) - 140) / 70;
605 draw(iter, x, y, z, res);
617 function Grid(width, height, cell_size) {
618 this.width = parseInt(width / cell_size + 0.5);
619 this.height = parseInt(height / cell_size + 0.5);
620 this.canvas_width = width;
621 this.canvas_height = height;
622 this.cell_size = cell_size;
623 this.cells = new Array();
624 for (var y = 0; y < this.height; ++y) {
625 this.cells[y] = new Array();
626 for (var x = 0; x < this.width; ++x) {
627 this.cells[y][x] = new Cell(x, y, 0, this);
631 Grid.prototype.cell = function(x, y) {
632 return this.cells[y][x];
634 Grid.prototype.pick_cell = function(x, y) {
635 var lx = parseInt(x / this.cell_size - 0.5);
636 var ly = parseInt(y / this.cell_size - 0.5);
637 return this.cells[ly][lx];
640 function Cell(x, y, value, grid) {
643 this.canvas_x = x * grid.cell_size;
644 this.canvas_y = y * grid.cell_size;
647 this._neighbours = new Array();
650 Cell.prototype.hash = function() {
651 return this.x + ", " + this.y;
653 Cell.prototype.set_value = function(value) {
655 this.last_mod = $.now();
657 Cell.prototype.neighbours = function() {
658 if (this._neighbours.length) {
659 return this._neighbours;
662 this._neighbours.push(this.grid.cell(this.x-1, this.y));
664 this._neighbours.push(this.grid.cell(this.x-1, this.y-1));
665 this._neighbours.push(this.grid.cell(this.x, this.y-1));
667 if (this.y + 1 < this.grid.height) {
668 this._neighbours.push(this.grid.cell(this.x-1, this.y+1));
671 if (this.x + 1 < this.grid.width) {
672 this._neighbours.push(this.grid.cell(this.x+1, this.y));
673 if (this.y + 1 < this.grid.height) {
674 this._neighbours.push(this.grid.cell(this.x+1, this.y+1));
675 this._neighbours.push(this.grid.cell(this.x, this.y+1));
678 this._neighbours.push(this.grid.cell(this.x+1, this.y-1));
681 return this._neighbours;
683 Cell.prototype.density = function() {
685 var neighbours = this.neighbours();
686 for (var n in neighbours) {
687 d += neighbours[n].value;
692 function Simulation(canvas, w, h, cell_size, life_colour, dead_colour) {
693 this.last_update = $.now() + 3000;
695 this.last_mouse_moved = 0;
696 this.redraw = new Array();
697 this.canvas = canvas;
698 this.canvas.width = w;
699 this.canvas.height = h;
700 this.context = canvas.getContext("2d");
701 this.pos_queue = new Array();
702 this.cell_queue = new Array();
703 this.cell_size = cell_size;
704 this.life_colour = life_colour;
705 this.dead_colour = dead_colour;
706 this.grid = new Grid(this.canvas.width, this.canvas.height, cell_size);
709 Simulation.prototype.draw = function() {
711 if (this.redraw.length) {
712 var cell = this.redraw[0];
714 this.context.fillStyle = cell.value == 1 ?
715 this.life_colour.str() : this.dead_colour.str();
716 this.context.fillRect(cell.canvas_x, cell.canvas_y,
717 this.grid.cell_size, this.grid.cell_size);
718 this.last_draw = $.now();
721 Simulation.prototype.update = function() {
723 while (this.pos_queue.length) {
724 var pos = this.pos_queue.pop();
725 if (pos[0] < this.canvas.width
726 && pos[1] < this.canvas.height) {
727 var cell = this.grid.pick_cell(pos[0], pos[1]);
729 this.cell_queue.push(cell);
730 this.cell_queue.concat(cell.neighbours());
731 this.redraw.unshift(cell);
734 if (this.last_update + 1000 > now) {
737 var changed = new Array();
738 var next_cell_queue = new Array();
739 while (this.cell_queue.length) {
740 var cell = this.cell_queue.pop();
741 if (changed[cell.hash()]) {
744 var d = cell.density();
745 if (d == 3 && cell.value == 0) {
746 changed[cell.hash()] = cell;
747 next_cell_queue = next_cell_queue.concat(cell.neighbours());
748 } else if (cell.value == 1) {
749 if (d < 2 || d > 3) {
750 changed[cell.hash()] = cell;
751 next_cell_queue = next_cell_queue.concat(cell.neighbours());
755 for (var pos in changed) {
756 var cell = changed[pos];
757 cell.set_value(1 - cell.value);
758 this.redraw.push(cell);
760 this.cell_queue = next_cell_queue;
761 this.last_update = now;
763 Simulation.prototype.activate_cell = function(pos) {
764 this.pos_queue.push(pos);
766 Simulation.prototype.mouse_moved = function(pos) {
768 if (this.last_mouse_moved + 50 < now) {
769 this.pos_queue.push(pos);
770 this.last_mouse_moved = now;