HTML5画布加载圆形图像

9
我正试图在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个回答

4

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

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

然后您需要逆时针方向绕回追踪内半径半径 - 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>


2

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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接