Not monolithic: split html into html and js parts
This commit is contained in:
parent
41e2a5b7f3
commit
c462428ea5
270
life.html
270
life.html
|
@ -1,275 +1,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>The Game of Life: HTML Canvas Demo</title>
|
<title>The Game of Life: HTML Canvas Demo</title>
|
||||||
<script language="javascript">
|
<script language="javascript" src="life.js"></script>
|
||||||
var size;
|
|
||||||
var hertz;
|
|
||||||
var height_px;
|
|
||||||
var width_px;
|
|
||||||
var height_c;
|
|
||||||
var width_c;
|
|
||||||
var cells;
|
|
||||||
var timer;
|
|
||||||
var effects;
|
|
||||||
|
|
||||||
// set start/stop button value
|
|
||||||
function btn_control_set_name(name) {
|
|
||||||
var btn = document.getElementById('control-btn');
|
|
||||||
btn.value = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate an 2d array of cells based on current geometry
|
|
||||||
function gen_cells() {
|
|
||||||
var new_cells = new Array(height_c);
|
|
||||||
for(var i = 0; i < height_c; i++) {
|
|
||||||
new_cells[i] = new Array(width_c);
|
|
||||||
}
|
|
||||||
for (var y = 0; y < height_c; y++) {
|
|
||||||
for (var x = 0; x < width_c; x++) {
|
|
||||||
new_cells[y][x] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new_cells;
|
|
||||||
}
|
|
||||||
|
|
||||||
// init the cells
|
|
||||||
function init_cells() {
|
|
||||||
cells = gen_cells();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate and populate the geometry variables
|
|
||||||
// possibly over complicated from my experiment with an elastic resizeable board
|
|
||||||
function get_demensions() {
|
|
||||||
var canvas = document.getElementById('board');
|
|
||||||
size = parseInt( document.getElementById('density').value);
|
|
||||||
width_px = canvas.offsetWidth - (canvas.offsetWidth%size);
|
|
||||||
canvas.width = width_px;
|
|
||||||
width_c = width_px/ size;
|
|
||||||
height_px = canvas.offsetHeight - (canvas.offsetHeight%size);
|
|
||||||
canvas.height = height_px;
|
|
||||||
height_c = height_px/size;
|
|
||||||
//console.log(width_px + 'x' + height_px + ' => ' + width_c + 'x' +height_c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// init the board
|
|
||||||
// set vars
|
|
||||||
// get geometry
|
|
||||||
// generate cells for 1st time
|
|
||||||
// draw
|
|
||||||
function board_init() {
|
|
||||||
var canvas = document.getElementById('board');
|
|
||||||
document.getElementById('density').value = 10;
|
|
||||||
get_demensions();
|
|
||||||
btn_control_set_name('Start');
|
|
||||||
document.getElementById('speed').value = 8;
|
|
||||||
change_speed();
|
|
||||||
init_cells();
|
|
||||||
document.getElementById('effects').value=0;
|
|
||||||
effects=0;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the current board: gird, then cells
|
|
||||||
function redraw() {
|
|
||||||
var canvas = document.getElementById('board');
|
|
||||||
var c = canvas.getContext('2d');
|
|
||||||
get_demensions();
|
|
||||||
|
|
||||||
c.globalCompositeOperation = 'destination-over';
|
|
||||||
|
|
||||||
c.clearRect(0, 0, width_px, height_px);
|
|
||||||
|
|
||||||
c.fillStyle='rgba(0,0,0,0.)';
|
|
||||||
c.strokeStyle= 'rgba(192,192,192,1)';
|
|
||||||
|
|
||||||
c.beginPath();
|
|
||||||
|
|
||||||
draw_grid(c);
|
|
||||||
c.stroke();
|
|
||||||
|
|
||||||
|
|
||||||
draw_cells(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a cycling darkening with age rainbow color
|
|
||||||
// based on math/code from http://www.krazydad.com/makecolors.php
|
|
||||||
function setStrokeAgeRainbow(l, c) {
|
|
||||||
var frequency = 0.3;
|
|
||||||
var center = 200; //128;
|
|
||||||
var width = 55; //127;
|
|
||||||
|
|
||||||
var red = Math.floor( (Math.sin(frequency*l + 0) * width + center) -l) ;
|
|
||||||
var green = Math.floor( (Math.sin(frequency*l + 2) * width + center) -l);
|
|
||||||
var blue = Math.floor( (Math.sin(frequency*l + 4) * width + center) -l);
|
|
||||||
|
|
||||||
red = Math.max(0, red);
|
|
||||||
green = Math.max(0, green);
|
|
||||||
blue = Math.max(0, blue);
|
|
||||||
|
|
||||||
c.strokeStyle= 'rgba('+red+','+green+','+blue+','+1+')';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw all the cells onto the board inside the grid
|
|
||||||
function draw_cells(c) {
|
|
||||||
for (var y = 0; y < height_c; y++) {
|
|
||||||
for (var x =0; x < width_c; x ++) {
|
|
||||||
if (cells[y][x] != 0) {
|
|
||||||
|
|
||||||
if(effects == 0) {
|
|
||||||
c.strokeStyle = 'rgba(0,0,0,1)';
|
|
||||||
} else {
|
|
||||||
setStrokeAgeRainbow(cells[y][x], c);
|
|
||||||
}
|
|
||||||
|
|
||||||
c.fillStyle = c.strokeStyle;
|
|
||||||
c.beginPath();
|
|
||||||
c.moveTo(x*size +1, y*size+1);
|
|
||||||
c.lineTo(x*size+ size-1, y*size+1);
|
|
||||||
c.lineTo(x*size+ size-1, y*size + size-1);
|
|
||||||
c.lineTo(x*size+1, y*size + size-1);
|
|
||||||
// auto return home
|
|
||||||
c.stroke();
|
|
||||||
c.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the grid and border
|
|
||||||
function draw_grid(c) {
|
|
||||||
// Horizontal lines
|
|
||||||
for (var y = 0; y <= height_px; y += size) {
|
|
||||||
c.moveTo(0, y);
|
|
||||||
c.lineTo(width_px, y);
|
|
||||||
}
|
|
||||||
// Vertical lines
|
|
||||||
for (var x = 0; x <= width_px; x += size) {
|
|
||||||
c.moveTo(x, 0);
|
|
||||||
c.lineTo(x, height_px);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// When we've loaded, run!
|
|
||||||
window.onload = board_init;
|
|
||||||
|
|
||||||
// is a cell alive or dead
|
|
||||||
// 0 for dead, 1 for alive
|
|
||||||
// walls count as dead
|
|
||||||
// used by num_neighbours
|
|
||||||
function cell_value(x, y) {
|
|
||||||
//console.log('(x:' + x + ',y:' + y + ') w/s:' + (width/size) + ' h/s:' + (height/size) );
|
|
||||||
if (x < 0 || x >= width_c || y < 0 || y >= height_c) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return cells[y][x] == 0 ? 0 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the number of neighbours for a cell
|
|
||||||
// walls count as dead
|
|
||||||
function num_neighbours(x, y) {
|
|
||||||
var n = 0;
|
|
||||||
n += cell_value(x-1, y-1);
|
|
||||||
n += cell_value(x, y-1);
|
|
||||||
n += cell_value(x+1, y-1);
|
|
||||||
|
|
||||||
n += cell_value(x-1, y);
|
|
||||||
n += cell_value(x+1, y);
|
|
||||||
|
|
||||||
n += cell_value(x-1, y+1);
|
|
||||||
n += cell_value(x, y+1);
|
|
||||||
n += cell_value(x+1, y+1);
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate one generation of cells
|
|
||||||
// create a new cells 2d array and simulate the next generation
|
|
||||||
// into it and then replace the current cells with it
|
|
||||||
function step() {
|
|
||||||
var new_cells = gen_cells();
|
|
||||||
for(var y=0; y < height_c; y++) {
|
|
||||||
for(var x =0 ; x < width_c; x++) {
|
|
||||||
var n = num_neighbours(x, y);
|
|
||||||
if (cells[y][x] != 0) {
|
|
||||||
if (n < 2 || n > 3) {
|
|
||||||
new_cells[y][x] = 0;
|
|
||||||
} else {
|
|
||||||
new_cells[y][x] = cells[y][x] +1;
|
|
||||||
}
|
|
||||||
} else if (n == 3) {
|
|
||||||
new_cells[y][x] = 1;
|
|
||||||
} else {
|
|
||||||
new_cells[y][x] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//new_cells[Math.floor(Math.random()*8)][ Math.floor(Math.random()*8) ] = true;
|
|
||||||
cells = new_cells;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop/Start button press
|
|
||||||
function control_click() {
|
|
||||||
var btn = document.getElementById('control-btn');
|
|
||||||
if (btn.value == 'Start') {
|
|
||||||
tick();
|
|
||||||
btn.value = 'Stop';
|
|
||||||
} else {
|
|
||||||
clearTimeout(timmer);
|
|
||||||
btn.value = 'Start';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to call on timmer
|
|
||||||
// simulate on e generation,
|
|
||||||
// redrawn
|
|
||||||
// reset timmer
|
|
||||||
function tick() {
|
|
||||||
step();
|
|
||||||
redraw();
|
|
||||||
timmer = setTimeout('tick();', 1000.0/hertz);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handler for a click on the board to place/unplace a cell
|
|
||||||
function board_click(e) {
|
|
||||||
var canvas = document.getElementById('board');
|
|
||||||
var x = Math.floor((e.pageX-canvas.offsetLeft)/size);
|
|
||||||
var y = Math.floor((e.pageY-canvas.offsetTop)/size);
|
|
||||||
cells[y][x] = ! cells[y][x];
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change speed handler
|
|
||||||
function change_speed() {
|
|
||||||
hertz = parseInt(document.getElementById('speed').value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize board handler (kind of not used)
|
|
||||||
// Left over from experiment in resiable elastic board
|
|
||||||
// Abandoned because of problems with lining up mouse clicks on board
|
|
||||||
// and weird stretcing issues
|
|
||||||
function resize_cells() {
|
|
||||||
var new_cells = gen_cells();
|
|
||||||
var w = Math.min(width_c, cells[0].length);
|
|
||||||
var h = Math.min(height_c, cells.length);
|
|
||||||
for(var y = 0; y < h; y++) {
|
|
||||||
for(x = 0; x < w; x++) {
|
|
||||||
new_cells[y][x] = cells[y][x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cells = new_cells;
|
|
||||||
}
|
|
||||||
|
|
||||||
// What to do on a document resize (more usefull for elastic boards)
|
|
||||||
function canvas_resize() {
|
|
||||||
get_demensions();
|
|
||||||
resize_cells();
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body onResize="canvas_resize();">
|
<body onResize="canvas_resize();">
|
||||||
Speed: <select id="speed" onChange="change_speed();">
|
Speed: <select id="speed" onChange="change_speed();">
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
var size;
|
||||||
|
var hertz;
|
||||||
|
var height_px;
|
||||||
|
var width_px;
|
||||||
|
var height_c;
|
||||||
|
var width_c;
|
||||||
|
var cells;
|
||||||
|
var timer;
|
||||||
|
var effects;
|
||||||
|
|
||||||
|
// set start/stop button value
|
||||||
|
function btn_control_set_name(name) {
|
||||||
|
var btn = document.getElementById('control-btn');
|
||||||
|
btn.value = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate an 2d array of cells based on current geometry
|
||||||
|
function gen_cells() {
|
||||||
|
var new_cells = new Array(height_c);
|
||||||
|
for(var i = 0; i < height_c; i++) {
|
||||||
|
new_cells[i] = new Array(width_c);
|
||||||
|
}
|
||||||
|
for (var y = 0; y < height_c; y++) {
|
||||||
|
for (var x = 0; x < width_c; x++) {
|
||||||
|
new_cells[y][x] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new_cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init the cells
|
||||||
|
function init_cells() {
|
||||||
|
cells = gen_cells();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate and populate the geometry variables
|
||||||
|
// possibly over complicated from my experiment with an elastic resizeable board
|
||||||
|
function get_demensions() {
|
||||||
|
var canvas = document.getElementById('board');
|
||||||
|
size = parseInt( document.getElementById('density').value);
|
||||||
|
width_px = canvas.offsetWidth - (canvas.offsetWidth%size);
|
||||||
|
canvas.width = width_px;
|
||||||
|
width_c = width_px/ size;
|
||||||
|
height_px = canvas.offsetHeight - (canvas.offsetHeight%size);
|
||||||
|
canvas.height = height_px;
|
||||||
|
height_c = height_px/size;
|
||||||
|
//console.log(width_px + 'x' + height_px + ' => ' + width_c + 'x' +height_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init the board
|
||||||
|
// set vars
|
||||||
|
// get geometry
|
||||||
|
// generate cells for 1st time
|
||||||
|
// draw
|
||||||
|
function board_init() {
|
||||||
|
var canvas = document.getElementById('board');
|
||||||
|
document.getElementById('density').value = 10;
|
||||||
|
get_demensions();
|
||||||
|
btn_control_set_name('Start');
|
||||||
|
document.getElementById('speed').value = 8;
|
||||||
|
change_speed();
|
||||||
|
init_cells();
|
||||||
|
document.getElementById('effects').value=0;
|
||||||
|
effects=0;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the current board: gird, then cells
|
||||||
|
function redraw() {
|
||||||
|
var canvas = document.getElementById('board');
|
||||||
|
var c = canvas.getContext('2d');
|
||||||
|
get_demensions();
|
||||||
|
|
||||||
|
c.globalCompositeOperation = 'destination-over';
|
||||||
|
|
||||||
|
c.clearRect(0, 0, width_px, height_px);
|
||||||
|
|
||||||
|
c.fillStyle='rgba(0,0,0,0.)';
|
||||||
|
c.strokeStyle= 'rgba(192,192,192,1)';
|
||||||
|
|
||||||
|
c.beginPath();
|
||||||
|
|
||||||
|
draw_grid(c);
|
||||||
|
c.stroke();
|
||||||
|
|
||||||
|
|
||||||
|
draw_cells(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a cycling darkening with age rainbow color
|
||||||
|
// based on math/code from http://www.krazydad.com/makecolors.php
|
||||||
|
function setStrokeAgeRainbow(l, c) {
|
||||||
|
var frequency = 0.3;
|
||||||
|
var center = 200; //128;
|
||||||
|
var width = 55; //127;
|
||||||
|
|
||||||
|
var red = Math.floor( (Math.sin(frequency*l + 0) * width + center) -l) ;
|
||||||
|
var green = Math.floor( (Math.sin(frequency*l + 2) * width + center) -l);
|
||||||
|
var blue = Math.floor( (Math.sin(frequency*l + 4) * width + center) -l);
|
||||||
|
|
||||||
|
red = Math.max(0, red);
|
||||||
|
green = Math.max(0, green);
|
||||||
|
blue = Math.max(0, blue);
|
||||||
|
|
||||||
|
c.strokeStyle= 'rgba('+red+','+green+','+blue+','+1+')';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw all the cells onto the board inside the grid
|
||||||
|
function draw_cells(c) {
|
||||||
|
for (var y = 0; y < height_c; y++) {
|
||||||
|
for (var x =0; x < width_c; x ++) {
|
||||||
|
if (cells[y][x] != 0) {
|
||||||
|
|
||||||
|
if(effects == 0) {
|
||||||
|
c.strokeStyle = 'rgba(0,0,0,1)';
|
||||||
|
} else {
|
||||||
|
setStrokeAgeRainbow(cells[y][x], c);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.fillStyle = c.strokeStyle;
|
||||||
|
c.beginPath();
|
||||||
|
c.moveTo(x*size +1, y*size+1);
|
||||||
|
c.lineTo(x*size+ size-1, y*size+1);
|
||||||
|
c.lineTo(x*size+ size-1, y*size + size-1);
|
||||||
|
c.lineTo(x*size+1, y*size + size-1);
|
||||||
|
// auto return home
|
||||||
|
c.stroke();
|
||||||
|
c.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the grid and border
|
||||||
|
function draw_grid(c) {
|
||||||
|
// Horizontal lines
|
||||||
|
for (var y = 0; y <= height_px; y += size) {
|
||||||
|
c.moveTo(0, y);
|
||||||
|
c.lineTo(width_px, y);
|
||||||
|
}
|
||||||
|
// Vertical lines
|
||||||
|
for (var x = 0; x <= width_px; x += size) {
|
||||||
|
c.moveTo(x, 0);
|
||||||
|
c.lineTo(x, height_px);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// When we've loaded, run!
|
||||||
|
window.onload = board_init;
|
||||||
|
|
||||||
|
// is a cell alive or dead
|
||||||
|
// 0 for dead, 1 for alive
|
||||||
|
// walls count as dead
|
||||||
|
// used by num_neighbours
|
||||||
|
function cell_value(x, y) {
|
||||||
|
//console.log('(x:' + x + ',y:' + y + ') w/s:' + (width/size) + ' h/s:' + (height/size) );
|
||||||
|
if (x < 0 || x >= width_c || y < 0 || y >= height_c) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return cells[y][x] == 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the number of neighbours for a cell
|
||||||
|
// walls count as dead
|
||||||
|
function num_neighbours(x, y) {
|
||||||
|
var n = 0;
|
||||||
|
n += cell_value(x-1, y-1);
|
||||||
|
n += cell_value(x, y-1);
|
||||||
|
n += cell_value(x+1, y-1);
|
||||||
|
|
||||||
|
n += cell_value(x-1, y);
|
||||||
|
n += cell_value(x+1, y);
|
||||||
|
|
||||||
|
n += cell_value(x-1, y+1);
|
||||||
|
n += cell_value(x, y+1);
|
||||||
|
n += cell_value(x+1, y+1);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate one generation of cells
|
||||||
|
// create a new cells 2d array and simulate the next generation
|
||||||
|
// into it and then replace the current cells with it
|
||||||
|
function step() {
|
||||||
|
var new_cells = gen_cells();
|
||||||
|
for(var y=0; y < height_c; y++) {
|
||||||
|
for(var x =0 ; x < width_c; x++) {
|
||||||
|
var n = num_neighbours(x, y);
|
||||||
|
if (cells[y][x] != 0) {
|
||||||
|
if (n < 2 || n > 3) {
|
||||||
|
new_cells[y][x] = 0;
|
||||||
|
} else {
|
||||||
|
new_cells[y][x] = cells[y][x] +1;
|
||||||
|
}
|
||||||
|
} else if (n == 3) {
|
||||||
|
new_cells[y][x] = 1;
|
||||||
|
} else {
|
||||||
|
new_cells[y][x] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//new_cells[Math.floor(Math.random()*8)][ Math.floor(Math.random()*8) ] = true;
|
||||||
|
cells = new_cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop/Start button press
|
||||||
|
function control_click() {
|
||||||
|
var btn = document.getElementById('control-btn');
|
||||||
|
if (btn.value == 'Start') {
|
||||||
|
tick();
|
||||||
|
btn.value = 'Stop';
|
||||||
|
} else {
|
||||||
|
clearTimeout(timmer);
|
||||||
|
btn.value = 'Start';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to call on timmer
|
||||||
|
// simulate on e generation,
|
||||||
|
// redrawn
|
||||||
|
// reset timmer
|
||||||
|
function tick() {
|
||||||
|
step();
|
||||||
|
redraw();
|
||||||
|
timmer = setTimeout('tick();', 1000.0/hertz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler for a click on the board to place/unplace a cell
|
||||||
|
function board_click(e) {
|
||||||
|
var canvas = document.getElementById('board');
|
||||||
|
var x = Math.floor((e.pageX-canvas.offsetLeft)/size);
|
||||||
|
var y = Math.floor((e.pageY-canvas.offsetTop)/size);
|
||||||
|
cells[y][x] = ! cells[y][x];
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change speed handler
|
||||||
|
function change_speed() {
|
||||||
|
hertz = parseInt(document.getElementById('speed').value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize board handler (kind of not used)
|
||||||
|
// Left over from experiment in resiable elastic board
|
||||||
|
// Abandoned because of problems with lining up mouse clicks on board
|
||||||
|
// and weird stretcing issues
|
||||||
|
function resize_cells() {
|
||||||
|
var new_cells = gen_cells();
|
||||||
|
var w = Math.min(width_c, cells[0].length);
|
||||||
|
var h = Math.min(height_c, cells.length);
|
||||||
|
for(var y = 0; y < h; y++) {
|
||||||
|
for(x = 0; x < w; x++) {
|
||||||
|
new_cells[y][x] = cells[y][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cells = new_cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
// What to do on a document resize (more usefull for elastic boards)
|
||||||
|
function canvas_resize() {
|
||||||
|
get_demensions();
|
||||||
|
resize_cells();
|
||||||
|
redraw();
|
||||||
|
}
|
Loading…
Reference in New Issue