<!-- index.html -->
<body>
  <canvas></canvas>
</body>

body {
	width: 100%;
}

canvas {
	display: block;
	margin: 50px auto;
}

const chaikin = ({ points, step, isClosed = false }) => {
	if (step <= 0) {
		return { points, isClosed };
	}

	const result = [];
	

	// use the isClosed variable to determine the max for loop index
	const maxIndex = isClosed ? points.length : points.length - 1;
	for (let i = 0; i < maxIndex; i++) {
		const pointA = points[i];
		const pointB = points[(i + 1) % points.length];

		const [xA, yA] = pointA;
		const [xB, yB] = pointB;

		// 25% in point's x and y
		const x1 = 0.25 * xB + 0.75 * xA;
		const y1 = 0.25 * yB + 0.75 * yA;

		// 75% in point's x and y
		const x2 = 0.75 * xB + 0.25 * xA;
		const y2 = 0.75 * yB + 0.25 * yA;

		result.push([x1, y1]);
		result.push([x2, y2]);
	}

	// NEW! pass the isClosed value to any future calls
	return chaikin({ points: result, step: step - 1, isClosed });
};


// Set up the canvas
var canvas = document.querySelector("canvas");
var context = canvas.getContext("2d");

// set the size to smaller of window width or height
var size = Math.min(window.innerWidth, window.innerHeight);
canvas.width = size - 100;
canvas.height = size - 100;

// draw a gray rectangle covering the entire canvas
context.rect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgba(0,0,0, 0.1)";
context.fill();


// NEW!
    // create the points
    const points = [
      [0, 0],
      [canvas.width, canvas.height * 0.25],
      [0, canvas.height * 0.5],
      [canvas.width, canvas.height * 0.75],
      [0, canvas.height],
    ]

    // draw the original points as a thin black line
    context.beginPath()
    context.lineWidth = 1
    context.moveTo(points[0][0], points[0][1])
    points.forEach(([x, y]) => {
      context.lineTo(x, y)
    })
    context.stroke()

    // draw the chaikin-ed points
    const { points: chaikinPoints } = chaikin({ points, step: 5 })
    context.lineWidth = 5
    context.strokeStyle = "red"
    context.beginPath()
    context.moveTo(chaikinPoints[0][0], chaikinPoints[0][1])
    chaikinPoints.forEach(([x, y]) => {
      context.lineTo(x, y)
    })
    context.stroke()
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.