JSFiddle - React, Tailwind, and code Playground

by not important

HTML

<script src="https://code.createjs.com/easeljs-0.8.0.min.js"></script>
<canvas id="maze" width="400" height="400"></canvas>

CSS

body {
    background-color: #cccccc;
}
canvas {
    background-color: #efefef;
}

CoffeeScript

###
Usage:
  new Visibility
Whenever map data changes:
  loadMap
Whenever light source changes:
  setLightLocation
To calculate the area:
  sweep
###
class Visibility
  constructor: ->
    @segments = []
    @endpoints = []
    @open = []
    @center = new Point 0, 0
    @output = []

  loadMap: (size, margin, blocks, walls) ->
    @segments = []
    @endpoints = []
    @loadEdgeOfMap size, margin
    for {x, y, r} in blocks
      @addSegment x - r, y - r, x - r, y + r
      @addSegment x - r, y + r, x + r, y + r
      @addSegment x + r, y + r, x + r, y - r
      @addSegment x + r, y - r, x - r, y - r
    for {p1, p2} in walls
      @addSegment p1.x, p1.y, p2.x, p2.y

  loadEdgeOfMap: (size, margin) ->
    @addSegment margin, margin, margin, size - margin
    @addSegment margin, size - margin, size - margin, size - margin
    @addSegment size - margin, size - margin, size - margin, margin
    @addSegment size - margin, margin, margin, margin

  addSegment: (x1, y1, x2, y2) ->
    segment = null
    p1 = new EndPoint 0, 0
    p1.segment = segment
    p1.visualize = true
    p2 = new EndPoint 0, 0
    p2.segment = segment
    p2.visualize = false
    segment = new Segment
    p1.x = x1
    p1.y = y1
    p2.x = x2
    p2.y = y2
    p1.segment = segment
    p2.segment = segment
    segment.p1 = p1
    segment.p2 = p2
    segment.d = 0
    @segments.push segment
    @endpoints.push p1
    @endpoints.push p2

  setLightLocation: (x, y) ->
    @center.x = x
    @center.y = y
    for segment in @segments
      dx = 0.5 * (segment.p1.x + segment.p2.x) - x
      dy = 0.5 * (segment.p1.y + segment.p2.y) - y
      segment.d = dx * dx + dy * dy
      segment.p1.angle = Math.atan2 segment.p1.y - y, segment.p1.x - x
      segment.p2.angle = Math.atan2 segment.p2.y - y, segment.p2.x - x
      dAngle = segment.p2.angle - segment.p1.angle
      dAngle += 2 * Math.PI if dAngle <= 0 - Math.PI
      dAngle -= 2 * Math.PI if dAngle > Math.PI
      segment.p1.begin = dAngle > 0
     ...