Creating a circle of bars with HTML5 canvas, but the space between the bars is uneven

I'm trying to create a circular progress bar (although it will no longer be a bar, right?). Around this cricle there are thin rods perpendicular to the circle. Now the problem is that my code does not generate bars in a uniform interval. Here is the code and image of the result: uneven perpendicular lines to the circle

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 the lines are not smoothing either. You know why? I must also explain that this progress bar has two parts. The outer circle (visible in the provided image) and the inner circle. The outer circle represents the sum of the integer part of the percentage (i.e. 45 to 45.98%), and the inner circle represents the sum of the non-integer part of the percentage (i.e. 98 to 45.98%). Therefore, now you know that intCircle and floatCircle :)

+7
source share
2 answers

You seem to be passing degrees in Math.sin and Math.cos. These functions await radians. For example,

 // i degrees to radians. Math.sin(i * (Math.PI / 180)); 
+5
source

If you look at how close the lines are and then far apart in the regular pattern (five close areas in your example), this gives you a good indication that it is related to your trigger functions. You can see the sine wave in the pattern.

In any case, your math for ray drawing has some errors. Try this simplified example:

 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 barThickness = 2; context.lineWidth = barThickness; context.strokeStyle = circleBackground; var innerRadius = 30; var outerRadius = 80; var center = { x:50, y:50 }; var percentDone = 60; var angleOfPercentDone = percentDone * 360 / 100; //rotate everything -90 degrees angleOfPercentDone -= 90; for(var angle = -90; angle < angleOfPercentDone; angle +=5) { //convert to radians var rad = angle * Math.PI/180; var c = Math.cos(rad); var s = Math.sin(rad); var innerPointX = center.x + (innerRadius * c); var innerPointY = center.y + (innerRadius * s); var outerPointX = center.x + (outerRadius * c); var outerPointY = center.x + (outerRadius * s); context.moveTo(innerPointX, innerPointY); context.lineTo(outerPointX, outerPointY); context.stroke(); } } 

Take a look at the fiddle here: http://jsfiddle.net/DXwrc/

+1
source

All Articles