I'm trying to generate a polygon with circles inside (JS canvas
). Here's a sample expected output:
It's basically a 4-sided polygon (square) with circles next to the vertices. Here is what I tried:
However, I don't get the expected outcome.
Note: I want this to work for any sized polygon and not just a square. Also, stopping the draw()
function to execute gives me a proper square. I believe there's a problem in the draw()
function. Any help is appreciated :)
function draw(x, y, ctx){
ctx.arc(x, y, 4, 0, Math.PI * 2);
ctx.fillStyle = "#283149";
ctx.fill(); // create circle
}
function createPolygon(n){
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext('2d');
ctx.reset();
var size = 60, Xcenter = 80, Ycenter = 80;
ctx.beginPath();
ctx.moveTo (Xcenter size * Math.cos(0), Ycenter size * Math.sin(0));
for (var i = 1; i <= n; i ) {
ctx.lineTo (Xcenter size * Math.cos(i * 2 * Math.PI / n), Ycenter size * Math.sin(i * 2 * Math.PI / n));
draw(Xcenter Math.cos(i * 2 * Math.PI / n), Ycenter Math.sin(i * 2 * Math.PI / n), ctx);
}
ctx.fillStyle = "#00818A"
ctx.fill();
}
<button onclick="createPolygon(4)">Create 4</button>
<canvas id="canvas"></canvas>
CodePudding user response:
Focus on drawing the polygon first. Then you can add the circles relative to the points of the polygon.
const main = () => {
const ctx = document.getElementById('poly').getContext('2d');
Object.assign(ctx.canvas, { width: 350, height: 150 });
Object.assign(ctx, { strokeStyle: 'red', lineWidth: 1 });
drawPolygon(ctx, 60, 75, 6, 50, 0, 5, 10);
drawPolygon(ctx, 180, 75, 4, 50, Math.PI / 4, 10, 25);
drawPolygon(ctx, 290, 75, 3, 50, Math.PI / 3, 2, 20);
};
const drawPolygon = (
ctx,
x,
y,
points,
radius,
rotation = 0,
nodeSize = 0,
nodeInset = 0
) => {
ctx.beginPath();
ctx.moveTo(
x radius * Math.cos(rotation),
y radius * Math.sin(rotation)
);
for (let i = 1; i <= points; i = 1) {
const angle = (i * (2 * Math.PI / points)) rotation;
ctx.lineTo(
x radius * Math.cos(angle),
y radius * Math.sin(angle)
);
}
ctx.stroke();
if (!nodeSize) return;
const dist = radius - nodeInset;
for (let i = 1; i <= points; i = 1) {
const angle = (i * (2 * Math.PI / points)) rotation;
let x1 = x dist * Math.cos(angle);
let y1 = y dist * Math.sin(angle);
ctx.beginPath();
ctx.arc(x1, y1, nodeSize, 0, 2 * Math.PI);
ctx.stroke();
}
};
main();
canvas { background: #FF0; }
<canvas id="poly"></canvas>
Inspired by: How to draw polygons on an HTML5 canvas?
CodePudding user response:
You have to close paths, so you have to use two loops
function draw(x, y, ctx) {
ctx.beginPath();
ctx.arc(x, y, 4, 0, Math.PI * 2);
ctx.fillStyle = "#283149";
ctx.fill(); // create circle
ctx.closePath()
}
function createPolygon(n) {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext('2d');
ctx.reset();
var size = 60,
Xcenter = 80,
Ycenter = 80;
ctx.beginPath();
ctx.moveTo(Xcenter size * Math.cos(0), Ycenter size * Math.sin(0));
for (let i = 1; i <= n; i ) {
ctx.lineTo(Xcenter size * Math.cos(i * 2 * Math.PI / n), Ycenter size * Math.sin(i * 2 * Math.PI / n));
}
ctx.fillStyle = "#00818A"
ctx.fill();
ctx.closePath()
for (let i = 1; i <= n; i ) {
draw(Xcenter Math.cos(i * 2 * Math.PI / n), Ycenter Math.sin(i * 2 * Math.PI / n), ctx);
}
}
<button onclick="createPolygon(4)">Create 4</button>
<canvas id="canvas"></canvas>