CSS线性渐变不正确? [英] CSS Linear gradient is inaccurate?

查看:29
本文介绍了CSS线性渐变不正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的应用程序,我正在寻找一种调色板,该调色板可以提供0度到360度之间的任何色相.我目前正在使用此代码制作调色板.让我们以色相120(纯绿色)为例:

For my application I'm looking to make a color palette that can serve any color hue from 0 degrees to 360 degrees. I'm currently using this code to make the palette. Let's use hue 120 (pure green) as an example:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  var grV = ctx.createLinearGradient(0, 0, 0, h);
  grV.addColorStop(0, 'rgba(0,0,0,0)');
  grV.addColorStop(1, '#000');

  ctx.fillStyle = grV;
  ctx.fillRect(0, 0, w, h);
}

drawPalette(120);

<canvas></canvas>

我遇到的问题是,这似乎并不是一个完美的渐变.例如,右上角的颜色是#02FF02 而不是#00FF00 (纯绿色).您可以使用颜色选择器亲自查看.

The issue I'm having is that this doesn't seem to be a perfect gradient. For example, the color at the top right is #02FF02 instead of #00FF00 (pure green). You can use a color picker to see this for yourself.

有什么方法可以制作出可用于调色板的完美线性渐变?

Is there any way to make a perfect linear gradient that is usable for a color palette?

推荐答案

否,渐变返回正确的结果.右上角像素位于渐变的起点和终点之间,并具有插值来反映该梯度.

No, the gradient is returning the correct result. The top right pixel is between the start and end points of the gradient, and has an interpolated value to reflect that.

想象一下具有单个水平或垂直渐变的单个像素画布.渐变的起点是[0,0],渐变的终点是[1,0].我们唯一的像素的中间值应介于开始值和结束值之间的一半.如果我们的起始值为255,255,255,结束值为0,255,0,则唯一像素应为128,255,128,如下所示:

Imagine a single pixel canvas with a single horizontal or vertical gradient. The gradient's start point is [0,0] and the gradient's end is [1,0]. The middle of our sole pixel should have a value half way between the start and end values. If our start value is 255,255,255 and the end value is 0,255,0, then the sole pixel should be 128,255,128, as seen below:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);

}

drawPalette(120);

<canvas width="1" height="1"></canvas>

如果我们有一个10像素乘10像素的画布,则渐变会从0扩展到10,最后一列像素的中间为9.5像素.这意味着,渐变的插值应为渐变的起始值和终止值之间的距离的95%.使用与上述相同的渐变,应为:13、255、13:

If we have a ten pixel by ten pixel canvas, the gradient stretches from 0 to 10, with the middle of the last column of pixels being 9.5 pixels over. Which means, the gradient's interpolated value should be 95% of the way between the start and end values of the gradient. Using the same gradient as above, that should be: 13, 255, 13:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);

}

drawPalette(120);

<canvas width="10" height="10"></canvas>

随着画布变大,具有所应用渐变的第一个/最后一个值与渐变开始/结束值之间的差减小.如果您将示例中的画布更改为大小为1000x1000,则由于四舍五入,右上角像素的值为0,255,0:

As the canvas gets bigger, the difference between the first/last values with the applied gradient and the gradient start/end values decreases. If you change the canvas in your example to have a size of 1000x1000, the top right pixel will have a value of 0,255,0 due to rounding:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  var grV = ctx.createLinearGradient(0, 0, 0, h);
  grV.addColorStop(0, 'rgba(0,0,0,0)');
  grV.addColorStop(1, '#000');

  ctx.fillStyle = grV;
  ctx.fillRect(0, 0, w, h);
  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);
  
}

drawPalette(120);

<canvas width="1000" height="1000"></canvas>

渐变包括起点和终点之间的像素.如果您不希望对它们进行渐变处理,则必须修改渐变,以使其在以后开始一个像素,并在结束之前一个像素:

The gradient includes the pixels between the start and end points. If you don't want them to be gradient-ized, then you'll have to modify the gradient so that it starts one pixel later and ends one pixel sooner:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;
  
  // to ensure we know we're covering the whole thing:
  ctx.fillRect(0,0,w,h)
  //

  var grH = ctx.createLinearGradient(1, 0, w-2, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);

}

drawPalette(120);

<canvas width="100" height="100"></canvas>

这篇关于CSS线性渐变不正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆