Как отобразить более плавный градиент в холсте HTML5?

У меня есть HTML5 холст на моей веб-странице. Я только поместил изображение и градиент в нем.

Canvas использует этот код JS для рисования:

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);

Когда он отображается, переход не очень плавный, он просто где-то начинается и где-то заканчивается.

Это выглядит так:

http://kendaj.net46.net/canvas-Stackru.png

Я хотел бы, чтобы переход был более плавным (я не имею в виду более широкий градиент).

Есть ли способ сделать это?

Спасибо за ответы.

3 ответа

Решение

Используйте градиент, основанный на s-наклоне, который можно определить с помощью функции замедления. Таким образом, переход между плоским и линейным сглаживается. Возможно, вам придется немного компенсировать ширину, так как начальные и конечные значения ближе к плоским значениям, чем в линейном подходе.

ослабление

пример

результат

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>

Если под "более плавным" вы подразумеваете переход более постепенно, то вам необходимо настроить цветовые остановки. Вам не нужно регулировать ширину градиента, чтобы сделать это.

grd.addColorStop(0.3,"hsla(360, 100%, 100%, 0)");
grd.addColorStop(1,"hsla(360, 100%, 100%, 0.8)");

Прямо сейчас эти остановки приводятся в действие этим, поэтому вы двигаетесь слева от 0 альфа до 30%, то есть, где вы переходите на 0,8 в вашем альфа-канале, если вы хотите, чтобы это ощущалось более плавным, то (в зависимости от на эффект, который вы хотите) вы должны настроить эти остановки.

grd.addColorStop(0.0,"hsla(360, 100%, 100%, 0)");
grd.addColorStop(1,"hsla(360, 100%, 100%, 0.8)");

Это было бы более плавно, и вы могли бы уменьшить альфа по желанию. Опять же, это действительно зависит от эффекта, который вы ищете на наложении градиента.

Другие вопросы по тегам