在画布中使用fill()的问题 - 不合逻辑的行为

时间:2014-03-12 18:13:28

标签: javascript html5-canvas

我正在尝试使用画布和JavaScript来学习如何绘制/填充不同的形状,但我的形状根本没有按照我想要的方式填充。我的HTML文档正文就是这么简单的一行:

<canvas id="canvas1" width="500" height="500"></canvas>

我的JavaScript文件看起来像这样:

function draw() {

    var canvas1 = document.getElementById('canvas1');

    if(canvas1.getContext) {
        var ctx = canvas1.getContext('2d');
        var gradient = ctx.createLinearGradient(0, 0, 50, 0);
        gradient.addColorStop(0, "blue");
        gradient.addColorStop(1, "white");

        ctx.beginPath();
        ctx.moveTo(25,25);
        ctx.lineTo(100, 25);
        ctx.stroke();

        ctx.moveTo(25, 50);
        ctx.bezierCurveTo(25, 50, 50, 80, 75, 60)
        ctx.fillStyle = "black";
        ctx.fill();

        ctx.beginPath();
        ctx.moveTo(75, 100);
        ctx.arc(50, 100, 25, 0, Math.PI*2, true);
        ctx.fillStyle = "black";
        ctx.fill();

        ctx.beginPath();                        
    ctx.fillStyle = gradient;
    ctx.arc(75, 150, 25, 0, Math.PI*2, true);
    ctx.fill();

    }
}

但这是结果:

http://i57.tinypic.com/63tx02.png http://oi57.tinypic.com/63tx02.jpg

我不明白。我尝试用其他颜色填充我的第二个圆圈,这很好用。如果我删除最后一个“ctx.beginPath();”我的第一个圆圈以渐变绘制。但是我不能通过更改代码的位置或其他东西来使我的第二个圆圈上的错误相同。我发现的每一个指南都告诉我,据我所知,这应该有效。

2 个答案:

答案 0 :(得分:1)

使用绝对位置定义渐变,因此如果您在渐变定义的区域之外绘制圆圈,它将显示为透明而不是填充。

无需关闭路径,fill()方法将close it implicit为您,但只需确保渐变中的坐标覆盖您要填充的区域。

您可以创建一个通用的包装函数,它可以填充位置和颜色(根据需要进行调整),而不是计算每次需要填充圆弧的时间:

<强> A demo here

/**
 * Fills a circle with a two-color gradient.
 * @param {Number} cx - center X
 * @param {Number} cy - center Y
 * @param {Number} radius - radius
 * @param {String} col1 - start color as CSS color string
 * @param {String} col2 - end color as CSS color string
 * @param {Boolean} [horiz=false] - Set true for horizontal gradient
*/
function fillCircle(cx, cy, radius, col1, col2, horiz) {

    var x = cx - radius,
        y = cy - radius,
        d = radius * 2,
        gradient;

    if (horiz) {
        gradient = ctx.createLinearGradient(x, 0, x+d, d);
    }
    else {
        gradient = ctx.createLinearGradient(0, y, 0, y+d);
    }

    gradient.addColorStop(0, col1);
    gradient.addColorStop(1, col2);

    ctx.fillStyle = gradient;
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, 2*Math.PI);
    ctx.fill();
}

然后就这样使用它:

fillCircle(200, 200, 70, 'yellow', 'red');

此处的最后一个标志是可选的,如果设置为true,则生成水平渐变。

答案 1 :(得分:0)

使用ctx.closePath();在你想要的每个单独的形状/线之后完成。

    ctx.beginPath();
    ctx.moveTo(25, 50);
    ctx.bezierCurveTo(25, 50, 50, 80, 75, 60)
    ctx.strokeStyle = "black";
    ctx.stroke();
    ctx.closePath();

需要使用与画布上的形状匹配的坐标来设置渐变。 梯度从0,0开始,

 var gradient = ctx.createLinearGradient(0, 0, 50, 0);

但你的圈位于25,50。使渐变坐标与圆坐标相同。

http://jsfiddle.net/bC75t/1/