I'm trying to draw a figure on a canvas, to be filled with a rainbow-colored gradient. The wanted result is something like this:
Creating the shape itself is pretty easy, just creating a path and drawing the lines. However, actually filling it with a gradient appears to be somewhat more difficult, as it seems only radial and linear gradients are supported.
The closest I have gotten is this:
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>
The gradient colors and such are correct, but the gradient should of course be more triangular-like, rather than being rectangular and cropped.
Native html5 canvas doesn't have a way to stretch one side of a gradient fill.
But there is a workaround:
Create your stretch gradient by drawing a series of vertical gradient lines with an increasing length.
Then you can use transformations to draw your stretched gradient at your desired angle
Example code and a Demo:
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);
}
#canvas{border:1px solid red; margin:0 auto; }
<h4>Stretched gradient made from vertical strokes</h4>
<canvas id="canvas" width=300 height=200></canvas>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With