123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- const canvas = document.getElementById('canvas');
- canvas.width = window.innerWidth - 50;
- canvas.height = window.innerHeight - 50;
- const canvwidth = canvas.width,
- canvheight = canvas.height,
- ctx = canvas.getContext('2d');
- function randIndivC(a = 0, b = 255) {
- return Math.floor(Math.random() * (b-a) + a);
- }
- function cts(c) {
- const r = c.r < 16 ? '0' + c.r.toString(16) : c.r.toString(16),
- g = c.g < 16 ? '0' + c.g.toString(16) : c.g.toString(16),
- b = c.b < 16 ? '0' + c.b.toString(16) : c.b.toString(16);
- return '#' + r + g + b;
- }
- function mixedColor(base) {
- let randr = Math.floor(Math.random() * 200 + 55),
- randg = Math.floor(Math.random() * 200 + 55),
- randb = Math.floor(Math.random() * 200 + 55);
- if( base ) {
- randr = Math.floor((base.r + randr) / 2);
- randg = Math.floor((base.g + randg) / 2);
- randb = Math.floor((base.b + randb) / 2);
- }
- return cts({r:randr, g:randg, b:randb});
- }
- function primaryOrSecondary() {
- const t = Math.random(),
- w = Math.floor(Math.random() * 3);
- if( t < 0.45 ) {
- const r = w === 0 ? 255 : 0,
- g = w === 1 ? 255 : 0,
- b = w === 2 ? 255 : 0;
- return {r, g, b};
- }
- else if( t < 0.9 ) {
- const r = w !== 0 ? 255 : 0,
- g = w !== 1 ? 255 : 0,
- b = w !== 2 ? 255 : 0;
- return {r, g, b};
- }
- else {
- const r = randIndivC(100, 255),
- g = randIndivC(100, 255),
- b = randIndivC(100, 255);
- return {r, g, b};
- }
- }
- function spot(x, y, colour) {
- ctx.save();
- ctx.fillStyle = colour;
- ctx.fillRect(x, y, 10, 10);
- ctx.restore();
- }
- function generateInitialRow(lx = canvwidth / 10 + 1) {
- const row = [];
- for( let i = 0; i < lx; i++ ) {
- row.push( Math.random() < 0.5 ? false : true );
- }
- return row;
- }
- const rules = {
- "111": false,
- "110": true,
- "101": true,
- "100": false,
- "011": true,
- "010": true,
- "001": true,
- "000": false,
- };
- function applyRules(first, second, third) {
- return rules[ [+first, +second, +third].join('') ];
- }
- function addRow(field) {
- if( !field.length ) {
- return field;
- }
- if( field[0].length < 3 ) {
- return field;
- }
- const last = field[ field.length - 1 ],
- newRow = last.map(function iter(val, ind) {
- const first = last[ind - 1] || 0,
- second = val,
- third = last[ind + 1] || 0;
- return applyRules(first, second, third);
- });
- field.push(newRow);
- return field;
- }
- function drawRow(row, y) {
- row.forEach(function spotter(val, ind) {
- if( val ) {
- const c = mixedColor(primaryOrSecondary());
- spot(ind * 10, y, c);
- }
- });
- }
- function step(field) {
- requestAnimationFrame(descend.bind(null, field));
- }
- function descend(field) {
- const n = field.length - 1;
- drawRow(field[n], n * 10);
- field = addRow(field);
- if( n * 10 < canvheight ) {
- setTimeout(step, 100, field);
- }
- else {//TODO: remove this clause after tests
- console.log('STOP!');
- }
- }
- step([ generateInitialRow() ]);
|