Radial chart using js and html5 canvas element - javascript

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>

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

how to spin and stop wheel has custom position with jquery

this i my code.
I am using this CSS code I want to spin my wheel:
now i want to spin and stop wheel has custom position with jquery?
like lucky wheeel in https://hockey-empire.com/
i'm a newbie, please help me :)
var color = ['#FF0000','#FF0000','#FF0000','#FF0000','#FF0000','#FF0000'];//list color
var label = ['googluck', '10%','Thank','10$','5$','10$',"20%"]; //list lable name
var slices = color.length;
var sliceDeg = 360/slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width/2; // center
var slices = color.length;
var sliceDeg = 360 / slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width;// size
var center = width / 2; // center
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.lineWidth = 2;
ctx.strokeStyle = "#ffffff";
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
ctx.stroke();
}
function drawPoin(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, 50, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = '18px Arial';
ctx.shadowColor = "#000000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 20;
ctx.fillText(text, center - 25, 10);
ctx.restore();
}
for (var i = 0; i < slices; i++) {
drawSlice(deg, color[i]);
drawPoin(deg, '#fff');
drawText(deg + sliceDeg / 2, label[i]);
deg += sliceDeg;
}
<canvas id="canvas" width="500" height="500"></canvas>
image
i want spin like it :)
You can do it using setInterval method by changing the degree in each interval, you can modify incrementer value and time setInterval to suit your speed and also break the interval using some flags or conditions
window.setInterval(draw, 1);
var color = ['#FF0000','#FF0000','#FF0000','#FF0000','#FF0000','#FF0000'];//list color
var label = ['googluck', '10%','Thank','10$','5$','10$',"20%"]; //list lable name
var slices = color.length;
var sliceDeg = 360/slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width/2; // center
var slices = color.length;
var sliceDeg = 360 / slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width;// size
var center = width / 2; // center
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.lineWidth = 2;
ctx.strokeStyle = "#ffffff";
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
ctx.stroke();
}
function drawPoin(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, 50, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = '18px Arial';
ctx.shadowColor = "#000000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 20;
ctx.fillText(text, center - 25, 10);
ctx.restore();
}
function draw() {
deg++;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < slices; i++) {
drawSlice(deg, color[i]);
drawPoin(deg, '#fff');
drawText(deg + sliceDeg / 2, label[i]);
deg += sliceDeg;
}
if(deg == 0) {
degreeMultiplier = 0;
deg=-90;
}
}
<canvas id="canvas" width="500" height="500"></canvas>

how to reload a circular progress bar

I made some web searching about canvas and how to create a circular progress bar and i got this. I made some changes to the pieces of code that I found online but i can't reload the circular path again. By reload I mean, when the circle is full ( a perfect circle) I would like to draw it again. In other words, I would like to repeat the procedure of drawing the circle again after a full spin is completed. I tried to clear the whole canvas when my variable trigger is greater than 100, but no success. Any ideas?
here's the code
function draw() {
var c=document.getElementById("prog");
var ctx=c.getContext("2d");
var time = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function justdoit(){
diff = ((time / 100) * Math.PI*2*10);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 10;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText( time+'s', cw*.5, ch*.5+2, cw);
ctx.beginPath();
ctx.arc(75, 75, 30, start, diff/10+start, false);
ctx.stroke();
if(trigger >= 100){
ctx.clearRect(0, 0, cw, ch);
}
time++;
}
var trigger = setInterval(justdoit, 1000);
}
<button onclick="draw()"> draw </button>
<canvas id="prog"></canvas>
The function draw is called on a button element with an attribute onclick="draw()";
I am not sure if this is what you are after, I have separated the timer out for the position of the circle so you can reset the position to 0 every 100 seconds without reseting the time.
The important things I have changed:
Added a new variable called pos.
var pos = 0;
Changed the diff calculation to use pos.
diff = ((pos / 100) * Math.PI*2*10);
Changed the if statement to set pos back to 0 every 100 seconds and clear the circle.
if(time % 100 == 0){
pos = 0;
ctx.clearRect(0, 0, cw, ch);
}
Increment pos with time.
pos++;
Also I have decreased the timer in the example so we don't have to wait a long time to see. - Change back to 1000 for 1 second interval setInterval(justdoit, 100);
function draw() {
var c=document.getElementById("prog");
var ctx=c.getContext("2d");
var time = 0;
var pos = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function justdoit(){
diff = ((pos / 100) * Math.PI*2*10);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 10;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText( time+'s', cw*.5, ch*.5+2, cw);
ctx.beginPath();
ctx.arc(75, 75, 30, start, diff/10+start, false);
ctx.stroke();
if(time % 100 == 0){
pos = 0;
ctx.clearRect(0, 0, cw, ch);
}
time++;
pos++;
}
var trigger = setInterval(justdoit, 100);
}
<button onclick="draw()"> draw </button>
<canvas id="prog"></canvas>
The last 'if' block is wrong. Use this instead:
if(time >= 100){
ctx.clearRect(0, 0, cw, ch);
time = 0;
}
This will just make the thing repeat itself over and over again. Hopefully this was what you wanted.
The complete code is here (I speeded the thing up by changing the step wait time from '1000' to '10 in the second line from the bottom):
function draw() {
var c=document.getElementById("prog");
var ctx=c.getContext("2d");
var time = 0;
var start = 4.72;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
var diff;
function justdoit(){
diff = ((time / 100) * Math.PI*2*10);
ctx.clearRect(0, 0, cw, ch);
ctx.lineWidth = 10;
ctx.fillStyle = '#09F';
ctx.strokeStyle = "#09F";
ctx.textAlign = 'center';
ctx.fillText( time+'s', cw*.5, ch*.5+2, cw);
ctx.beginPath();
ctx.arc(75, 75, 30, start, diff/10+start, false);
ctx.stroke();
if(time >= 100){
ctx.clearRect(0, 0, cw, ch);
time = 0;
}
time++;
}
var trigger = setInterval(justdoit, 10);
}
<button onclick="draw()"> draw </button>
<canvas id="prog"></canvas>

Can't change size of Canvas Item

I am trying to change the size of my canvas element.
var canvas = document.getElementById('timer'),
ctx = canvas.getContext('2d'),
sec = this.length,
countdown = sec;
ctx.lineWidth = 10;
ctx.strokeStyle = "#F60017";
ctx.strokeStyle = "#000000";
var startAngle = 0,
time = 0,
intv = setInterval(function () {
ctx.clearRect(0, 0, 200, 200);
var endAngle = (Math.PI * time * 2 / sec);
ctx.arc(65, 35, 30, startAngle, endAngle, false);
startAngle = endAngle;
ctx.stroke();
countdown--;
if (++time > sec, countdown == 0) {
clearInterval(intv), $("#timer, #counter").show();
}
}, 10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<canvas id="timer"></canvas>
If I change ctx.clearRect(0, 0, 200, 200); it still remains 200x200
The clearRect() is used to remove the previous drawing before a new one is drawn. I added new variables: x, y and size. Along with ctx.lineWidth, this should be enough to change the appearance.
var canvas = document.getElementById('timer'),
ctx = canvas.getContext('2d'),
sec = 100,
countdown = sec;
var x = 60,
y = 60
size = 30; // change me
ctx.lineWidth = 25;
ctx.strokeStyle = "#F60017";
ctx.strokeStyle = "#000000";
var startAngle = 0,
time = 0,
intv = setInterval(function () {
console.log('interval');
ctx.clearRect(0, 0, 200, 200);
var endAngle = (Math.PI * time * 2 / sec);
ctx.arc(x, y, size, startAngle, endAngle, false);
startAngle = endAngle;
ctx.stroke();
countdown--;
if (++time > sec && countdown <0) {
clearInterval(intv), $("#timer, #counter").show();
}
}, 10);
<canvas id="timer"></canvas>

Categories