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>
Related
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);
I have pie chart like grow/shrink animation, but in the middle of it, there is showing up fill circle on one frame, how can I get rid of it?
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var increase = Math.PI * 2 / 100;
var max = Math.PI * 2;
var angle = 0;
var start = false;
setInterval(function() {
ctx.clearRect(0, 0, 32, 32);
ctx.fillStyle = '#F00A0A';
ctx.beginPath();
if (start) {
ctx.arc(16, 16, 12, angle, 0);
} else {
ctx.arc(16, 16, 12, 0, angle);
}
ctx.lineTo(16, 16);
ctx.fill();
angle += increase;
if (angle >= max) {
angle = 0;
start = !start;
}
}, 20);
<canvas width="32" height="32"/>
I've tried this:
if (angle !== 0) {
ctx.beginPath();
if (start) {
ctx.arc(16, 16, 12, angle, 0);
} else {
ctx.arc(16, 16, 12, 0, angle);
}
ctx.lineTo(16, 16);
ctx.fill();
}
but this don't work, when arc change side it show full circle for one frame.
The easiest solution is to just offset your angle ever so slightly.
That way circle isn't "complete" when you change drawing mode:
var canvas = document.body.appendChild(document.createElement('canvas'));
var canvasSize = canvas.width = canvas.height = 100;
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#F00A0A';
var increase = Math.PI * 2 / 100;
var max = Math.PI * 2;
var angle = 0.0000001;
var start = false;
function update() {
ctx.clearRect(0, 0, canvasSize, canvasSize);
ctx.beginPath();
ctx.arc(canvasSize / 2, canvasSize / 2, canvasSize / 3, angle, 0, start);
ctx.lineTo(canvasSize / 2, canvasSize / 2);
ctx.fill();
angle += increase;
if (angle >= max) {
angle = angle % max;
start = !start;
}
requestAnimationFrame(update);
}
update();
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>
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>
How to add another stroke with a different color and length into the same circle?
This script use Mootools lib. Can it be converted in pure JavaScript or jQuery?
fiddle: http://jsfiddle.net/xc4xnzcq/1/
Thanks :)
// SVG stuff
var ctx = document.id('counter').getContext('2d');
var circ = Math.PI * 2;
var quart = Math.PI / 2;
ctx.beginPath();
ctx.strokeStyle = '#ff00ab';
ctx.lineCap = 'square';
ctx.closePath();
ctx.fill();
ctx.lineWidth = 10;
var imd = ctx.getImageData(0, 0, 160, 160);
var draw = function(current) {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
}
var myFx = new Fx({
duration: 5500,
transition: 'bounce:out',
onStep: function(step){
draw(step / 100);
}
});
myFx.set = function(now){
var ret = Fx.prototype.set.call(this, now);
this.fireEvent('step', now);
return ret;
};
myFx.start(0, 80);
Drawing a second path seems to work fine for me.
// SVG stuff
var ctx = document.id('counter').getContext('2d');
var circ = Math.PI * 2;
var quart = Math.PI / 2;
var imd = ctx.getImageData(0, 0, 160, 160);
var draw = function(current) {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.strokeStyle = '#ff00ab';
ctx.lineCap = 'square';
ctx.lineWidth = 10;
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = '#bb00bc';
ctx.lineCap = 'square';
ctx.lineWidth = 5;
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
}
var myFx = new Fx({
duration: 5500,
transition: 'bounce:out',
onStep: function(step){
draw(step / 100);
}
});
myFx.set = function(now){
var ret = Fx.prototype.set.call(this, now);
this.fireEvent('step', now);
return ret;
};
myFx.start(0, 80);