SOURCE

console 命令行工具 X clear

                    
>
console
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

'floor|random|round|abs|sqrt|PI|atan2|sin|cos|pow|max|min'
    .split('|')
    .forEach(function (p) {
        window[p] = Math[p];
    });

var TAU = PI * 2;

function r(n) {
    return random() * n;
}

function rrng(lo, hi) {
    return lo + r(hi - lo);
}

function rint(lo, hi) {
    return lo + floor(r(hi - lo + 1));
}

function choose() {
    return arguments[rint(0, arguments.length - 1)];
}

function choose1(args) {
    return args[rint(0, args.length - 1)];
}

/*---------------------------------------------------------------------------*/

var W, H, frame, t0, time;
var DPR = devicePixelRatio || 1;

function dpr(n) {
    return n * DPR;
}

function resize() {
    var w = innerWidth;
    var h = innerHeight;

    canvas.style.width = w + 'px';
    canvas.style.height = h + 'px';

    W = canvas.width = w * DPR;
    H = canvas.height = h * DPR;
}

function loop(t) {
    frame = requestAnimationFrame(loop);
    draw();
    time++;
}

function pause() {
    cancelAnimationFrame(frame);
    frame = frame ? null : requestAnimationFrame(loop);
}

function reset() {
    cancelAnimationFrame(frame);
    resize();
    ctx.clearRect(0, 0, W, H);
    init();
    time = 0;
    frame = requestAnimationFrame(loop);
}

/*---------------------------------------------------------------------------*/

var up = {
    x: 0,
    y: -1
};
var down = {
    x: 0,
    y: 1
};
var left = {
    x: -1,
    y: 0
};
var right = {
    x: 1,
    y: 0
};

var dirs = [up, down, left, right];

function Growth(grid) {
    var pos = grid.freeCell();
    this.x = pos.x;
    this.y = pos.y;
    this.grid = grid;
    grid.cells[pos.x][pos.y] = true;
    this.setNewDirection();
}

Growth.prototype.canMove = function (dir) {
    var x = this.x + dir.x;
    var y = this.y + dir.y;
    if (x < 0 || x >= this.grid.dim) return false;
    if (y < 0 || y >= this.grid.dim) return false;
    return !this.grid.cells[x][y];
};

Growth.prototype.possibleDirs = function () {
    return dirs.filter(this.canMove.bind(this));
};

Growth.prototype.setNewDirection = function () {
    var possibles = this.possibleDirs();
    if (!possibles.length) return this.dir = null;
    this.dir = choose1(possibles);
    this.grid.cells[this.x + this.dir.x][this.y + this.dir.y] = true;
};

Growth.prototype.update = function () {
    if (this.dead) return;

    this.x += this.dir.x;
    this.y += this.dir.y;
    this.setNewDirection();
};

Growth.prototype.draw = function (t) {
    var dir = this.dead ? {
        x: 0,
        y: 0
    } : this.dir;
    var size = this.grid.size;

    var x = this.grid.x + (this.x + dir.x * t) * size;
    var y = this.grid.y + (this.y + dir.y * t) * size;
    ctx.fillRect(x + PAD, y + PAD, size - PAD2, size - PAD2);
};

Object.defineProperty(Growth.prototype, 'dead', {
    get: function () {
        return !this.dir;
    }
});

function Grid(x, y, size, dim) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.dim = dim;
    this.cells = new Array(dim);
    for (var i = 0; i < dim; i++) {
        this.cells[i] = new Array(dim);
        for (var j = 0; j < dim; j++) {
            this.cells[i][j] = false;
        }
    }
    this.growths = [];
    for (var i = 0; i < dim; i++) {
        this.growths[i] = new Growth(this);
    }
}

Grid.prototype.freeCell = function () {
    var x, y;
    do {
        x = ~~r(this.dim);
        y = ~~r(this.dim);
    } while (this.cells[x][y] === true);
    return {
        x: x,
        y: y
    };
};

Grid.prototype.update = function () {
    this.growths.forEach(function (growth) {
        growth.update();
    });
};

Grid.prototype.draw = function (t) {
    this.growths.forEach(function (growth) {
        growth.draw(t);
    });
};

Object.defineProperty(Grid.prototype, 'dead', {
    get: function () {
        return this.growths.every(function (g) {
            return g.dead;
        });
    }
});

/*---------------------------------------------------------------------------*/

var PAD = dpr(2);
var PAD2 = 2 * PAD;
var STEP = 10;

var w = 5;
var h = 3;
var sz = dpr(10);
var dim = 7;
var spc = 2;

var grids;

function init() {
    grids = [];

    var ww = (w * sz * dim) + (w - 1) * spc * sz;
    var hh = (h * sz * dim) + (h - 1) * spc * sz;
    var offsetX = ~~((W - ww) / 2);
    var offsetY = ~~((H - hh) / 2);
    for (var i = 0; i < w; i++) {
        for (var j = 0; j < h; j++) {
            var grid = new Grid(offsetX + (i * (dim + spc) * sz),
                offsetY + (j * (dim + spc) * sz),
                sz, dim);
            grids.push(grid);
        }
    }

    ctx.fillStyle = 'rgb(34, 49, 63)';
    ctx.fillRect(0, 0, W, H);
    ctx.fillStyle = 'rgb(218, 223, 225)';
}

function draw() {
    if (time && time % STEP === 0) {
        grids.forEach(function (g) {
            g.update();
        });
    }
    var t = time % STEP / STEP;
    grids.forEach(function (g) {
        g.draw(t);
    });
    if (grids.every(function (g) {
        return g.dead;
    })) {
        pause();
        setTimeout(reset, 1000);
    }
}

/*---------------------------------------------------------------------------*/

document.onclick = pause;
window.onresize = reset;

reset();
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>
</html>
body {
    margin: 0;
    padding: 0;
    overflow: hidden;
}