Mathematic Rays

by Licson Lee

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.3.5/Tween.min.js"></script>
<div id="controls">
  <span>Radius: <input type="number" name="r" value="275" /></span>
  <span>Multiplier: <input type="number" name="mul" value="2" /></span>
  <button>Morph</button>
</div>
<canvas id="surface"></canvas>

CSS

body {
  overflow: hidden;
  margin: 0;
  padding: 0;
  /* background-color: #fff; */
}

#controls {
  position: absolute;
  top: 0;
  left: 0;
  padding: 5px;
}

#controls span {
  margin-right: 10px;
}

#controls input[type=number] {
  width: 30px;
}

JavaScript

var canvas = document.getElementById("surface");
var ctx = canvas.getContext("2d");

// Set dimensions
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// Graphing Parameters
var params = {
  r: 275,
  sam: 400,
  mul: 2
};

// Internal
function draw() {
  var points = [];
  var cx = canvas.width / 2;
  var cy = canvas.height / 2;

	ctx.clearRect(0, 0, canvas.width, canvas.height);

  for (var i = 0; i < params.sam; i++) {
    var p = (i + 1) / params.sam;
    points.push([
      cx + params.r * Math.cos(Math.PI * 2 * p),
      cy + params.r * Math.sin(Math.PI * 2 * p)
    ]);
  }

	ctx.strokeStyle = "#5cd6a1";

  for (i = 0; i < params.sam; i++) {
    var cp = points[i];
    var np = points[Math.floor(params.mul * i) % params.sam];

    if (cp[0] != np[0] && cp[1] != np[1]) {
      ctx.beginPath();
      ctx.moveTo(cp[0], cp[1]);
      ctx.lineTo(np[0], np[1]);
      ctx.stroke();
    }
  }
}

var morphButton = document.querySelector("#controls button");
var rInp = document.querySelector("input[name=r]");
var mInp = document.querySelector("input[name=mul]");

morphButton.addEventListener("click", function(e) {
  new TWEEN.Tween(params)
    .to({
      r: rInp.value,
      mul: mInp.value
    }, 10000)
    .easing(TWEEN.Easing.Circular.In)
    .start();
}, false);

function update() {
  TWEEN.update();
  draw();
  window.requestAnimationFrame(update);
}

update();