I'm trying to create a loading circle from an image in HTML5 canvas.
Here's the result I expect when percentage is at 50%:
here's what I've done after a lot of tests: (the blue stroke is just to see the circle, it'll be removed after)
var img = new Image();
img.onload = draw;
img.src = "http://i.imgur.com/HVJBZ1L.png";
var canvas = document.getElementsByTagName("canvas")[0];
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext("2d");
function draw() {
ctx.globalAlpha = 0.5
ctx.drawImage(img, 0, 0);
ctx.globalAlpha = 1;
var X = 50;
var Y = 50;
var Radius = img.width / 2;
var end = 40;
var start = 0;
var PI2 = Math.PI * 2;
var quart = Math.PI / 2;
var pct = 50 / 100;
var extent = (end - start) * pct;
var current = (end - start) / 100 * PI2 * pct - quart;
var pattern = ctx.createPattern(img, 'no-repeat');
ctx.beginPath();
ctx.arc(X, Y, Radius, -quart, current);
ctx.closePath();
ctx.fillStyle=pattern;
ctx.fill();
ctx.strokeStyle = "blue";
ctx.stroke();
}
<canvas></canvas>
as you can see, the result here isn't as excepted
What is wrong?
The arc() method creates an arc/curve (used to create circles, or parts of circles). Tip: To create a circle with arc(): Set start angle to 0 and end angle to 2*Math. PI. Tip: Use the stroke() or the fill() method to actually draw the arc on the canvas.
Importing images into a canvas is basically a two step process: Get a reference to an HTMLImageElement object or to another canvas element as a source. It is also possible to use images by providing a URL. Draw the image on the canvas using the drawImage() function.
To draw arcs or circles, we use the arc() or arcTo() methods. Draws an arc which is centered at (x, y) position with radius r starting at startAngle and ending at endAngle going in the given direction indicated by counterclockwise (defaulting to clockwise).
First, you need to correctly calculate your center point:
var X = img.width / 2;
var Y = img.height / 2;
Then you need to circle back in counter-clockwise direction tracing the inner radius Radius - 17
:
ctx.beginPath();
ctx.arc(X, Y, Radius, -quart, current);
ctx.arc(X, Y, Radius - 17, current, -quart, true);
ctx.closePath();
If you aren't interested in the stroke outline, you could move to the center first, and then arc
:
ctx.beginPath();
ctx.moveTo(X, Y);
ctx.arc(X, Y, Radius, -quart, current);
ctx.closePath();
Example:
var img = new Image();
img.onload = draw;
img.src = "http://i.imgur.com/HVJBZ1L.png";
var canvas = document.getElementsByTagName("canvas")[0];
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext("2d");
function draw() {
ctx.globalAlpha = 0.5
ctx.drawImage(img, 0, 0);
ctx.globalAlpha = 1;
var X = img.width / 2;
var Y = img.height / 2;
var Radius = img.width / 2;
var end = 40;
var start = 0;
var PI2 = Math.PI * 2;
var quart = Math.PI / 2;
var pct = 50 / 100;
var extent = (end - start) * pct;
var current = (end - start) / 100 * PI2 * pct - quart;
var pattern = ctx.createPattern(img, 'no-repeat');
ctx.beginPath();
ctx.moveTo(X, Y);
ctx.arc(X, Y, Radius, -quart, current);
ctx.closePath();
ctx.fillStyle = pattern;
ctx.fill();
}
<canvas></canvas>
const img = new Image();
img.src = "http://i.imgur.com/HVJBZ1L.png";
img.onload = imageLoaded;
var W,H; // width and height when image ready
const ctx = canvas.getContext("2d");
// define the distance of the progress 0- 100
const min = 0;
const max = 100;
var pattern;
var radius;
// get pattern, radius canvas size from image ans start animation
function imageLoaded(){
requestAnimationFrame(mainLoop);
W = this.width;
H = this.height;
pattern = ctx.createPattern(this, 'no-repeat');
radius = W / 2;
canvas.width = W;
canvas.height = H;
}
// draw the background and forground images
// amount is the amount of progress. amount >= min amount <= max
function draw(amount) {
ctx.globalAlpha = 0.5
ctx.drawImage(img, 0, 0);
ctx.globalAlpha = 1;
ctx.fillStyle=pattern;
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.arc( // draw inside circle CCW
W/2,
H/2,
radius - 17,
((amount - min) / (max-min)) * Math.PI * 2 - Math.PI / 2,
-Math.PI / 2,
true
);
ctx.arc( // draw outer circle CW
W/2,
H/2,
radius,
-Math.PI / 2,
((amount - min) / (max-min)) * Math.PI * 2 - Math.PI / 2
);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
// animate the thing.
function mainLoop(time){
ctx.clearRect(0,0,canvas.width,canvas.height);
draw((time / 50) % max);
requestAnimationFrame(mainLoop);
}
canvas { border : 2px solid black;}
<canvas id="canvas"></canvas>
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