JSFiddle - React, Tailwind, and code Playground

HTML

<canvas></canvas>

JavaScript

const cnv = document.querySelector('canvas');
cnv.width = 600;
cnv.height = 600;
const ctx = cnv.getContext('2d');

drawSpline(ctx, createPoints(100, 100, 70, 4, 40), 0.5);

function createPoints(cx, cy, r, n, d) {
  const points = [];
	for (let i = 0; i < n; i++) 
    points.push(
    	r * Math.cos(Math.PI * 2 / n * i) + Math.round(Math.random() * d - d / 2) + cx,
      r * Math.sin(Math.PI * 2 / n * i) + Math.round(Math.random() * d - d / 2) + cy
    );
  return points;
}


function drawSpline(ctx, pts, t) {
  ctx.lineWidth = 4;
  ctx.save();
  var cp = []; // array of control points, as x0,y0,x1,y1,...
  var n = pts.length;

  //   Append and prepend knots and control points to close the curve
  pts.push(pts[0], pts[1], pts[2], pts[3]);
  pts.unshift(pts[n - 1]);
  pts.unshift(pts[n - 1]);
  
  for (var i = 0; i < n; i += 2) {
    cp = cp.concat(getControlPoints(pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], t));
  }
  cp = cp.concat(cp[0], cp[1]);
  
  ctx.beginPath();
  ctx.moveTo(pts[2], pts[3]);
  for (var i = 2; i < n + 2; i += 2) {
    ctx.bezierCurveTo(cp[2 * i - 2], cp[2 * i - 1], cp[2 * i], cp[2 * i + 1], pts[i + 2], pts[i + 3]);
  }
  ctx.closePath();
	ctx.fill()
  ctx.restore();
}

function getControlPoints(x0, y0, x1, y1, x2, y2, t) {
  //  x0,y0,x1,y1 are the coordinates of the end (knot) pts of this segment
  //  x2,y2 is the next knot -- not connected here but needed to calculate p2
  //  p1 is the control point calculated here, from x1 back toward x0.
  //  p2 is the next control point, calculated here and returned to become the 
  //  next segment's p1.
  //  t is the 'tension' which controls how far the control points spread.

  //  Scaling factors: distances from this knot to the previous and following knots.
  var d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
  var d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));

  var fa = t * d01 / (d01 + d12);
  var fb = t - fa;

  var p1x = x1 + fa *...