How to get coordinates of every circle from this Canvas - javascript

I need to create a pattern where 5 circles connected by lines to a middle main circle.
So I have created dynamically by rotating in some certain angle. Now I need each and every circle's x and y axis coordinates for capturing the click events on every circle.
Please help me how to find out of coordinates of every circle?
var canvas, ctx;
function createCanvasPainting() {
canvas = document.getElementById('myCanvas');
if (!canvas || !canvas.getContext) {
return false;
}
canvas.width = 600;
canvas.height = 600;
ctx = canvas.getContext('2d');
ctx.strokeStyle = '#B8D9FE';
ctx.fillStyle = '#B8D9FE';
ctx.translate(300, 250);
ctx.arc(0, 0, 50, 0, Math.PI * 2); //center circle
ctx.stroke();
ctx.fill();
drawChildCircles(5);
fillTextMultiLine('Test Data', 0, 0);
drawTextInsideCircles(5);
}
function drawTextInsideCircles(n) {
let ang_unit = Math.PI * 2 / n;
ctx.save();
for (var i = 0; i < n; i++) {
ctx.rotate(ang_unit);
//ctx.moveTo(0,0);
fillTextMultiLine('Test Data', 200, 0);
ctx.strokeStyle = '#B8D9FE';
ctx.fillStyle = '#B8D9FE';
}
ctx.restore();
}
function drawChildCircles(n) {
let ang_unit = Math.PI * 2 / n;
ctx.save();
for (var i = 0; i < n; ++i) {
ctx.rotate(ang_unit);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,0);
ctx.arc(200, 0, 40, 0, Math.PI * 2);
let newW = ctx.fill();
ctx.stroke();
}
ctx.restore();
}
function fillTextMultiLine(text, x, y) {
ctx.font = 'bold 13pt Calibri';
ctx.textAlign = 'center';
ctx.fillStyle = "#FFFFFF";
// Defining the `textBaseline`…
ctx.textBaseline = "middle";
var lineHeight = ctx.measureText("M").width * 1.2;
var lines = text.split("\n");
for (var i = 0; i < lines.length; ++i) {
// console.log(lines);
if (lines.length > 1) {
if (i == 0) {
y -= lineHeight;
} else {
y += lineHeight;
}
}
ctx.fillText(lines[i], x, y);
}
}
createCanvasPainting();
<canvas id="myCanvas"></canvas>

The problem here is that you are rotating the canvas matrix and your circles are not aware of their absolute positions.
Why don't you use some simple trigonometry to determine the center of your circle and the ending of the connecting lines ?
function lineToAngle(ctx, x1, y1, length, angle) {
angle *= Math.PI / 180;
var x2 = x1 + length * Math.cos(angle),
y2 = y1 + length * Math.sin(angle);
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
return {x: x2, y: y2};
}
Ref: Finding coordinates after canvas Rotation
After that, given the xy center of your circles, calculating if a coord is inside a circle, you can apply the following formula:
Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)) < r
Ref: Detect if user clicks inside a circle

Related

Circle is not connecting through lines properly using Canvas

I am trying to create 11 circles which connected through lines with a middle circle. I am trying to draw the circles. Here I have doing some r&d but I could not able to make lines. Please help me to complete this.
var canvas, ctx;
var circlePoints = [];
function createCanvasPainting() {
canvas = document.getElementById('myCanvas');
if (!canvas || !canvas.getContext) {
return false;
}
canvas.width = 600;
canvas.height = 600;
ctx = canvas.getContext('2d');
ctx.strokeStyle = '#B8D9FE';
ctx.fillStyle = '#B8D9FE';
ctx.translate(300, 250);
ctx.arc(0, 0, 50, 0, Math.PI * 2); //center circle
ctx.stroke();
ctx.fill();
var angleRotate = 0;
for (var i=0; i<11; i++) {
if (i > 0) {
angleRotate += 32.72;
}
lineToAngle(ctx, 0, 0, 200, angleRotate);
}
}
function lineToAngle(ctx, x1, y1, length, angle) {
angle *= Math.PI / 180;
var x2 = x1 + length * Math.cos(angle),
y2 = y1 + length * Math.sin(angle);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineWidth = 1;
ctx.arc(x2, y2, 40, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
circlePoints.push({x: x2, y: y2});
// console.log(circlePoints);
}
createCanvasPainting();
<canvas id="myCanvas"></canvas>
Here is my JSFiddle Link
See below I removed all the "noise" from your code.
Just circles with lines connecting with a middle circle.
canvas = document.getElementById('myCanvas');
canvas.width = canvas.height = 200;
ctx = canvas.getContext('2d');
ctx.lineWidth = 1;
ctx.translate(99, 99);
angle = 0;
function draw() {
ctx.clearRect(-99, -99, 200, 200);
ctx.beginPath();
ctx.arc(0, 0, 35 + Math.cos(angle / 3000), 0, Math.PI * 2);
ctx.stroke();
ctx.fill();
for (var i = 0; i < 11; i++) {
a = angle * Math.PI / 180;
x = 80 * Math.cos(a)
y = 80 * Math.sin(a)
ctx.beginPath();
ctx.arc(x, y, 18, 0, Math.PI * 2);
ctx.moveTo(x, y);
ctx.lineTo(0, 0);
ctx.fill();
ctx.stroke();
angle += 32.7;
}
}
setInterval(draw, 10);
<canvas id="myCanvas"></canvas>

Rotate a triangle in the cente of itself

I want to rotate a triangle in the center of itself.
I have this script:
var ctx = canvas.getContext('2d');
var angle = 30;
setInterval(rotate, 50);
function rotate() {
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(150, 150); // x, y
ctx.rotate(angle * Math.PI / 180)
ctx.fillStyle = "yellow";
var path=new Path2D();
path.moveTo(-50+50,-25);
path.lineTo(-50,-50-25);
path.lineTo(-50-50,-25);
ctx.fill(path);
ctx.restore();
angle++;
}
<canvas id="canvas" width="1800" height="700"></canvas>
It rotates it, but not in the center. I want it to look like this:
var ctx = canvas.getContext('2d');
setInterval(rotate, 50);
var angle = 30;
function rotate() {
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(50, 50);
ctx.rotate(angle * Math.PI / 180)
ctx.fillStyle = "green";
ctx.fillRect(-25, -25, 50, 50);
ctx.restore();
angle++;
}
<canvas id="canvas" width="1800" height="700"></canvas>
I think, I just have to get the width and hight of the triangle and devive it by 2, but I don't know, how to do that.
Thx for every answer!
What you want is the centroid of your shape.
var ctx = canvas.getContext('2d');
var angle = 30;
var points = [
{x:0, y:-25},
{x:-50, y:-75},
{x:-100, y:-25}
];
// first sum it all
var sums = points.reduce( (sum, point) => {
sum.x += point.x;
sum.y += point.y;
return sum;
}, {x:0, y:0});
// we want the mean
var centroid = {
x: sums.x / points.length,
y: sums.y / points.length
};
rotate();
function rotate() {
ctx.setTransform(1,0,0,1,0,0);
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// general position in canvas
ctx.translate(100, 100);
// move to centroid of our triangle
ctx.translate(centroid.x, centroid.y); // x, y
// rotate
ctx.rotate(angle * Math.PI / 180)
// go back to our initial position
ctx.translate(-centroid.x, -centroid.y); // x, y
ctx.fillStyle = "yellow";
var path=new Path2D();
path.moveTo(points[0].x, points[0].y);
path.lineTo(points[1].x, points[1].y);
path.lineTo(points[2].x, points[2].y);
ctx.fill(path);
// demo only
ctx.beginPath();
ctx.arc(centroid.x, centroid.y, 50, 0, Math.PI*2)
ctx.stroke();
angle++;
requestAnimationFrame( rotate );
}
<canvas id="canvas" width="1800" height="700"></canvas>
Create the Path once
You are using a Path2D object which is reusable.
If you create the triangle already centered on its origin (or any path for that matter) it is then trivial to rotate it.
Reusing the path object is also a lot quicker if you have a lot to render.
The function to creates a path from a set of points. It automatically centers the path to its own origin (defined by the mean of its points)
const point = (x, y) => ({x, y});
function createPath(...points) {
var cx = 0; cy = 0;
for (const p of points) {
cx += p.x;
cy += p.y;
}
cx /= points.length;
cy /= points.length;
const path = new Path2d;
for (const p of points) { path.lineTo(p.x - cx, p.y - cy); }
path.closePath();
return path;
}
To create the triangle
const triangle = createPath(point(0,-25), point(-50,-75), point(-100,-25));
Then you can render it rotated about its own origin with
function drawPath(path, x, y, angle) {
ctx.setTransform(1, 0, 0, 1, x, y);
ctx.rotate(angle);
ctx.stroke(path);
}
Example
Shows how to create various shapes centered on their means. Each shape is a path created once and then rendered as needed.
const point = (x, y) => ({x, y});
const triangle = createPath(point(0,-25), point(-50,-75), point(-100,-25));
const rectangle = createPath(point(0,-25), point(-50,-25), point(-50,-125), point(0,-125));
const thing = createPath(point(0,-12), point(-25,-12), point(-25,-62), point(0,-62), point(22,-35));
function drawPath(path, x, y, angle) {
ctx.setTransform(1, 0, 0, 1, x, y);
ctx.rotate(angle);
ctx.stroke(path);
}
function drawPath_V2(path, x, y, scale, angle, strokeStyle, fillStyle) {
ctx.setTransform(scale, 0, 0, scale, x, y);
ctx.rotate(angle);
fillStyle && (ctx.fillStyle = fillStyle, ctx.fill(path));
strokeStyle && (ctx.strokeStyle = strokeStyle, ctx.stroke(path));
}
function renderLoop(time) {
ctx.clearRect(0, 0, can.width, can.height);
const scale = Math.sin(time / 500) * 0.2 + 1.0;
const scale2 = Math.cos(time / 1000) * 0.4 + 1.0;
drawPath(triangle, 75, 74, time / 1000 * Math.PI); //360 every 2 second
// scale path
drawPath_V2(rectangle, 125, 125, scale, time / 2000 * Math.PI, "black"); //360 every 4 second
// fill scale path
drawPath_V2(thing, 125, 100, scale2, time / 3000 * Math.PI, "", "black");
ctx.setTransform(1, 0, 0, 1, 0, 0);
requestAnimationFrame(renderLoop);
}
requestAnimationFrame(renderLoop);
const can = Object.assign(document.createElement("canvas"), {width: 200, height: 200});
document.body.appendChild(can);
const ctx = can.getContext("2d");
function createPath(...points) {
var cx = 0; cy = 0;
for (const p of points) {
cx += p.x;
cy += p.y;
}
cx /= points.length;
cy /= points.length;
const path = new Path2D;
for (const p of points) {
path.lineTo(p.x - cx , p.y - cy);
}
path.closePath();
return path;
}

Canvas line drawing animation

I am new learner of animation using HTML5 Canvas. I am struggling to create line drawing animation in a canvas with desired length of a line.
Here is the code
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight;
var x = 200;
var y = 200;
draw();
update();
function draw() {
context.beginPath();
context.moveTo(100, 100);
context.lineTo(x, y);
context.stroke();
}
function update() {
context.clearRect(0, 0, width, height);
x = x + 1;
y = y + 1;
draw();
requestAnimationFrame(update);
}
html,
body {
margin: 0px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
The line is growing on Canvas in the above code. But how to achieve that the 200px wide line and animate the movement in x and y direction. And the same animation with multiple lines using for loop and move them in different direction.
Check the reference image ....
Need to move each line in a different direction
Thanks in advance
Find a new reference image which i want to achieve
You need to either use transforms or a bit of trigonometry.
Transforms
For each frame:
Reset transforms and translate to center
Clear canvas
Draw line from center to the right
Rotate x angle
Repeat from step 2 until all lines are drawn
var ctx = c.getContext("2d");
var centerX = c.width>>1;
var centerY = c.height>>1;
var maxLength = Math.min(centerX, centerY); // use the shortest direction for demo
var currentLength = 0; // current length, for animation
var lenStep = 1; // "speed" of animation
function render() {
ctx.setTransform(1,0,0,1, centerX, centerY);
ctx.clearRect(-centerX, -centerY, c.width, c.height);
ctx.beginPath();
for(var angle = 0, step = 0.1; angle < Math.PI * 2; angle += step) {
ctx.moveTo(0, 0);
ctx.lineTo(currentLength, 0);
ctx.rotate(step);
}
ctx.stroke(); // stroke all at once
}
(function loop() {
render();
currentLength += lenStep;
if (currentLength < maxLength) requestAnimationFrame(loop);
})();
<canvas id=c></canvas>
You can use transformation different ways, but since you're learning I kept it simple in the above code.
Trigonometry
You can also calculate the line angles manually using trigonometry. Also here you can use different approaches, ie. if you want to use delta values, vectors or brute force using the math implicit.
For each frame:
Reset transforms and translate to center
Clear canvas
Calculate angle and direction for each line
Draw line
var ctx = c.getContext("2d");
var centerX = c.width>>1;
var centerY = c.height>>1;
var maxLength = Math.min(centerX, centerY); // use the shortest direction for demo
var currentLength = 0; // current length, for animation
var lenStep = 1; // "speed" of animation
ctx.setTransform(1,0,0,1, centerX, centerY);
function render() {
ctx.clearRect(-centerX, -centerY, c.width, c.height);
ctx.beginPath();
for(var angle = 0, step = 0.1; angle < Math.PI * 2; angle += step) {
ctx.moveTo(0, 0);
ctx.lineTo(currentLength * Math.cos(angle), currentLength * Math.sin(angle));
}
ctx.stroke(); // stroke all at once
}
(function loop() {
render();
currentLength += lenStep;
if (currentLength < maxLength) requestAnimationFrame(loop);
})();
<canvas id=c></canvas>
Bonus animation to play around with (using the same basis as above):
var ctx = c.getContext("2d", {alpha: false});
var centerX = c.width>>1;
var centerY = c.height>>1;
ctx.setTransform(1,0,0,1, centerX, centerY);
ctx.lineWidth = 2;
ctx.strokeStyle = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 16;
function render(time) {
ctx.globalAlpha=0.77;
ctx.fillRect(-500, -500, 1000, 1000);
ctx.globalAlpha=1;
ctx.beginPath();
ctx.rotate(0.025);
ctx.shadowColor = "hsl(" + time*0.1 + ",100%,75%)";
ctx.shadowBlur = 16;
for(var angle = 0, step = Math.PI / ((time % 200) + 50); angle < Math.PI * 2; angle += step) {
ctx.moveTo(0, 0);
var len = 150 + 150 * Math.cos(time*0.0001618*angle*Math.tan(time*0.00025)) * Math.sin(time*0.01);
ctx.lineTo(len * Math.cos(angle), len * Math.sin(angle));
}
ctx.stroke();
ctx.globalCompositeOperation = "lighter";
ctx.shadowBlur = 0;
ctx.drawImage(ctx.canvas, -centerX, -centerY);
ctx.drawImage(ctx.canvas, -centerX, -centerY);
ctx.globalCompositeOperation = "source-over";
}
function loop(time) {
render(time);
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
body {margin:0;background:#222}
<canvas id=c width=640 height=640></canvas>
Here is what I think you are describing...
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = 400,
height = canvas.height = 220,
xcenter = 200,
ycenter = 110,
radius = 0,
radiusmax = 100,
start_angle1 = 0,
start_angle2 = 0;
function toRadians(angle) {
return angle * (Math.PI / 180);
}
function draw(x1, y1, x2, y2) {
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
}
function drawWheel(xc, yc, start_angle, count, rad) {
var inc = 360 / count;
for (var angle = start_angle; angle < start_angle + 180; angle += inc) {
var x = Math.cos(toRadians(angle)) * rad;
var y = Math.sin(toRadians(angle)) * rad;
draw(xc - x, yc - y, xc + x, yc + y);
}
}
function update() {
start_angle1 += 0.1;
start_angle2 -= 0.1;
if(radius<radiusmax) radius++;
context.clearRect(0, 0, width, height);
drawWheel(xcenter, ycenter, start_angle1, 40, radius);
drawWheel(xcenter, ycenter, start_angle2, 40, radius);
requestAnimationFrame(update);
}
update();
};
html,
body {
margin: 0px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
This is one that is a variable length emerging pattern. It has a length array element for each spoke in the wheel that grows at a different rate. You can play with the settings to vary the results:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;
var xcenter = width/4;
var ycenter = height/2;
var radius;
var time;
if(width>height) {
radius = height*0.4;
}
else {
radius = width*0.4;
}
var start_angle1 = 0;
var start_angle2 = 0;
function toRadians (angle) {
return angle * (Math.PI / 180);
}
function draw(x1,y1,x2,y2) {
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.stroke();
}
var radmax=width;
var rads = [];
var radsinc = [];
function drawWheel(xc,yc,start_angle,count,rad) {
var inc = 360/count;
var i=0;
for(var angle=start_angle; angle < start_angle+180; angle +=inc) {
var x = Math.cos(toRadians(angle)) * rads[rad+i];
var y = Math.sin(toRadians(angle)) * rads[rad+i];
draw(xc-x,yc-y,xc+x,yc+y);
rads[rad+i] += radsinc[i];
if(rads[rad+i] > radmax) rads[rad+i] = 1;
i++;
}
}
function update() {
var now = new Date().getTime();
var dt = now - (time || now);
time = now;
start_angle1 += (dt/1000) * 10;
start_angle2 -= (dt/1000) * 10;
context.clearRect(0,0,width,height);
drawWheel(xcenter,ycenter,start_angle1,50,0);
drawWheel(xcenter,ycenter,start_angle2,50,50);
requestAnimationFrame(update);
}
function init() {
for(var i=0;i<100;i++) {
rads[i] = 0;
radsinc[i] = Math.random() * 10;
}
}
window.onload = function() {
init();
update();
};
html, body {
margin: 0px;
}
canvas {
width:100%;
height:200px;
display: block;
}
<canvas id="canvas"></canvas>

Circle won't be drawn on canvas

Hi I try to make an animation. A circle should run from right to left. Now the problem is that no circle become drawed in the canvas. I check in chromes developer tool the console log but there was no error. Have anyone a idea what the mistake is?
window.onload = window.onresize = function() {
var C = 1; // canvas width to viewport width ratio
var el = document.getElementById("myCanvas");
var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var canvasWidth = viewportWidth * C;
var canvasHeight = viewportHeight;
el.style.position = "fixed";
el.setAttribute("width", canvasWidth);
el.setAttribute("height", canvasHeight);
var x = canvasWidth / 100;
var y = canvasHeight / 100;
var ballx = canvasWidth / 100;
var n;
window.ctx = el.getContext("2d");
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// draw triangles
function init() {
ballx;
return setInterval(main_loop, 1000);
}
function drawcircles() {
function getRandomElement(array) {
if (array.length == 0) {
return undefined;
}
return array[Math.floor(Math.random() * array.length)];
}
var circles = [
'#FFFF00',
'#FF0000',
'#0000FF'
];
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, x * 5, 0, 2 * Math.PI, false);
ctx.fillStyle = JSON.stringify(getRandomElement(circles));
ctx.fill();
ctx.closePath;
}
function draw() {
var counterClockwise = false;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
//first halfarc
ctx.beginPath();
ctx.arc(x * 80, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath;
//second halfarc
ctx.beginPath();
ctx.arc(x * 50, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath;
//third halfarc
ctx.beginPath();
ctx.arc(x * 20, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath;
// draw stop button
ctx.beginPath();
ctx.moveTo(x * 87, y * 2);
ctx.lineTo(x * 87, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x * 95, y * 2);
ctx.lineTo(x * 95, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.closePath;
//circle
}
function update() {
ballx -= 0.1;
if (ballx < 0) {
ballx = -radius;
}
}
function main_loop() {
drawcircles();
draw();
update();
}
init();
function initi() {
console.log('init');
// Get a reference to our touch-sensitive element
var touchzone = document.getElementById("myCanvas");
// Add an event handler for the touchstart event
touchzone.addEventListener("mousedown", touchHandler, false);
}
function touchHandler(event) {
// Get a reference to our coordinates div
var can = document.getElementById("myCanvas");
// Write the coordinates of the touch to the div
if (event.pageX < x * 50 && event.pageY > y * 10) {
ballx += 1;
} else if (event.pageX > x * 50 && event.pageY > y * 10) {
ballx -= 1;
}
console.log(event, x, ballx);
draw();
}
initi();
draw();
}
<div id="gameArea">
<canvas id="myCanvas"></canvas>
</div>
Your call to draw() after calling drawcircles() has a ctx.clearRect - this clears the canvas (including the just drawn circles).
Moving drawcircles(); to after draw(); in main_loop will make the circle appear. Note that you have to wait for a bit for the circle to be drawn within the visible area.

How to draw polygons on an HTML5 canvas?

I need to know how to draw polygons on a canvas. Without using jQuery or anything like that.
Create a path with moveTo and lineTo (live demo):
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(100,50);
ctx.lineTo(50, 100);
ctx.lineTo(0, 90);
ctx.closePath();
ctx.fill();
from http://www.scienceprimer.com/drawing-regular-polygons-javascript-canvas:
The following code will draw a hexagon. Change the number of sides to create different regular polygons.
var ctx = document.getElementById('hexagon').getContext('2d');
// hexagon
var numberOfSides = 6,
size = 20,
Xcenter = 25,
Ycenter = 25;
ctx.beginPath();
ctx.moveTo (Xcenter + size * Math.cos(0), Ycenter + size * Math.sin(0));
for (var i = 1; i <= numberOfSides;i += 1) {
ctx.lineTo (Xcenter + size * Math.cos(i * 2 * Math.PI / numberOfSides), Ycenter + size * Math.sin(i * 2 * Math.PI / numberOfSides));
}
ctx.strokeStyle = "#000000";
ctx.lineWidth = 1;
ctx.stroke();
#hexagon { border: thin dashed red; }
<canvas id="hexagon"></canvas>
//poly [x,y, x,y, x,y.....];
var poly=[ 5,5, 100,50, 50,100, 10,90 ];
var canvas=document.getElementById("canvas")
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(poly[0], poly[1]);
for(let item=2 ; item < poly.length-1 ; item+=2 ){ctx.lineTo( poly[item] , poly[item+1] )}
ctx.closePath();
ctx.fill();
//create and fill polygon
CanvasRenderingContext2D.prototype.fillPolygon = function (pointsArray, fillColor, strokeColor) {
if (pointsArray.length <= 0) return;
this.moveTo(pointsArray[0][0], pointsArray[0][1]);
for (var i = 0; i < pointsArray.length; i++) {
this.lineTo(pointsArray[i][0], pointsArray[i][1]);
}
if (strokeColor != null && strokeColor != undefined)
this.strokeStyle = strokeColor;
if (fillColor != null && fillColor != undefined) {
this.fillStyle = fillColor;
this.fill();
}
}
//And you can use this method as
var polygonPoints = [[10,100],[20,75],[50,100],[100,100],[10,100]];
context.fillPolygon(polygonPoints, '#F00','#000');
Here is a function that even supports clockwise/anticlockwise drawing do that you control fills with the non-zero winding rule.
Here is a full article on how it works and more.
// Defines a path for any regular polygon with the specified number of sides and radius,
// centered on the provide x and y coordinates.
// optional parameters: startAngle and anticlockwise
function polygon(ctx, x, y, radius, sides, startAngle, anticlockwise) {
if (sides < 3) return;
var a = (Math.PI * 2)/sides;
a = anticlockwise?-a:a;
ctx.save();
ctx.translate(x,y);
ctx.rotate(startAngle);
ctx.moveTo(radius,0);
for (var i = 1; i < sides; i++) {
ctx.lineTo(radius*Math.cos(a*i),radius*Math.sin(a*i));
}
ctx.closePath();
ctx.restore();
}
// Example using the function.
// Define a path in the shape of a pentagon and then fill and stroke it.
context.beginPath();
polygon(context,125,125,100,5,-Math.PI/2);
context.fillStyle="rgba(227,11,93,0.75)";
context.fill();
context.stroke();
In addition to #canvastag, use a while loop with shift I think is more concise:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var poly = [5, 5, 100, 50, 50, 100, 10, 90];
// copy array
var shape = poly.slice(0);
ctx.fillStyle = '#f00'
ctx.beginPath();
ctx.moveTo(shape.shift(), shape.shift());
while(shape.length) {
ctx.lineTo(shape.shift(), shape.shift());
}
ctx.closePath();
ctx.fill();
You can use the lineTo() method same as:
var objctx = canvas.getContext('2d');
objctx.beginPath();
objctx.moveTo(75, 50);
objctx.lineTo(175, 50);
objctx.lineTo(200, 75);
objctx.lineTo(175, 100);
objctx.lineTo(75, 100);
objctx.lineTo(50, 75);
objctx.closePath();
objctx.fillStyle = "rgb(200,0,0)";
objctx.fill();
if you not want to fill the polygon use the stroke() method in the place of fill()
You can also check the following: http://www.authorcode.com/draw-and-fill-a-polygon-and-triangle-in-html5/
thanks
For the people looking for regular polygons:
function regPolyPath(r,p,ctx){ //Radius, #points, context
//Azurethi was here!
ctx.moveTo(r,0);
for(i=0; i<p+1; i++){
ctx.rotate(2*Math.PI/p);
ctx.lineTo(r,0);
}
ctx.rotate(-2*Math.PI/p);
}
Use:
//Get canvas Context
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.translate(60,60); //Moves the origin to what is currently 60,60
//ctx.rotate(Rotation); //Use this if you want the whole polygon rotated
regPolyPath(40,6,ctx); //Hexagon with radius 40
//ctx.rotate(-Rotation); //remember to 'un-rotate' (or save and restore)
ctx.stroke();
To make a simple hexagon without the need for a loop, Just use the beginPath() function. Make sure your canvas.getContext('2d') is the equal to ctx if not it will not work.
I also like to add a variable called times that I can use to scale the object if I need to.This what I don't need to change each number.
// Times Variable
var times = 1;
// Create a shape
ctx.beginPath();
ctx.moveTo(99*times, 0*times);
ctx.lineTo(99*times, 0*times);
ctx.lineTo(198*times, 50*times);
ctx.lineTo(198*times, 148*times);
ctx.lineTo(99*times, 198*times);
ctx.lineTo(99*times, 198*times);
ctx.lineTo(1*times, 148*times);
ctx.lineTo(1*times,57*times);
ctx.closePath();
ctx.clip();
ctx.stroke();
Let's do that with HTML and get that down to this:
<!DOCTYPE html>
<html>
<head>
<title> SVG hexagon </title>
</head>
<body>
<svg width="300" height="110" >
<polygon point="50 3, 100 28, 100 75, 50 100, 3 75, 3 25" stroke="red" fill="lime" stroke-width="5"/>
</svg>
</body>
</html>
var ctx = document.getElementById('hexagon').getContext('2d');
// hexagon
var numberOfSides = 4,
size = 25,
Xcenter = 40,
Ycenter = 40;
ctx.beginPath();
ctx.moveTo (Xcenter + size * Math.cos(0), Ycenter + size * Math.sin(0));
for (var i = 1; i <= numberOfSides;i += 1) {
ctx.lineTo (Xcenter + size * Math.cos(i * 2 * Math.PI / numberOfSides), Ycenter + size * Math.sin(i * 2 * Math.PI / numberOfSides));
}
ctx.strokeStyle = "#000000";
ctx.lineWidth = 1;
ctx.stroke();
#hexagon { border: thin dashed red; }
<canvas id="hexagon"></canvas>

Categories

Resources