Polygons
Draw stars with flexible styling (size, colors, number-of-points).
// Usage:drawStar(75,75,5,50,25,'mediumseagreen','gray',9);drawStar(150,200,8,50,25,'skyblue','gray',3);drawStar(225,75,16,50,20,'coral','transparent',0);drawStar(300,200,16,50,40,'gold','gray',3);
// centerX, centerY: the center point of the star// points: the number of points on the exterior of the star// inner: the radius of the inner points of the star// outer: the radius of the outer points of the star// fill, stroke: the fill and stroke colors to apply// line: the linewidth of the stroke
function drawStar(centerX, centerY, points, outer, inner, fill, stroke, line) { // define the star ctx.beginPath(); ctx.moveTo(centerX, centerY+outer); for (var i=0; i < 2*points+1; i++) { var r = (i%2 == 0)? outer : inner; var a = Math.PI * i/points; ctx.lineTo(centerX + r*Math.sin(a), centerY + r*Math.cos(a)); }; ctx.closePath(); // draw ctx.fillStyle=fill; ctx.fill(); ctx.strokeStyle=stroke; ctx.lineWidth=line; ctx.stroke()}Regular Polygon
Section titled “Regular Polygon”A regular polygon has all sides equal length.
// Usage:drawRegularPolygon(3,25,75,50,6,'gray','red',0);drawRegularPolygon(5,25,150,50,6,'gray','gold',0);drawRegularPolygon(6,25,225,50,6,'gray','lightblue',0);drawRegularPolygon(10,25,300,50,6,'gray','lightgreen',0);
function drawRegularPolygon(sideCount,radius,centerX,centerY,strokeWidth,strokeColor,fillColor,rotationRadians){ var angles=Math.PI*2/sideCount; ctx.translate(centerX,centerY); ctx.rotate(rotationRadians); ctx.beginPath(); ctx.moveTo(radius,0); for(var i=1;i<sideCount;i++){ ctx.rotate(angles); ctx.lineTo(radius,0); } ctx.closePath(); ctx.fillStyle=fillColor; ctx.strokeStyle = strokeColor; ctx.lineWidth = strokeWidth; ctx.stroke(); ctx.fill(); ctx.rotate(angles*-(sideCount-1)); ctx.rotate(-rotationRadians); ctx.translate(-centerX,-centerY);}Render a rounded polygon.
Section titled “Render a rounded polygon.”Creates a path from a set of points [{x:?,y:?},{x:?,y:?},...,{x:?,y:?}] with rounded corners of radius. If the corner angle is too small to fit the radius or the distance between corners does not allow room the corners radius is reduced to a best fit.

Usage Example
var triangle = [ { x: 200, y : 50 }, { x: 300, y : 200 }, { x: 100, y : 200 }];var cornerRadius = 30;ctx.lineWidth = 4;ctx.fillStyle = "Green";ctx.strokeStyle = "black";ctx.beginPath(); // start a new pathroundedPoly(triangle, cornerRadius);ctx.fill();ctx.stroke();Render function
var roundedPoly = function(points,radius){ var i, x, y, len, p1, p2, p3, v1, v2, sinA, sinA90, radDirection, drawDirection, angle, halfAngle, cRadius, lenOut; var asVec = function (p, pp, v) { // convert points to a line with len and normalised v.x = pp.x - p.x; // x,y as vec v.y = pp.y - p.y; v.len = Math.sqrt(v.x * v.x + v.y * v.y); // length of vec v.nx = v.x / v.len; // normalised v.ny = v.y / v.len; v.ang = Math.atan2(v.ny, v.nx); // direction of vec } v1 = {}; v2 = {}; len = points.length; // number points p1 = points[len - 1]; // start at end of path for (i = 0; i < len; i++) { // do each corner p2 = points[(i) % len]; // the corner point that is being rounded p3 = points[(i + 1) % len]; // get the corner as vectors out away from corner asVec(p2, p1, v1); // vec back from corner point asVec(p2, p3, v2); // vec forward from corner point // get corners cross product (asin of angle) sinA = v1.nx * v2.ny - v1.ny * v2.nx; // cross product // get cross product of first line and perpendicular second line sinA90 = v1.nx * v2.nx - v1.ny * -v2.ny; // cross product to normal of line 2 angle = Math.asin(sinA); // get the angle radDirection = 1; // may need to reverse the radius drawDirection = false; // may need to draw the arc anticlockwise // find the correct quadrant for circle center if (sinA90 < 0) { if (angle < 0) { angle = Math.PI + angle; // add 180 to move us to the 3 quadrant } else { angle = Math.PI - angle; // move back into the 2nd quadrant radDirection = -1; drawDirection = true; } } else { if (angle > 0) { radDirection = -1; drawDirection = true; } } halfAngle = angle / 2; // get distance from corner to point where round corner touches line lenOut = Math.abs(Math.cos(halfAngle) * radius / Math.sin(halfAngle)); if (lenOut > Math.min(v1.len / 2, v2.len / 2)) { // fix if longer than half line length lenOut = Math.min(v1.len / 2, v2.len / 2); // ajust the radius of corner rounding to fit cRadius = Math.abs(lenOut * Math.sin(halfAngle) / Math.cos(halfAngle)); } else { cRadius = radius; } x = p2.x + v2.nx * lenOut; // move out from corner along second line to point where rounded circle touches y = p2.y + v2.ny * lenOut; x += -v2.ny * cRadius * radDirection; // move away from line to circle center y += v2.nx * cRadius * radDirection; // x,y is the rounded corner circle center ctx.arc(x, y, cRadius, v1.ang + Math.PI / 2 * radDirection, v2.ang - Math.PI / 2 * radDirection, drawDirection); // draw the arc clockwise p1 = p2; p2 = p3; } ctx.closePath();}

