问题
I have a html5 canvas in my web page. I have only put an image and a gradient in it.
Canvas uses thic JS code to draw itself:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.clearRect ( 0 , 0 , canvas.width, canvas.height );
var img = document.getElementById("slika");
ctx.drawImage(img, 0, 0,canvas.width,canvas.height);
var grd = ctx.createLinearGradient(x-400, 0, x, 0)
grd.addColorStop(0.3,"hsla(360, 100%, 100%, 0)");
grd.addColorStop(1,"hsla(360, 100%, 100%, 0.8)");
ctx.fillStyle=grd;
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.font = "70px Arial";
ctx.fillStyle = "black"
ctx.textAlign = "right";
ctx.fillText(textInput,canvas.width-50,canvas.height-120);
When it displays, the transition isn't very smooth, it just starts somewhere and ends somewhere.
It looks like this:
I would like the transition to be smoother(I don't mean a wider gradient).
Is there any way to do that?
Thanks for answering.
回答1:
Use a s-slope based gradient which could be defined using an ease-in-out function. This way the transition between flat and linear is smoothed out. You may need to compensate a little on the width as initial and final values are closer to the flat values than in the linear approach.
Example
var ctx = document.querySelector("canvas").getContext("2d"), img = new Image();
img.onload = function() {
// init canvas and image
ctx.canvas.width = this.naturalWidth;
ctx.canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
// gradient using ease-in-out
var comp = 100;
var grd = ctx.createLinearGradient(550 - comp, 0, 700 + comp, 0);
for(var t = 0; t <= 1; t += 0.02) { // convert linear t to "easing" t:
grd.addColorStop(t, "hsla(360, 100%, 100%, " + easeInOut(t) * 0.8 + ")");
}
ctx.fillStyle = grd;
ctx.fillRect(0,0, ctx.canvas.width, ctx.canvas.height * 0.5);
// linear (as before)
var grd = ctx.createLinearGradient(550, 0, 700, 0);
grd.addColorStop(0, "hsla(360, 100%, 100%, 0)");
grd.addColorStop(1, "hsla(360, 100%, 100%, 0.8)");
ctx.fillStyle = grd;
ctx.fillRect(0,ctx.canvas.height * 0.5+1, ctx.canvas.width, ctx.canvas.height * 0.5);
};
function easeInOut(t) {return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1}
img.src = "//i.imgur.com/ESyzwQg.png";
canvas {width:100%; height:auto}
<canvas></canvas>
回答2:
If by "smoother" you mean transition more gradually, then you need to adjust your color stops. You don't need to adjust the width of the gradient to do that.
grd.addColorStop(0.3,"hsla(360, 100%, 100%, 0)");
grd.addColorStop(1,"hsla(360, 100%, 100%, 0.8)");
Right now, those stops are driven by this, so you're moving from the left at 0 alpha to 30%, which is where you jump to .8 in your alpha channel, if you want this to feel more gradual, then (depending on the effect you want) you should adjust those stops.
grd.addColorStop(0.0,"hsla(360, 100%, 100%, 0)");
grd.addColorStop(1,"hsla(360, 100%, 100%, 0.8)");
That would be more fluid, and you could reduce the alpha as desired. Again, it really depends on the effect you're seeking on the gradient overlay.
来源:https://stackoverflow.com/questions/30196043/how-to-display-a-smoother-gradient-in-html5-canvas