{"size": 1980, "ext": "js", "max_stars_repo_path": "matrix-digital-rain/sketch.js", "max_stars_repo_name": "LunaLovegoood/matrix-digital-rain", "max_stars_repo_stars_event_min_datetime": "2019-01-01T20:54:39.000Z", "max_stars_repo_stars_event_max_datetime": "2019-01-01T20:54:39.000Z", "max_issues_repo_path": "matrix-digital-rain/sketch.js", "max_issues_repo_name": "LunaLovegoood/matrix-digital-rain", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "matrix-digital-rain/sketch.js", "max_forks_repo_name": "LunaLovegoood/matrix-digital-rain", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 1, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 18.5046728972, "max_line_length": 64, "alphanum_fraction": 0.5843434343}
const symbolSize = 20;
let matrix;

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);
  textSize(symbolSize);
  stroke(0);

  matrix = new Matrix();
}

function draw() {
  background(0, 150);
  matrix.render();
}

class Matrix {
  constructor() {
    this._columns = [];
    this._numberOfColumns = round(width / symbolSize);

    this._initMatrix();
  }

  _initMatrix() {
    for (let i = 0; i < this._numberOfColumns; i++) {
      this._columns.push(new SymbolColumn(
        i * symbolSize, round(random(-1000, 0))
      ));
    }
  }

  render() {
    this._columns.forEach(column => column.render());
  }
}

class SymbolColumn {
  constructor(x, y) {
    this._symbols = [];
    this._numberOfSymbols = round(random(10, 30));

    this._x = x;
    this._y = y;
    this._speed = round(random(4, 15));

    this._generateSymbols();
  }

  _generateSymbols() {
    let isFirst = true;

    for (let i = 0; i < this._numberOfSymbols; i++) {
      this._symbols.push(new Symbol(
        this._x, this._y - i*symbolSize,
        this._speed, 255 - i*round(255 / this._numberOfSymbols),
        isFirst
      ));
      isFirst = false;
    }
  }

  render() {
    this._symbols.forEach(symbol => symbol.render());
  }
}

class Symbol {
  constructor(x, y, speed, opacity, isFirst) {
    this._x = x;
    this._y = y;
    this._speed = speed;
    this._switchInterval = round(random(5, 20));

    this._value;
    this._color = isFirst
      ? color(118, 216, 159)
      : color(57, 192, 70, opacity);

    this._setToRandomSymbol();
  }

  _setToRandomSymbol() {
    this._value = String.fromCharCode(
      0x30a0 + round(random(0, 96))
    );
  }

  render() {
    fill(this._color);
    text(this._value, this._x, this._y);

    this._fallDown();
    if (frameCount % this._switchInterval === 0) {
      this._setToRandomSymbol();
    }
  }

  _fallDown() {
    this._y += this._speed;

    if (this._y >= height) {
      this._y -= height;
    }
  }
}
