All about canvas arcTo

What arcTo does and how to use it to draw polygons with rounded corners.

by Doguleez

HTML

<canvas id="myCanvas" width="900" height="1200"></canvas>

JavaScript

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.font = '12pt sansserif';

// "current point" 
var ct = {
  x: 100,
  y: 160
}

// control point 1
var cp1 = {
  x: 180,
  y: 40
};

// control point 2
var cp2 = {
  x: 250,
  y: 140
};

drawAngle(ct, cp1, cp2, 20);

ctx.fillText('arcTo rounds the angle', 70, 200);
ctx.fillText('formed by the current point', 70, 225);
ctx.fillText('(red) and two control points', 70, 250);
ctx.fillText('(green, blue), according to ', 70, 275);
ctx.fillText('a given radius (here, 20).', 70, 300);

ctx.translate(300, 0);

drawAngle(ct, cp1, cp2, 150);

ctx.fillText('Note that it will look weird if', 50, 265);
ctx.fillText('the rounding radius doesn\'t', 50, 290);
ctx.fillText('fit into the angle', 50, 315);

ctx.fillText('I added the grey lines ', 250, 40);
ctx.fillText('to show the underlying,', 250, 65);
ctx.fillText('unrounded angles.', 250, 90);

ctx.translate(-220, 350);
ctx.lineWidth = 2;

// arcTo is ideal for drawing polygons with rounded corners
// first a rectangle

// the underlying rectangle

var vertices = [{
  x: 0,
  y: 0
}, {
  x: 250,
  y: 0
}, {
  x: 250,
  y: 200
}, {
  x: 0,
  y: 200
}];

ctx.strokeStyle = 'lightgrey';
drawPolygon(vertices);

// the rectangle with rounded corners
ctx.strokeStyle = 'black';
drawRoundedPolygon(vertices, 50);

ctx.fillText('arcTo is ideal for drawing rounded polygons.',
  100, 250);

// now a more general polygon
ctx.translate(300, 25);
vertices = [{
  x: 0,
  y: 0
}, {
  x: 100,
  y: 50
}, {
  x: 200,
  y: -20
}, {
  x: 250,
  y: 200
}, {
  x: 50,
  y: 150
}];

ctx.strokeStyle = 'lightgrey';
drawPolygon(vertices);

// the rectangle with rounded corners
ctx.strokeStyle = 'black';
drawRoundedPolygon(vertices, 30);


function drawAngle(ct, cp1, cp2, radius) {
  ctx.save();
  ctx.lineWidth = 2;

  // underlying angle
  ctx.strokeStyle = 'lightgrey';
  ctx.beginPath();

  ctx.moveTo(ct.x, ct.y);
  ctx.lineTo(cp1.x, cp1.y);
  ctx.lineTo(cp2.x,...