How to display a smoother gradient in HTML5 canvas?

白昼怎懂夜的黑 提交于 2019-12-24 04:27:39

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!