JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="e1"></canvas>
<canvas id="e2"></canvas>
<canvas id="e3"></canvas>

JavaScript

(function() {
  var textures = document.querySelector('#e1');

  var ctx = textures.getContext('2d');
  var tcount = 8;

  textures.width = tcount * 100;
  textures.height = 100;

  function rcolor() {
    return '#' + (Math.floor(Math.random() * (0xffffff - 0x100000)) + 0x100000).toString(16);
  }

  for (var i = 0; i < tcount; ++i) {
    var g = Math.random() > .5
      ? ctx.createRadialGradient(i * 100 + 50, 50, 0, i * 100 + 50, 50, 100)
      : ctx.createLinearGradient(i * 100, 0, i * 100 + 100, 100);
    g.addColorStop(0, rcolor());
    g.addColorStop(1, rcolor());
    ctx.fillStyle = g;
    ctx.fillRect(i * 100, 0, 100, 100);
  }

  var map = window.map = [
    'xxxxxxxxxxxxxxx',
    'x      x  x   x',
    'x  xx xxx   x x',
    'x         x   x',
    'xxxxxxxxxxxxxxx',
  ].join('').split('').map(function (s) {
    // spaces are open, xes are a random texture
    if (s === ' ') return 0;
    return 1 + Math.floor(Math.random() * tcount);
  });

  var width = 15;
  var height = 5;
  var unit = 50;
  var canvas = document.querySelector('#e2');
  var ctx = window.ctx2 = canvas.getContext('2d');
  canvas.width = width * unit;
  canvas.height = height * unit;

  window.drawMiniMap = function() {
    for (var x = 0; x < width; ++x) {
      for (var y = 0; y < height; ++y) {
        if (map[y * width + x]) {
          ctx.drawImage(textures, (map[y * width + x] - 1) * 100, 0, 100, 100, x * unit, y * unit, unit, unit);
        }
      }
    }
  };
  
})();

(function() {
  var textures = document.querySelector('#e1');
  var mini = document.querySelector('#e2');
  var canvas = document.querySelector('#e3');
  var ctx = canvas.getContext('2d');
  var ctx2 = mini.getContext('2d');

  canvas.width = 500;
  canvas.height = 200;
  canvas.style.border = '1px solid black';

  var fix = false;

  if (!fix) mini.onmousemove = function(e){
    x = (e.clientX - mini.offsetLeft) / unit;
    y = (e.clientY - mini.offsetTop) / unit;
  };

  function cast(px, py, angle) {
    if...