Square spiral

by Nicolaus Maloney

HTML

<canvas id='c'></canvas>

JavaScript

const width = 500,
      height = 500;
var canvas = new fabric.Canvas('c', {
  width: width,
  height: height,
});
const ctx = canvas.getContext();
ctx.translate(Math.floor(width / 2), 
  Math.floor(height / 2));


const vertex = [
  { x: 0, y: -70 },
  { x: -50, y: 50 },
  { x: 50, y: 50 },
  { x: 70, y: -20 },
];

// This defines the initial state
const initial = {
  iter: 0,
  scale: 1,
  x: vertex[0].x,
  y: vertex[0].y,
};

// This function takes the last state, and return the next state
function getNext(last) {
  const iter = last.iter + 1,
        scale = last.scale * 1.05,
        v = vertex[iter % vertex.length];
  return {
    iter: iter,
    scale: scale,
    x: v.x * scale,
    y: v.y * scale,
  };
}

// This takes last and next, and does the drawing
function draw(last, next) {
  const opts = {
    stroke: `hsl(${(last.iter * 10) % 360}, 100%, 50%)`,
    //stroke: 'hsl(50, 100%, 50%)',
    strokeWidth: 5 * last.scale,
    fill: false,
    strokeLineCap: 'round',
  };
  const path = new fabric.Path(`M ${last.x} ${last.y} ` +
    `L ${next.x} ${next.y}`, opts);    
  canvas.add(path);
}

// This function takes the last state, computes the next state,
// draws, and returns the new state.
function segment(last) {
  const next = getNext(last);
  draw(last, next);
  return next;
}

var last = initial;
for (var i = 0; i <50; ++i) {
  last = segment(last);
}