I'm trying to create a circular progressbar(though it wouldn't be a bar anymore, would it?). Around this cricle there are thin bars perpendicular to the circle. Now the problem is, my code doesn't generate there bars in an even spacing. Here's the code and an image of the result:
function MH5PB(canvasId, //the id of the canvas to draw the pb on
value, //a float value, representing the progress(ex: 0.3444)
background, //the background color of the pb(ex: "#ffffff")
circleBackground, //the background color of the bars in the circles
integerColor, //the color of the outer circle(or the int circle)
floatColor //the color of the inner circle(or the float circle)
)
{
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var radius = Math.min(canvasWidth, canvasHeight) / 2;
var numberOfBars = 72;
var barThickness = 2;
//margin from the borders, and also the space between the two circles
var margin = parseInt(radius / 12.5) >= 2 ? parseInt(radius / 12.5) : 2;
//the thickness of the int circle and the float circle
var circleThickness = parseInt((radius / 5) * 2);
//the outer radius of the int circle
var intOuterRadius = radius - margin;
//the inner radius of the int circle
var intInnerRadius = radius - margin - circleThickness;
//the outer radius of the float circle
var floatOuterRadius = intOuterRadius - margin - circleThickness;
//the inner radius of the float circle
var floatInnerRadius = floatOuterRadius - circleThickness;
//draw a bar, each degreeStep degrees
var intCircleDegreeStep = 5;
// ((2 * Math.PI * intOuterRadius) / (barThickness + 10)) //
// this area is the total number of required bars //
// to fill the intCircle.1px space between each bar//
var floatCircleDegreeStep = 360 / ((2 * Math.PI * floatOuterRadius) / (barThickness + 10));
context.lineWidth = barThickness;
context.strokeStyle = circleBackground;
//draw the bg of the outer circle
for(i = 90; i < 450; i+=intCircleDegreeStep)
{
//since we want to start from top, and move cw, we have to map the degree
//in the loop
cxOuter = Math.floor(intOuterRadius * Math.cos(i) + radius);
cyOuter = Math.floor(intOuterRadius * Math.sin(i) + radius);
cxInner = Math.floor(intInnerRadius * Math.cos(i) + radius);
cyInner = Math.floor(intInnerRadius * Math.sin(i) + radius);
context.moveTo(cxOuter, cyOuter);
context.lineTo(cxInner, cyInner);
context.stroke();
}
}
EDIT: Oh, and also the lines aren't anti-aliased. Do you know why? I should also explain that this progressbar consists of two parts. An outer circle (visible in the provided image) and an inner circle. The outer circle is the amount of the integer part of the percentage (i.e. 45 in 45.98%) and the inner circle is the amount of the not integer part of the percentage (i.e. 98 in 45.98%). Hence you now know what intCircle and floatCircle are :)
It appears you are passing degrees to Math.sin and Math.cos. These functions expect radians. For example,
// i degrees to radians.
Math.sin(i * (Math.PI / 180));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With