html5 canvas加载圈子图片

时间:2017-06-05 14:38:20

标签: javascript html5 canvas

我正在尝试从HTML5画布中的图像创建加载圈。

以下是百分比为50%时的预期结果:

enter image description here

这是我经过大量测试后所做的事情:(蓝色笔划只是为了看到圆圈,之后会被删除)

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>

如您所见,此处的结果不是例外

enter image description here

有什么问题?

2 个答案:

答案 0 :(得分:4)

首先,您需要正确计算您的中心点:

var X = img.width / 2;
var Y = img.height / 2;

然后你需要以逆时针方向回绕,追踪内半径Radius - 17

ctx.beginPath();
ctx.arc(X, Y, Radius, -quart, current);
ctx.arc(X, Y, Radius - 17, current, -quart, true);
ctx.closePath();

如果您对笔划轮廓不感兴趣,可先移至中心,然后arc

ctx.beginPath();
ctx.moveTo(X, Y);
ctx.arc(X, Y, Radius, -quart, current);
ctx.closePath();

示例:

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>

答案 1 :(得分:2)

&#13;
&#13;
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);
}
&#13;
canvas { border : 2px solid black;}
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;