画布弧形和渐变填充

时间:2016-06-27 18:48:21

标签: html5 canvas

我有以下源代码:

HTML:

<canvas id="main" width="500" height="500" style="border:1px solid black;"></canvas>

JavaScript的:

function myRnd(val)
{
    return parseInt(Math.random() * val);
}

function rndCircles() {
    var maxCircles = 30;

    for (var r = 1; r <= maxCircles; r++) {
        var c = document.getElementById("main");
        var x = myRnd(c.clientWidth);
        var y = myRnd(c.clientHeight);
        var radius = parseInt(Math.random() * 30);

        var ctx = c.getContext("2d");
        // Create gradient
        var grd = ctx.createRadialGradient(75, 50, 5, 90, 60, 100);
        grd.addColorStop(0, 'rgb(' + myRnd(255) + ', ' + myRnd(255) + ',' + myRnd(255) + ')');
        grd.addColorStop(1, 'white');

        ctx.beginPath();

        ctx.arc(x, y, radius, 0, 2 * Math.PI,false);
        // Fill with gradient
        ctx.fillStyle = grd;
        ctx.fill();
        ctx.lineWidth = 5;
        //ctx.strokeStyle = '#003300';
        ctx.stroke();
    }
}

rndCircles();

我无法在Chrome上看到每个弧都填充了不同的颜色/渐变。为什么?我错过了什么吗?

这里小提琴: https://jsfiddle.net/j9wst2yd/

1 个答案:

答案 0 :(得分:2)

渐变将在定义时使用初始位置和半径,这意味着远离它的弧最终将变为完全白色(或者外部颜色将是什么)。

您可以使用翻译而不是为弧设置位置来解决此问题。

只需要进行一些调整 -

根据原点(0,0)创建渐变:

var grd = ctx.createRadialGradient(0, 0, 5, 0, 0, 100);
// ...

然后用平移替换设置弧位置,这里绝对使用setTransform()代替(translate()会累积,迫使你在之后反转翻译,这样性能更高):

ctx.setTransform(1,0,0,1, x, y);               // two last = translation
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI,false);   // draw at origin

要重置回正常(单位矩阵),只需为setTransform()设置(0,0):

ctx.setTransform(1, 0, 0, 1, 0, 0);

根据需要进行调整。

&#13;
&#13;
function myRnd(val)
{
    return parseInt(Math.random() * val);
}
function rndCircles() {
    var maxCircles = 30;
	var c = document.getElementById("main");
    var ctx = c.getContext("2d");
	
    for (var r = 1; r <= maxCircles; r++) {
        var x = myRnd(c.clientWidth);
        var y = myRnd(c.clientHeight);
        var radius = parseInt(Math.random() * 30);

		var grd = ctx.createRadialGradient(0, 0, 5, 0, 0, radius);
		grd.addColorStop(0, 'rgb(' + myRnd(255) + ', ' + myRnd(255) + ',' + myRnd(255) + ')');
		grd.addColorStop(1, 'white');
		ctx.fillStyle = grd;

        ctx.setTransform(1,0,0,1,x,y);
	    ctx.beginPath();
        ctx.arc(0, 0, radius, 0, 2 * Math.PI,false);
        // Fill with gradient
        ctx.fill();
        ctx.lineWidth = 5;
        //ctx.strokeStyle = '#003300';
        ctx.stroke();
    }
}
rndCircles();
&#13;
<canvas id="main" width="500" height="500" style="border:1px solid black;"></canvas>
&#13;
&#13;
&#13;