Javascript 在画布上画花哨的圆圈会产生奇怪的效果

Javascript 在画布上画花哨的圆圈会产生奇怪的效果,javascript,geometry,html5-canvas,drawing,Javascript,Geometry,Html5 Canvas,Drawing,我试图在画布上画一个圆,它的生成过程如下: ,并缩放: 我不确定为什么会发生这种情况,尽管我以前见过这种效果,我怀疑这与部分像素有关(尽管afaict我没有这么做)。在这里可以看到一个工作示例 为了总结代码,我使用了一个函数来画圆。我逐步向内绘制内侧和外侧边缘,同时调整alpha。代码如下所示: function drawCircle(x, y, radius, startAngle, endAngle, antiClockwise, lineWidth, r, g, b, a) { c

我试图在画布上画一个圆,它的生成过程如下:

,并缩放:

我不确定为什么会发生这种情况,尽管我以前见过这种效果,我怀疑这与部分像素有关(尽管afaict我没有这么做)。在这里可以看到一个工作示例

为了总结代码,我使用了一个函数来画圆。我逐步向内绘制内侧和外侧边缘,同时调整alpha。代码如下所示:

function drawCircle(x, y, radius, startAngle, endAngle, antiClockwise, lineWidth, r, g, b, a) {
    c.beginPath(); 

    var w = Math.abs(lineWidth / 2);

    var alphaFactor = a / w;
    var alpha = alphaFactor;

    var outer = radius + w;
    var inner = radius - w;

    // draw centre line
    c.lineWidth = 1;
    c.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
    c.arc(x, y, radius, startAngle, endAngle, true); 
    c.stroke();

    for(i = 0; i < w; i++, inner++, outer--, alpha += alphaFactor) {
        // draw inner
        c.beginPath(); 
        c.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
        c.arc(x, y, inner, startAngle, endAngle, true); 
        c.stroke();

        // draw outer
        c.beginPath(); 
        c.arc(x, y, outer, startAngle, endAngle, true); 
        c.stroke();
    }
};
函数画圈(x,y,半径,星形,端角,逆时针,线宽,r,g,b,a){
c、 beginPath();
var w=数学绝对值(线宽/2);
varα系数=a/w;
varα=α因子;
var外部=半径+w;
var内=半径-w;
//画中心线
c、 线宽=1;
c、 strokeStyle='rgba('+r+'、'+g+'、'+b+'、'+a+');
c、 弧(x,y,半径,星形,端角,真);
c、 笔划();
对于(i=0;i

我相信我可以使用径向渐变来解决这个问题(我认为会更快,具体取决于线条的宽度),但是我想了解为什么会出现上述影响。

我猜这是由于非直线(圆圈包含很多)的抗锯齿/圆整效果造成的。特别是,具有(非常)小的线宽。我的猜测是,这会导致部分重叠的圆线,部分相邻的线,甚至在某些地方留下间隙的线

随着线宽的增加,问题似乎得到了解决:

c.lineWidth = 1.4;

请参阅更新的。

我解决了这个问题,没有画单独的线条,只画了一条带有径向渐变的线条,重新创建了我想要的效果:

这看起来(afaict)更有效,因为它只使用一个填充,而不是多个笔划

在这里可以看到解决方案,而代码非常小:

$(function () {
  draw(document.getElementById('canvas').getContext('2d'));

  function draw(ctx) {
    var radgrad = ctx.createRadialGradient(60, 60, 0, 60, 60, 60);
    radgrad.addColorStop(0.8, 'rgba(255,0,0,0)');
    radgrad.addColorStop(0.85, 'rgba(255,0,0,.6)');
    radgrad.addColorStop(0.9, 'rgba(255,0,0,1)');
    radgrad.addColorStop(0.95, 'rgba(255,0,0,.6)');
    radgrad.addColorStop(1, 'rgba(255,0,0,0)');

    ctx.fillStyle = radgrad;
    ctx.arc(60, 60, 60, 0, 2 * Math.PI, true);
    ctx.fill();
  }
});

我从一个解决方案导出另一个解决方案。

对不起,维格,但这似乎对我不起作用。我仍然在您的JSFIDLE中看到奇怪的(莫尔图案?)人工制品。您是否尝试进一步增加
线宽?