Complex shape with rainbow gradient.

I'm trying to draw a shape on canvas to fill the gradient of the rainbow. The desired result looks something like this:

Desired Result

Creating the shape itself is quite simple, just creating a path and drawing lines. However, actually filling it with a gradient seems somewhat more complicated, since only radial and linear gradients are supported.

The closest I got 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> 

Gradient colors, etc. are correct, but the gradient should, of course, be more triangular, and not rectangular and cropped.

+5
source share
1 answer

The native html5 canvas does not have the ability to stretch one side of the gradient fill.

But there is a workaround:

Create your stretch gradient by drawing a series of vertical gradient lines with increasing length.

enter image description here

Then you can use transforms to draw a stretched gradient at the desired angle.

enter image description here

Sample code and 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> 
+4
source

Source: https://habr.com/ru/post/1242708/


All Articles