Multiple circular progress bar becoming active on scrolling down - javascript

I want four different circular progress bar in my webpage which will be placed on one particular div.Upon scrolling at that div I want all of them to be active at the same time and finishes on the specified percentage.
Only one is working fine.How can I do this? Here, is the attached code.
var ctx = document.getElementById('my_canvas').getContext('2d');
var al = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function progressSim() {
diff = ((al / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 5;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText(al + 'K TOURIST', cw * .5, ch * .5 + 2, cw);
ctx.beginPath();
ctx.arc(35, 35, 30, start, diff / 10 + start, false);
/*ctx.arc(200,75,50,0*Math.PI,1.5*Math.PI);*/
ctx.stroke();
if (al >= 50) {
clearTimeout(sim);
// Add scripting here that will run when progress completes
}
al++;
}
var sim = setInterval(progressSim, 50);
<div id="first_progress">
<canvas id="my_canvas" width="70" height="70" style="border:1px dashed #CCC;"></canvas>
</div>
<div id="second_progress">
<canvas id="my_canvas2" width="70" height="70" style="border:1px dashed #CCC;"></canvas>
</div>

it seem you only update one canvas. you need to update both canvas using two different contexts. or you could draw the progress bars into the same but bigger canvas.
this example will not help using four. you need to store different angles and progress you know for each bar but it show how to update the two in the example.
hope it works out. ps - use arrays to store the ctx's and values. much easier that way.
var ctx = document.getElementById('my_canvas').getContext('2d');
var ctx2 = document.getElementById('my_canvas2').getContext('2d');
var al = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function progressSim(ctx, simInx) {
diff = ((al / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 5;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText(al + 'K TOURIST', cw * .5, ch * .5 + 2, cw);
ctx.beginPath();
ctx.arc(35, 35, 30, start, diff / 10 + start, false);
/*ctx.arc(200,75,50,0*Math.PI,1.5*Math.PI);*/
ctx.stroke();
if (al >= 50) {
clearTimeout(simInx == 1 ? sim1 : sim2);
// Add scripting here that will run when progress completes
}
al++;
}
var sim1 = setInterval(progressSim, 50, ctx, 1);
var sim2 = setInterval(progressSim, 50, ctx2, 2);
<div id="first_progress">
<canvas id="my_canvas" width="70" height="70" style="border:1px dashed #CCC;"></canvas>
</div>
<div id="second_progress">
<canvas id="my_canvas2" width="70" height="70" style="border:1px dashed #CCC;"></canvas>
</div>

Related

How do i update canvas using js continuously?

I've got this piece of code that draws a ball and i want to continuously pass in different cooridinates in order to make it move around but when the refresh rate gets way too high, canvas stops updating. How do i force canvas to update and redraw everything with the arguments passed in?
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
function determinePosition(x, y) {
var trueX = x + 120;
var trueY = y + 80;
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
}
while(true){
determinePosition(x, y);
}
<div class="gcircle">
<canvas id="circle" width="240px" height="160"></canvas>
</div>
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
function determinePosition(x, y) {
//clear the canvas
ctx.clearRect(0, 0, c.width, c.height);
var trueX = x + 120;
var trueY = y + 80;
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
}
//set random location for each 0.5 sec
setInterval(function() {
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
determinePosition(x, y);
}, 500)
<div class="gcircle">
<canvas id="circle" width="240px" height="160"></canvas>
</div>
`
Drawing should always happen in a requestAnimationFrame loop. requestAnimationFrame runs at your monitor's refresh rate, so it's the fastest any animation can run. You can set it up like this:
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
var trueX = 0;
var trueY = 0;
function determinePosition(x, y) {
trueX = x + 120;
trueY = y + 80;
}
requestAnimationFrame(function draw() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
requestAnimationFrame(draw);
})
determinePosition(x, y);

HTML5 Canvas multi circle issue

I have this code that is displaying one circle with a % value, and i'm trying to add another circle next to it who displays another % value.
To do so, i have tried to add another JS code who calls the second ID my_canvas2 but the results are one circle with an incremental % value with no ending.
var ctx = document.getElementById('my_canvas1').getContext('2d');
var al = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function progressSim() {
diff = ((al / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 7;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText(al + '%', cw * .5, ch * .5 + 2, cw);
ctx.beginPath();
ctx.arc(80, 80, 70, start, diff / 10 + start, false);
ctx.stroke();
if (al >= 65) {
clearTimeout(sim);
// Add scripting here that will run when progress completes
}
al++;
}
var sim = setInterval(progressSim, 25);
<canvas id="my_canvas1" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
<canvas id="my_canvas2" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
I've seen some similars subjects where the issue was the closing path of the first circle, i've tried so, still the same problem. Thanks for helping.
Try this.
function progressSim(ctx, al, start) {
let cw = ctx.canvas.width;
let ch = ctx.canvas.height;
let diff;
diff = ((al / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 7;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText(al + '%', cw * .5, ch * .5 + 2, cw);
ctx.beginPath();
ctx.arc(80, 80, 70, start, diff / 10 + start, false);
ctx.stroke();
}
function startProgress(canvas_id, progress_int_1, stop_at) {
let ctx = document.getElementById(canvas_id).getContext('2d');
// let start = 4.72;
let al = progress_int_1;
let start = 4.72;
var sim = setInterval(function(){
progressSim(ctx, al, start);
al++;
if (al >= stop_at) {
clearTimeout(sim);
}
}, 25);
}
var progress_int_1 = 0;
var progress_int_2 = 0;
var sim1;
var sim2;
sim1 = startProgress('my_canvas1', progress_int_1, 50);
sim2 = startProgress('my_canvas2', progress_int_2, 80);
<canvas id="my_canvas1" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
<canvas id="my_canvas2" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
You need to isolate your variables if you want to duplicate the functionality. This allows you to have code that is free from conflict.
This function takes in 2 parameters, the ID of your Canvas, and what percentage you want to show it to. diff and start are local variables that do not need to persist in between calls.
function progressSim(id, percent) {
var ctx = document.getElementById(id).getContext('2d'),
cw = ctx.canvas.width,
ch = ctx.canvas.height,
al = 0,
sim = setInterval(progress, 25);
function progress() {
var start = 4.72,
diff = ((al / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 7;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText(al + '%', cw * .5, ch * .5 + 2, cw);
ctx.beginPath();
ctx.arc(80, 80, 70, start, diff / 10 + start, false);
ctx.stroke();
if (al >= percent) {
clearTimeout(sim);
// Add scripting here that will run when progress completes
}
al++;
};
}
progressSim('my_canvas1', 65);
progressSim('my_canvas2', 80);
<canvas id="my_canvas1" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
<canvas id="my_canvas2" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
Very simple solution, I've just copied you code and done a find and replace on it so it can be used for my_canvas2
var ctx = document.getElementById('my_canvas1').getContext('2d');
var al = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function progressSim() {
diff = ((al / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 7;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText(al + '%', cw * .5, ch * .5 + 2, cw);
ctx.beginPath();
ctx.arc(80, 80, 70, start, diff / 10 + start, false);
ctx.stroke();
if (al >= 65) {
clearTimeout(sim);
// Add scripting here that will run when progress completes
}
al++;
}
var sim = setInterval(progressSim, 25);
var ctx2 = document.getElementById('my_canvas2').getContext('2d');
var al2 = 0;
var start2 = 4.72;
var cw2 = ctx2.canvas.width;
var ch2 = ctx2.canvas.height;
var diff2;
function progresssim2() {
diff2 = ((al2 / 100) * Math.PI * 2 * 10).toFixed(2);
ctx2.clearRect(0, 0, cw2, ch2);
ctx2.lineWidth = 7;
ctx2.fillStyle = '#09F';
ctx2.strokeStyle = "#09F";
ctx2.textal2ign = 'center';
ctx2.fillText(al2 + '%', cw2 * .5, ch2 * .5 + 2, cw2);
ctx2.beginPath();
ctx2.arc(80, 80, 70, start2, diff2 / 10 + start2, false);
ctx2.stroke();
if (al2 >= 45) {
clearTimeout(sim2);
// Add scripting here that will run when progress completes
}
al2++;
}
var sim2 = setInterval(progresssim2, 25);
<canvas id="my_canvas1" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
<canvas id="my_canvas2" width="170" height="170" style="border:1px dashed #CCC;"></canvas>
Other on here may have a more eloquent solution

calculate circumference with given radius

I am trying to calculate and display the circumference by retrieving the already defined radius from the given code of a drawn circle. Is it the way I typed out the formula wrong or does it need to be in the same script section?
function draw() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
}
}
function calculatecircumference() {
var circumference = ((2) * (Math.Pi) * (R));
}
document.getElementById("Circumference").innerHTML = circumference;
<!Doctype>
<html>
<body onload="draw();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
<p>Circumference: <span id="Circumference"></span></p>
</html>
Actually the math PI is wrong....you have written Math.Pi
var circumference = ((2) * (Math.Pi) * (R));
but in actual it is Math.PI
var circumference = ((2) * (Math.PI) * (R));
Hence it Returns a NaN for a radius of 45 ..
Check the working below code.... also you need to call the calculatecircumference function..and pass the Radius as param
function draw() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
calculatecircumference(R);
}
}
function calculatecircumference(R) {
var circumference = ((2) * (Math.PI) * (R));
document.getElementById("Circumference").innerHTML = circumference;
}
<body onload="draw();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
<p>Circumference: <span id="Circumference"></span></p>
You have three problems:
First, you need to give calculatecircumference() scope to access R. This can be done by calling calculatecircumference() from within draw() and passing it through as a function parameter. You'll also need to tell calculatecircumference() that its function parameter should be assigned to the local variable R, by writing it as calculatecircumference(R).
Second, document.getElementById("Circumference").innerHTML does not have access to the scope of circumference. Simply run the line document.getElementById("Circumference").innerHTML = circumference line inside caluclatecircumference().
Finally, you called Math.Pi instead of Math.PI in calculatecircumference(). The PI must be uppercase.
Correcting these three issues fixes the problem, as can be seen below:
function draw() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
calculatecircumference(R);
}
}
function calculatecircumference(R) {
var circumference = ((2) * (Math.PI) * (R));
document.getElementById("Circumference").innerHTML = circumference;
}
<!Doctype>
<html>
<body onload="draw();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
<p>Circumference: <span id="Circumference"></span></p>
</html>
Hope this helps! :)

Radial chart using js and html5 canvas element

I'm trying to make circular chart on html5 canvas el.
(function () {
var ctx = document.getElementById('canvas').getContext('2d');
var counter = 0;
var start = 4.72;
var cW = ctx.canvas.width;
var cH = ctx.canvas.height;
var diff;
var maxVal = 44;
function progressChart(){
diff = ((counter / 100) * Math.PI*2*10).toFixed(2);
ctx.clearRect(0, 0, cW, cH);
ctx.lineWidth = 15;
ctx.fillStyle = '#ff883c';
ctx.strokeStyle = '#ff883c';
ctx.textAlign = 'center';
ctx.font = '25px Arial';
ctx.fillText(counter+'%', cW*.5, cH*.55, cW);
ctx.beginPath();
ctx.arc(70, 70, 60, start, diff/10+start, false);
ctx.stroke();
if(counter >= maxVal){
clearTimeout(drawChart);
}
counter++;
}
var drawChart = setInterval(progressChart, 20);
})();
<canvas id="canvas" width="140" height="140"></canvas>
I want to add doughnut background before browser start drawing fill chart. Unfortunately, I need to use ctx.clearRect() because I've got strange visual effect. Is any way to combine this two rings?
Yes, there is a way and that is, drawing another arc for doughnut background, before drawing fill chart.
Also, you should use requestAnimationFrame() instead of setInterval(), for better efficiency.
var ctx = document.getElementById('canvas').getContext('2d');
var counter = 0;
var start = 4.72;
var cW = ctx.canvas.width;
var cH = ctx.canvas.height;
var diff;
var maxVal = 44;
var rAF;
function progressChart() {
diff = ((counter / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cW, cH);
ctx.lineWidth = 15;
ctx.fillStyle = '#ff883c';
ctx.textAlign = 'center';
ctx.font = '25px Arial';
ctx.fillText(counter + '%', cW * .5, cH * .55, cW);
// doughnut background
ctx.beginPath();
ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
ctx.strokeStyle = '#ddd';
ctx.stroke();
// fill chart
ctx.beginPath();
ctx.arc(70, 70, 60, start, diff / 10 + start, false);
ctx.strokeStyle = '#ff883c';
ctx.stroke();
if (counter >= maxVal) {
cancelAnimationFrame(rAF);
return;
}
counter++;
rAF = requestAnimationFrame(progressChart);
}
progressChart();
<canvas id="canvas" width="140" height="140"></canvas>

HTML5 Canvas - Changing a square into a circle

On an HTML5 canvas I can't find a method to make colored circles. I've been consulting this as a reference.
Here is my current attempt
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillRect(20, 20, 100, 100);
ctx.lineJoin = "round";
ctx.lineWidth = "cornerRadius";
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
(Also on jsFiddle: http://jsfiddle.net/kvnm21r1/1/)
I've tried using the canvas arc method, which creates a circle, but doesn't color it.
I can't use the border-radius property, because ctx is not an element.
Is there any way, I can transform my squares into circles?
Thanks in advance.
You can use quadratic curves to "round-out" the straight lines of your square until they form a circle.
// change sideCount to the # of poly sides desired
//
var sideCount = 4;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 2;
ctx.fillStyle = randomColor();
var PI2 = Math.PI * 2;
var cx = 150;
var cy = 150;
var radius = 100;
var xx = function (a) {
return (cx + radius * Math.cos(a));
}
var yy = function (a) {
return (cy + radius * Math.sin(a));
}
var lerp = function (a, b, x) {
return (a + x * (b - a));
}
var sides = [];
for (var i = 0; i < sideCount; i++) {
sides.push(makeSide(i, sideCount));
}
var percent = 0;
var percentDirection = 0.50;
$("#toShape").click(function () {
percentDirection = -0.50;
})
$("#toCircle").click(function () {
percentDirection = 0.50;
})
animate();
// functions
function animate() {
requestAnimationFrame(animate);
drawSides(percent);
percent += percentDirection;
if (percent > 100) {
percent = 100;
}
if (percent < 0) {
percent = 0;
}
}
function drawSides(pct, color) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (pct == 100) {
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, PI2);
ctx.closePath();
ctx.fill();
} else {
ctx.beginPath();
ctx.moveTo(sides[0].x0, sides[0].y0);
for (var i = 0; i < sideCount; i++) {
var side = sides[i];
var cpx = lerp(side.midX, side.cpX, pct / 100);
var cpy = lerp(side.midY, side.cpY, pct / 100);
ctx.quadraticCurveTo(cpx, cpy, side.x2, side.y2);
}
ctx.fill();
}
}
function makeSide(n, sideCount) {
var sweep = PI2 / sideCount;
var sAngle = sweep * (n - 1);
var eAngle = sweep * n;
var x0 = xx(sAngle);
var y0 = yy(sAngle);
var x1 = xx((eAngle + sAngle) / 2);
var y1 = yy((eAngle + sAngle) / 2);
var x2 = xx(eAngle);
var y2 = yy(eAngle);
var dx = x2 - x1;
var dy = y2 - y1;
var a = Math.atan2(dy, dx);
var midX = lerp(x0, x2, 0.50);
var midY = lerp(y0, y2, 0.50);
var cpX = 2 * x1 - x0 / 2 - x2 / 2;
var cpY = 2 * y1 - y0 / 2 - y2 / 2;
return ({
x0: x0,
y0: y0,
x2: x2,
y2: y2,
midX: midX,
midY: midY,
cpX: cpX,
cpY: cpY,
color: randomColor()
});
}
function randomColor() {
return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="toShape">Animate to Shape</button>
<button id="toCircle">Animate to Circle</button><br>
<canvas id="canvas" width=300 height=300></canvas>
JSfiddle with a circle
To draw a circle you'll need to draw an arc and have a starting angle and an ending angle. So you'll have to use Pi and define a radius.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
Avoid w3schools.com whenever possible. Refer to sites like MDN instead.
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
ctx.beginPath();
var radius = 50; // Arc radius
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI*2; // End point on circle
ctx.arc(150, 75, radius, startAngle, endAngle, true);
ctx.fill();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">

Categories