Skip to content

Instantly share code, notes, and snippets.

@r-i-c-h
Last active August 18, 2023 23:42
Show Gist options
  • Save r-i-c-h/40b101a8a322e4b132dd440f5322d532 to your computer and use it in GitHub Desktop.
Save r-i-c-h/40b101a8a322e4b132dd440f5322d532 to your computer and use it in GitHub Desktop.
HTML Canvas Shape Drawing Functions
/*** Canvas Shape Drawing Functions ***/
// 1. drawStar() - Draw an n-pointed Star w/controls for outer and inner radii - [can make sorta-polygons too]
// 2. drawCircle() - Draw a circle (ctx.arc() wrapper)
// 3A. drawPoly1() - Draw an n-sided Polygon
// 3B. drawPoly2() - Draw an n-sided Polygon
// 3C. drawPoly3() - Draw an n-sided Polygon (controls for initial Rotation in Radians)
/* Assume the following setup: */
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = canvas.clientWidth; // correct for screen distortion
canvas.height = canvas.clientHeight; // correct for screen distortion
/* 1. Draw an N-pointed Star with control of outer and inner radii: */
function drawStar({ cx = 0, cy = 0, numPoints = 5, outerRadius = 100, innerRadius = 50,
lineWidth = 1, stroke = '#FFF', fill = 'transparent' } = {}) {
let rotationBase = Math.PI / 2 * 3;
const rotationIncrement = Math.PI / numPoints;
// set Visual properties
ctx.lineWidth = lineWidth;
ctx.strokeStyle = stroke;
ctx.fillStyle = fill;
ctx.beginPath();
ctx.moveTo(cx, cy - outerRadius); // move to top
for (i = 0; i < numPoints; i++) {
// x = cx + Math.cos(rotationBase) * outerRadius;
// y = cy + Math.sin(rotationBase) * outerRadius;
ctx.lineTo(
(cx + Math.cos(rotationBase) * outerRadius),
(cy + Math.sin(rotationBase) * outerRadius)
);
rotationBase += rotationIncrement;
// x = cx + Math.cos(rotationBase) * innerRadius;
// y = cy + Math.sin(rotationBase) * innerRadius;
ctx.lineTo(
(cx + Math.cos(rotationBase) * innerRadius),
(cy + Math.sin(rotationBase) * innerRadius)
);
rotationBase += rotationIncrement;
}
ctx.lineTo(cx, cy - outerRadius); // back to start
ctx.closePath();
// add the outline
ctx.stroke();
// add the fill
ctx.fill();
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
// 2. Draw a Circle. Really just `context.arc()`
function drawCircle({ cx = 0, cy = 0, radius = 50, strokeColor = '#000', strokeWidth = 2, fill = 'transparent' } = {}) {
// start the path
ctx.beginPath();
// plot out the path
ctx.arc(cx, cy, radius, 0, 2 * Math.PI);
// Stroke & Fill:
ctx.lineWidth = strokeWidth;
ctx.strokeStyle = strokeColor;
ctx.fillStyle = fill;
ctx.stroke();
ctx.fill();
};
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*** --- Three Different Tweaks on drawing an N-gon Polygon --- ***/
// --- VERSION A: --- //
function drawPoly1({ cx = 200, cy = 200, numSides = 3, radius = 100, lineWidth = 1, stroke = '#FFFFFF', fill = 'transparent' } = {}) {
// set Visual properties
ctx.lineWidth = lineWidth;
ctx.strokeStyle = stroke;
ctx.fillStyle = fill;
// start the path
ctx.beginPath();
// move to the first point (at "3 o'clock" position)
ctx.moveTo(cx + radius, cy + 0);
// determine angle of each pie slice based on number of sides
const angle = 2 * Math.PI / numSides;
// for each side, go to a corner.
for (var i = 1; i <= numSides; i++) {
// get the current angle based on where we are in the loop
let currentAngle = i * angle;
// use cosine to get horizontal coordinate
let x = cx + radius * Math.cos(currentAngle);
// use sin to get vertical coordinate
let y = cy + radius * Math.sin(currentAngle);
// go to this point next
ctx.lineTo(x, y);
}
// add the outline
ctx.stroke();
// add the fill
ctx.fill();
};
// ----- VERSION B: ----- //
function drawPoly2({ cx = 200, cy = 200, numSides = 5, radius = 100,
lineWidth = 1, stroke = '#FFFFFF', fill = 'transparent' } = {}){
if (numSides < 3){ return }
const angleIncrement = Math.PI / (numSides/2);
let rotationBase = Math.PI / 2 * 3;
// set Visual properties
ctx.lineWidth = lineWidth;
ctx.strokeStyle = stroke;
ctx.fillStyle = fill;
ctx.beginPath();
ctx.moveTo(cx, cy - radius); // move to top
for (i = 0; i < numSides; i++) {
ctx.lineTo(
(cx + Math.cos(rotationBase) * radius),
(cy + Math.sin(rotationBase) * radius)
);
rotationBase += angleIncrement;
}
ctx.lineTo(cx, cy - radius); // back to start
ctx.closePath();
ctx.stroke();
ctx.fill();
}
// ---- VERSION C: ---- //
function drawPoly3({cx = 200, cy = 200, numSides = 5, radius = 100, initialRotationInRAD = Math.PI * 1.5} = {}) {
if (numSides < 3) return;
const angle = (Math.PI * 2)/numSides;
ctx.save()
ctx.beginPath();
ctx.translate( cx, cy );
ctx.rotate(initialRotationInRAD); // MUST BE IN RADIANS, aka Math.PI * ___
ctx.moveTo( radius, 0 );
for (var i = 1; i < numSides; i++) {
ctx.lineTo( radius * Math.cos(i * angle), radius * Math.sin(i * angle));
}
ctx.closePath();
ctx.stroke()
ctx.restore()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment