screensaver/GameOfLife/index.html
2023-08-25 15:04:43 +00:00

301 lines
11 KiB
HTML
Executable File

<html>
<head>
<style>
canvas {
image-rendering: optimizeSpeed; /* Older versions of FF */
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
image-rendering: -webkit-optimize-contrast; /* Safari */
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
image-rendering: pixelated; /* Awesome future-browsers */
-ms-interpolation-mode: nearest-neighbor; /* IE */
}
html, body {
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<script type="text/javascript">
var grid = new Array();
var newGrid = new Array();
var scaleX = 10 ;
var scaleY = 10 ;
var width = Math.round( ( window.innerWidth/scaleX ) / 2 ) * 2 ;
var height = Math.round( ( window.innerHeight/scaleY ) / 2 ) * 2 ;
var element = document.getElementById('canvas');
var context = element.getContext('2d');
var step = 0.005 ;
var ratio = 1 ;
var ratioIndex = 0 ;
var hue = 0.6 ;
var speed = 1.0;
var HSV = function(h, s, v, a){
var self = this ;
self.h = h ;
self.s = s ;
self.v = v ;
self.a = a ;
self.toRGB = function() {
var r, g, b, i, f, p, q, t;
var h = self.h;
var s = self.s;
var v = self.v;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
}
function countNeighbours(xPos, yPos){
var n = 0;
for(var x=-1;x<2;x++){
for(var y=-1;y<2;y++){
var calcX = (xPos+x);
var calcY = (yPos+y);
if(calcX == width){
calcX = 0;
}
else if(calcX == -1){
calcX = width - 1;
}
if(calcY == height){
calcY = 0;
}
else if(calcY == -1){
calcY = height - 1;
}
var state = grid[calcX][calcY];
if((x != 0 || y != 0) && state == 1){
n++;
}
}
}
return n;
}
var imagedata = context.createImageData(width, height);
function placeGlider(){
placeSchematic( Math.floor(Math.random() * (width-4)) , Math.floor(Math.random() * (height-4)) , glider , Math.floor(Math.random()*4) );
setTimeout(placeGlider, 1000 * (1/speed));
}
function init(){
context.canvas.width = width ;
context.canvas.height = height ;
element.style.width = width * scaleX ;
element.style.height = height * scaleY ;
for(var x=0;x<width;x++){
grid[x] = new Array();
newGrid[x] = new Array();
for(var y=0;y<height;y++){
grid[x][y] = 0; // Math.floor(Math.random() * 2) + 0 : (Math.floor(Math.random() * 5) == 1) ;
newGrid[x][y] = 0;
}
}
placeGlider();
placeSchematic( Math.round(width/2)+4, Math.round(height/2) , glider , 2 );
placeSchematic( Math.round(width/2), Math.round(height/2)+4 , glider , 0 );
placeSchematic( Math.round(width/2), Math.round(height/2) , glider , 1 );
}
var glider = [ [0, 1, 0],
[1, 0, 0],
[1, 1, 1]];
function placeSchematic (xPos , yPos , s, r){
for(var n=0;n<r;n++){
s = mirrorArr(RotateMatrix(s , s.length ) );
}
for(var x=0;x<s.length;x++){
for(var y=0;y<s[0].length;y++){
grid[xPos+x][yPos+y] = s[y][x] ;
}
}
}
function mirrorArr(a) {
return a.map(function(arr){return arr.reverse();});
}
function RotateMatrix(a) {
return Object.keys(a[0]).map(
function (c) {
return a.map(function (r) {
return r[c];
});
}
);
}
function update(){
ratioIndex += speed ;
if(ratioIndex >= ratio){
ratioIndex = 0;
for(var x=0;x<width;x++){
for(var y=0;y<height;y++){
var n = countNeighbours(x, y);
if(grid[x][y] < 1){
if(n == 3){
newGrid[x][y] = 1;
}
else {
newGrid[x][y] = Math.max(grid[x][y] - step * speed , 0);
}
}
else if(grid[x][y] == 1) {
if(n < 2 || n > 3){
newGrid[x][y] = 1 - step ;
}
if(n == 2 || n == 3){
newGrid[x][y] = 1;
}
}
}
}
}
else {
for(var x=0;x<width;x++){
for(var y=0;y<height;y++){
if(grid[x][y] < 1) {
newGrid[x][y] = Math.max(grid[x][y] - step * speed , 0);
}
else {
newGrid[x][y] = 1;
}
}
}
}
for(var x=0;x<width;x++){
for(var y=0;y<height;y++){
grid[x][y] = newGrid[x][y];
var pixelindex = (y * width + x) * 4;
// Generate a xor pattern with some random noise
var intensity = grid[x][y] ;
var color = new HSV( hue + (0.2*intensity) , intensity > (1-step) ? 0.1 : 0.25+intensity , intensity*intensity , 1 ).toRGB();
var red = color.r ;
var green = color.g ;
var blue = color.b ;
// var red = green = blue = intensity * 255 ;
// Set the pixel data
imagedata.data[pixelindex] = red; // Red
imagedata.data[pixelindex+1] = green; // Green
imagedata.data[pixelindex+2] = blue; // Blue
imagedata.data[pixelindex+3] = 255; // Alpha
}
}
}
init();
function point(x, y, canvas){
canvas.beginPath();
canvas.moveTo(x, y);
canvas.lineTo(x+1, y+1);
canvas.stroke();
}
function draw(){
window.requestAnimationFrame(draw);
update();
context.putImageData(imagedata, 0, 0);
}
draw();
var looping = false;
setInterval(function(){
if(looping){
hue = hue+0.01;
hue = hue>1?0:hue;
}
},400);
document.addEventListener ('keydown', function (event) {
if (event.which == 38) {
hue = Math.min(hue+0.01, 1);
}
else if(event.which == 40){
hue = Math.max(hue-0.01, 0);
}
if (event.which == 37) {
speed = Math.min(speed+0.01, 1);
}
else if(event.which == 39){
speed = Math.max(speed-0.01, 0.1 );
}
if (event.which == 32){
looping = looping?false:true;
}
});
</script>
</html>