彩虹渐变的复杂形状

时间:2016-02-10 14:33:35

标签: javascript html5-canvas

我正在尝试在画布上绘制一个图形,以填充彩虹色渐变。想要的结果是这样的:

Wanted result

创建形状本身非常简单,只需创建路径并绘制线条即可。然而,实际上用渐变填充它似乎有点困难,因为它似乎只支持径向和线性渐变。

我最接近的是:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var gradient=ctx.createLinearGradient(0,0,0,100);
gradient.addColorStop (0, 'red');
gradient.addColorStop (0.25, 'yellow');
gradient.addColorStop (0.5, 'green');
gradient.addColorStop (0.75, 'blue');
gradient.addColorStop (1, 'violet');
ctx.moveTo(0,40);
ctx.lineTo(200,0);
ctx.lineTo(200,100);
ctx.lineTo(0, 50);
ctx.closePath();
ctx.fillStyle = gradient;
ctx.fill();
<body onload="draw();">
   <canvas id="canvas" width="400" height="300"></canvas>
 </body>

渐变颜色等是正确的,但渐变当然应该更像三角形,而不是矩形和裁剪。

1 个答案:

答案 0 :(得分:4)

原生html5画布无法拉伸渐变填充的一侧。

但是有一种解决方法:

通过绘制一系列长度增加的垂直渐变线来创建拉伸渐变。

enter image description here

然后,您可以使用变换以所需的角度绘制拉伸的渐变

enter image description here

示例代码和演示:

&#13;
&#13;
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var length=200;
var y0=40;
var y1=65
var stops=[
    {stop:0.00,color:'red'},
    {stop:0.25,color:'yellow'},
    {stop:0.50,color:'green'},
    {stop:0.75,color:'blue'},
    {stop:1.00,color:'violet'},
];

var g=stretchedGradientRect(length,y0,y1,stops);

ctx.translate(50,100);
ctx.rotate(-Math.PI/10);
ctx.drawImage(g,0,0);


function stretchedGradientRect(length,startingHeight,endingHeight,stops){
    var y=startingHeight;
    var yInc=(endingHeight-startingHeight)/length;
    // create a temp canvas to hold the stretched gradient
    var c=document.createElement("canvas");
    var cctx=c.getContext("2d");
    c.width=length;
    c.height=endingHeight;
    // clip the path to eliminate "jaggies" on the bottom
    cctx.beginPath();
    cctx.moveTo(0,0);
    cctx.lineTo(length,0);
    cctx.lineTo(length,endingHeight);
    cctx.lineTo(0,startingHeight);
    cctx.closePath();
    cctx.clip();
    // draw a series of vertical gradient lines with increasing height
    for(var x=0;x<length;x+=1){
        var gradient=cctx.createLinearGradient(0,0,0,y);
        for(var i=0;i<stops.length;i++){
            gradient.addColorStop(stops[i].stop,stops[i].color);
        }
        cctx.beginPath();
        cctx.moveTo(x,0);
        cctx.lineTo(x,y+2);
        cctx.strokeStyle=gradient;
        cctx.stroke();
        y+=yInc;
    }
    return(c);
}
&#13;
#canvas{border:1px solid red; margin:0 auto; }
&#13;
<h4>Stretched gradient made from vertical strokes</h4>
<canvas id="canvas" width=300 height=200></canvas>
&#13;
&#13;
&#13;