JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="canvas" width="1000" height="1000"></canvas>

CSS

body {
  margin: 0;
  padding: 0;
}

JavaScript

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext("2d");

const grd = ctx.createLinearGradient(0, 0, 170, 0);
grd.addColorStop(0, "black");
grd.addColorStop(1, "white");

const user = {
  x: 0,
  y: 100,
  r: 10
};

const rects = [{
    x: (t) => 50 + Math.sin(t / 1000) * 5,
    y: (t) => 0,
  },
  {
    x: (t) => 150,
    y: (t) => 50,
  },
  {
    x: (t) => 150 + Math.cos(t / 5000) * 100,
    y: (t) => 150,
  },
  {
    x: (t) => 450,
    y: (t) => 50,
  }
];

const render = (t) => {
  if (t % 3 === 0) return;

  ctx.fillStyle = "rgb(100,100,100)"
  ctx.fillRect(0, 0, 1000, 1000);
  ctx.fillStyle = "black"

  for (let i = 0; i < rects.length; i++) {
    ctx.fillRect(rects[i].x(t), rects[i].y(t), 50, 50);
  }


  ctx.beginPath();
  ctx.fillStyle = "green"
  ctx.arc(user.x, user.y, user.r, 0, 2 * Math.PI);
  ctx.fill();

  ctx.beginPath();
  ctx.strokeStyle = "rgb(40,40,40)"
  ctx.lineWidth = 5;

  let radStep = 1;
  let maxRadius = 300;
  for (let i = 0; i < 360; i += 1) {
    let endX = 0;
    let endY = 0;

    let isWall = false;
    let thisRad = 0;
    for (let r = user.r + 1; r < maxRadius; r += radStep) {
      endX = user.x + Math.sin(i) * r;
      endY = user.y + Math.cos(i) * r;

      let wall = false;
      for (let i = 0; i < rects.length; i++) {
        const x = rects[i].x(t);
        const y = rects[i].y(t);
        if (endX >= x && endX <= x + 50 && endY >= y && endY <= y + 50) {
          wall = true;
        }
      }

      if (isWall && !wall) {
        r = maxRadius;
        isWall = false;
      }

      isWall = wall;
      thisRad = r;
    }

    const startX = user.x + Math.sin(i) * maxRadius;
    const startY = user.y + Math.cos(i) * maxRadius;

    if (Math.abs(startX - endX) > radStep && Math.abs(endY - startY) > radStep) {
      ctx.moveTo(startX, startY);
      ctx.lineTo(user.x + Math.sin(i + 50) * maxRadius, user.y + Math.cos(i + 50) * maxRadius);

      //ctx.lineTo(user.x + Math.sin(i + 2) *...