簡體   English   中英

CSS 線性梯度不准確?

[英]CSS Linear gradient is inaccurate?

對於我的應用程序,我正在尋找可以提供從 0 度到 360 度的任何色調的調色板。 我目前正在使用此代碼來制作調色板。 讓我們以色調 120(純綠色)為例:

 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 (純綠色)。 您可以使用顏色選擇器自己查看。

有沒有辦法制作可用於調色板的完美線性漸變?

不,漸變返回正確的結果。 右上角的像素位於漸變的起點和終點之間,並有一個插值來反映這一點。

想象一個具有單一水平或垂直漸變的單像素 canvas。 漸變的起點是 [0,0],漸變的終點是 [1,0]。 我們唯一像素的中間應該有一個介於開始值和結束值之間的值。 如果我們的起始值為 255,255,255,結束值為 0,255,0,那么唯一的像素應該是 128,255,128,如下所示:

 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 像素的 canvas,漸變從 0 延伸到 10,最后一列像素的中間超過 9.5 像素。 這意味着,漸變的插值應該是漸變的開始值和結束值之間的 95%。 使用與上面相同的梯度,應該是: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>

隨着 canvas 變大,應用梯度的第一個/最后一個值與梯度開始/結束值之間的差異減小。 如果您將示例中的 canvas 更改為 1000x1000 的大小,則由於四舍五入,右上角的像素將具有 0,255,0 的值:

 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>

漸變包括起點和終點之間的像素。 如果您不希望它們被漸變化,那么您必須修改漸變,使其晚一個像素開始並早一點結束:

 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM