如何使用javascript按百分比从渐变中获取颜色值?

     2023-02-23     218

关键词:

【中文标题】如何使用javascript按百分比从渐变中获取颜色值?【英文标题】:How to get color value from gradient by percentage with javascript? 【发布时间】:2015-07-20 12:08:46 【问题描述】:

我有一个使用 css 应用渐变的固定宽度 div。我想基于这个渐变构建基于滑块的颜色选择器。

当我拖动滑块时,我会计算百分比位置,并且我想根据该值获取十六进制或 rgb 颜色代码。

我的想法是创建一个定义了开始/停止位置和颜色的数组,然后根据滑块位置从该数组中找到两个值,然后以某种方式找到两者之间的颜色:这是我无法前进的地方。

演示:http://jsfiddle.net/pdu8rpfv/

var gradient = [
    [
        0,
        'ff0000'
    ],
    [
        28,
        '008000'
    ],
    [
        72,
        '0000ff'
    ],
    [
        100,
        'ff0000'
    ]
];
$( "#slider" ).slider(
    min: 1,
    slide: function( event, ui ) 

        var colorRange = []
        $.each(gradient, function( index, value ) 
            if(ui.value<=value[0]) 
                colorRange = [index-1,index]
                return false;
            
        );

        $('#result').css("background-color", 'red');

    
);

【问题讨论】:

【参考方案1】:

我能够使用这个基于less.js函数的函数解决这个问题:http://lesscss.org/functions/#color-operations-mix

function pickHex(color1, color2, weight) 
    var w1 = weight;
    var w2 = 1 - w1;
    var rgb = [Math.round(color1[0] * w1 + color2[0] * w2),
        Math.round(color1[1] * w1 + color2[1] * w2),
        Math.round(color1[2] * w1 + color2[2] * w2)];
    return rgb;

我只需要传递渐变数组中最接近的两个颜色代码和滑块手柄所在的比率(可以借助滑块宽度轻松计算)。这是一个活生生的例子:

http://jsfiddle.net/vksn3yLL/

【讨论】:

【参考方案2】:

有一个很好的库可以处理各种颜色操作chroma.js

yarn add chroma-js

然后

import chroma from 'chroma-js';

const f = chroma.scale(['yellow', 'red', 'black']);

console.log( f(0.25).toString() );                    // #ff8000
console.log( f(0.5).css('rgba') );                    // rgba(255,0,0,1)
console.log( f(0.75).css() );                         // rgb(128,0,0)
console.log( f(1).css() );                            // rgb(0,0,0)

【讨论】:

【参考方案3】:

这是另一种将百分比转换为颜色的方法

此示例根据其值将显示的值从红色变为绿色(例如在 excel 条件格式中):

function(percentValue) 
  $(`#output`)
    // print the value
    .html(percentValue)
    // colorize the text, more red if it's close to 0
    // and more green as it approach 100
    .css(color: `rgb($(100 - percent) *2.56, $percent *2.56,0)`)

请看下面的演示:

$('button').click( e => 
  const percent = Math.floor(Math.random()*100);
  const newElm = $(`<b>$percent</b><br>`)
  .css(color: `rgb($(100 - percent) *2.56,$percent *2.56,0)`)
  $('body').append(newElm);
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click to make new percentage</button><br>

【讨论】:

【参考方案4】:

无限数量的颜色渐变(两种或更多)

如果您有 2、3、4 或 20 种颜色,您可以使用此解决方案。生成一个HTML 元素并使用CSS 渐变背景对其进行样式设置。然后查看单个像素的颜色值。

    创建一个&lt;canvas&gt; 元素。宽度为 101px(0 到 100%),高度为 1px(我们不关心高度)。然后将背景颜色设置为渐变。见方法initCanvas(colorsArray)

    查看画布的单个像素,并返回它的颜色。见方法getColor(percent)

    最后,您可以找到由 5 种颜色(红色、橙色、绿色、石灰、蓝色)组成的渐变示例。

const WIDTH = 101; // 0 to 100
const HEIGHT = 1;
  
let context;

function initCanvas(gradientColors) // gradientColors [colorA, colorB, ..]

  // Canvas
  const canvasElement = document.createElement("CANVAS");
  canvasElement.width = WIDTH;
  canvasElement.height = HEIGHT;

  context = canvasElement.getContext("2d");
  
  // Gradient
  const gradient = context.createLinearGradient(0, 0, WIDTH, 0); // x0, y0, x1, y1
  
  const step = 1 / (gradientColors.length - 1); // need to validate at least two colors in gradientColors
  let val = 0;
  gradientColors.forEach(color => 
    gradient.addColorStop(val, color);
    val += step;
  );

  // Fill with gradient
  context.fillStyle = gradient;
  context.fillRect(0, 0, WIDTH, HEIGHT); // x, y, width, height


function getColor(percent) // percent [0..100]

  const color = context.getImageData(percent, 0, 1, 1); // x, y, width, height
  const rgba = color.data;
  
  return `rgb($ rgba[0] , $ rgba[1] , $ rgba[2] )`;


// Test:
initCanvas(['red', 'orange', 'green', 'lime', 'blue']);

document.getElementById("color0"  ).style.backgroundColor = getColor(0);
document.getElementById("color10" ).style.backgroundColor = getColor(10);
document.getElementById("color20" ).style.backgroundColor = getColor(20);
document.getElementById("color30" ).style.backgroundColor = getColor(30);
document.getElementById("color40" ).style.backgroundColor = getColor(40);
document.getElementById("color50" ).style.backgroundColor = getColor(50);
document.getElementById("color60" ).style.backgroundColor = getColor(60);
document.getElementById("color70" ).style.backgroundColor = getColor(70);
document.getElementById("color80" ).style.backgroundColor = getColor(80);
document.getElementById("color90" ).style.backgroundColor = getColor(90);
document.getElementById("color100").style.backgroundColor = getColor(100);
.example 
  width: 100px;
  height: 25px;
<h3>Gradient colors: red, orange, green, lime, blue</h3>
<div id="color0"   class="example">0%  </div>
<div id="color10"  class="example">10% </div>
<div id="color20"  class="example">20% </div>
<div id="color30"  class="example">30% </div>
<div id="color40"  class="example">40% </div>
<div id="color50"  class="example">50% </div>
<div id="color60"  class="example">60% </div>
<div id="color70"  class="example">70% </div>
<div id="color80"  class="example">80% </div>
<div id="color90"  class="example">90% </div>
<div id="color100" class="example">100%</div>

P.S - 我使用initCanvs()getColors() 两种方法进行编码,因此您不会为每种颜色选择生成新的画布。但是如果你每次都有新的渐变,你可以合并它们。

【讨论】:

【参考方案5】:

使用与 Felipe Ribeiro 的最佳答案类似的逻辑,

我创建了一个 Javascript color-scales 来为您处理它。您还可以输入多个色标以及设置透明度级别。

现场演示在这里:https://codepen.io/dalisc/pen/yLVXoeR

包链接在这里:https://www.npmjs.com/package/color-scales

示例用法:

const ColorScale = require("color-scales");
let colorScale = new ColorScale(0, 100, ["#ffffff", "#000000"], 0.5);
let rgbaStr = colorScale.getColor(50).toRGBAString(); // returns "rgba(127,127,127, 0.5)"

该软件包能够根据您的需要输出十六进制、rgb 或 rgba 字符串。它还可以输出自定义颜色对象 (r,g,b,a),以防您需要挑选单个颜色分量。

我在尝试在基于 Javascript 的应用程序上模仿 Tableau 仪表板时遇到了类似的问题。我意识到这是 Tableau 和 Microsoft Excel 等数据可视化工具的常见功能,所以我创建了一个 npm 包来在 Javascript 应用程序上处理它。如果你想减少你的代码,你可以使用这个包。

【讨论】:

【参考方案6】:

三色渐变

以防万一有人想要 3 色渐变,这里有一个使用红色、黄色和绿色的示例:

colorGradient 函数的 github JS 代码在 here 可用。

function colorGradient(fadeFraction, rgbColor1, rgbColor2, rgbColor3) 
    var color1 = rgbColor1;
    var color2 = rgbColor2;
    var fade = fadeFraction;

    // Do we have 3 colors for the gradient? Need to adjust the params.
    if (rgbColor3) 
      fade = fade * 2;

      // Find which interval to use and adjust the fade percentage
      if (fade >= 1) 
        fade -= 1;
        color1 = rgbColor2;
        color2 = rgbColor3;
      
    

    var diffRed = color2.red - color1.red;
    var diffGreen = color2.green - color1.green;
    var diffBlue = color2.blue - color1.blue;

    var gradient = 
      red: parseInt(Math.floor(color1.red + (diffRed * fade)), 10),
      green: parseInt(Math.floor(color1.green + (diffGreen * fade)), 10),
      blue: parseInt(Math.floor(color1.blue + (diffBlue * fade)), 10),
    ;

    return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')';

演示:

// Gradient Function
function colorGradient(fadeFraction, rgbColor1, rgbColor2, rgbColor3) 
    console.log('>> fade: ', fadeFraction)
    var color1 = rgbColor1;
    var color2 = rgbColor2;
    var fade = fadeFraction;

    // Do we have 3 colors for the gradient? Need to adjust the params.
    if (rgbColor3) 
      fade = fade * 2;

      // Find which interval to use and adjust the fade percentage
      if (fade >= 1) 
        fade -= 1;
        color1 = rgbColor2;
        color2 = rgbColor3;
      
    

    var diffRed = color2.red - color1.red;
    var diffGreen = color2.green - color1.green;
    var diffBlue = color2.blue - color1.blue;

    var gradient = 
      red: parseInt(Math.floor(color1.red + (diffRed * fade)), 10),
      green: parseInt(Math.floor(color1.green + (diffGreen * fade)), 10),
      blue: parseInt(Math.floor(color1.blue + (diffBlue * fade)), 10),
    ;
    return 'rgb(' + gradient.red + ',' + gradient.green + ',' + gradient.blue + ')';

  
// IMPLEMENTATION EXAMPLE:
var spans = $('.gradient-test');
var count = spans.length, color;
var color1 = 
  red: 19, green: 233, blue: 19
;
var color3 = 
  red: 255, green: 0, blue: 0
;
var color2 = 
  red: 255, green: 255, blue: 0
;
$('.gradient-test').each(function(i, span) 
  var g = Math.round(((i+1) * 100) / count);
  if (g < 10)
    g = '0' + g;
   
  g = +g === 100 ? 1 : +('0.' + g)
  color = colorGradient(g, color1, color2, color3);
  $(span).css('background-color', color);
);
.gradient-test 
  width: 1rem;
  height: 1rem;
  display: inline-block;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>
<span class="gradient-test"></span>

【讨论】:

最后一个颜色是开头的那个,应该是这样吗? 不,不是@htmlcoderexe,是实现代码错误(不在colorGradient函数中)(100%被解析为0.1而不是1.0)。我刚刚修好了。谢谢【参考方案7】:

根据上面的 Gils 回答,我创建了一个使用渐变的类,颜色设置为沿线性渐变的特定百分比。因此,它可以轻松地处理从 CSS 复制粘贴的更复杂的渐变。

// background: linear-gradient(90deg, #386657 0%, #85B87A 24.48%, #FFE600 51.56%, #BA4F1A 80.21%, #940023 100%);
const grad = new LinearGradientHelper([
  ['#386657', 0],
  ['#85B87A', .2448],
  ['#FFE600', .5156],
  ['#BA4F1A', .8021],
  ['#940023', 1]
])

console.log(grad.getColor(0))
console.log(grad.getColor(.1))
console.log(grad.getColor(.4))
console.log(grad.getColor(.95))
console.log(grad.getColor(1))

https://jsfiddle.net/ctk916xa/2/

【讨论】:

【参考方案8】:

这是我对多色渐变集 RGB 的实现。 (没有 Alpha 通道)。先前答案的扩展变体。

r1.addEventListener('change',(ev)=>
  let res = test(ev.target.value)
  d2.innerText=ev.target.value +' color: '+res
  d2.style.backgroundColor = res
)
function test(value)
  let colorPicked = pickRgbRange(value,
       color:[255,0,228,1], position:0,
       color:[0,194,255,1,1], position:15,
       color:[35,200,0,1], position:35,
       color:[255, 250, 164], position:50,
       color:[255,0,0,1], position:75,
       color:[0,0,0,1], position:100
       );
  let resultRgba = `rgba($colorPicked[0],$colorPicked[1],$colorPicked[2],$colorPicked[3])`;
     return resultRgba


//(ildarin cc0) Start copy from here: ----------------------------------
/** @description usage
   let colorPickedRgba = pickRgbRange(value,
     color:[255,0,228,1], position:0,
     color:[0,194,255,1,0.5], position:.15,
     color:[35,200,0,1], position:.35,
     color:[255, 250, 164], position:.50,
     color:[255,0,0,1], position:.75,
     color:[0,0,0,1], position:.100
     )
     let resultRgba = `rgba($colorPicked[0],$colorPicked[1],$colorPicked[2],$colorPicked[3])`
*/
function pickRgbRange(position, ...elements) 
    var [left, right, weight] = pickClosest(position, ...elements);
    return pickRgba(left.color, right.color, weight);


function pickRgba(color1, color2, weight) 
    var w1 = weight;
    var w2 = 1 - w1;
    var rgba = [
        Math.round(color1[0] * w2 + color2[0] * w1),
        Math.round(color1[1] * w2 + color2[1] * w1),
        Math.round(color1[2] * w2 + color2[2] * w1),
        1
    ];
    return rgba;


function pickClosest(position, ...elements) 
    var left = elements[0], 
    right =  color: [0, 0, 0], position: Number.MAX_VALUE ;
    var leftIndex = 0;
    for (var i = 0; i < elements.length; i++) 
        if (position >= elements[i].position && position > left.position)
            left = elements[i];
            leftIndex = i;
        
    
    if (elements.length - 1 === leftIndex) 
        right = elements[leftIndex];
    
    else 
        right = elements[leftIndex + 1];
    
    if(left == right)
      return [right, right, 0];
    
    var dleft = position - left.position;
    var sum = dleft + right.position - position;
    var weight = dleft / sum;
    return [left, right, weight];
#r1
width:100%;

#d1,
#d2 
  width: 100%;
  height: 50px;


#d1 
  background: linear-gradient(90deg,
      rgb(255, 0, 228) 0%,
      rgb(0, 194, 255) 15%,
      rgb(35, 200, 0) 35%,
      rgb(255, 250, 164) 50%,
      rgb(255, 0, 0) 75%,
      rgb(0, 0, 0) 100%);


#d2 
  text-shadow:0 0 4px #fff;
  background-color: #ccc;
<div id='d1'></div>
<input id='r1' type='range' />
<div id='d2'></div>

【讨论】:

如何使用Javascript从文件上传中获取完整路径

】如何使用Javascript从文件上传中获取完整路径【英文标题】:howtogetfullpathfromfileuploadusingJavascript【发布时间】:2010-12-1018:09:46【问题描述】:我需要知道如何使用javascript从文件上传中获取完整路径,我尝试使用以下编码但没有... 查看详情

我可以获得一些关于如何通过在 C# 中使用 webhook API 从 Forge 获取文件翻译进度百分比的帮助/示例吗?

...关于如何通过在C#中使用webhookAPI从Forge获取文件翻译进度百分比的帮助/示例吗?【英文标题】:CanIgetsomehelp/exampleonhowtogetthefiletranslationprogresspercentagefromForgebyusingwebhookAPIinC#?【发布时间】:2020-10-1221:05:16【问题描述】:我能否获... 查看详情

如何使用 JavaScript 从完整路径中获取文件名?

】如何使用JavaScript从完整路径中获取文件名?【英文标题】:HowtogetthefilenamefromafullpathusingJavaScript?【发布时间】:2010-09-3005:13:45【问题描述】:有没有办法从完整路径中获取最后一个值(基于“\\”符号)?例子:C:\\DocumentsandSe... 查看详情

如何使用javascript从网页中获取点击或选择的文本? [复制]

】如何使用javascript从网页中获取点击或选择的文本?[复制]【英文标题】:howtogettheclickedorselectedtextfromthewebpagesusingjavascript?[duplicate]【发布时间】:2020-11-0321:38:00【问题描述】:如何使用javascript从网页中获取点击或选择的文本?... 查看详情

JavaScript如何从百分比计算中返回一个看起来像双倍的字符串[重复]

】JavaScript如何从百分比计算中返回一个看起来像双倍的字符串[重复]【英文标题】:JavaScripthowtoreturnastringwhichlookslikeadoublefromapercentagecalculation[duplicate]【发布时间】:2017-07-0701:07:30【问题描述】:我在javascript中从价格中执行简单... 查看详情

如何使用 javascript 从网页中获取所有图像 url?

】如何使用javascript从网页中获取所有图像url?【英文标题】:Howtogetallimageurlsfromawebpageusingjavascript?【发布时间】:2021-04-2609:59:55【问题描述】:有几种方法可以使用javascript加载图像srcurl,例如使用document.images或选择所有img标记... 查看详情

如何从动态添加(使用 javascript)元素中获取值?

】如何从动态添加(使用javascript)元素中获取值?【英文标题】:Howtogetvaluesfromdynamicallyadded(usingjavascript)elements?【发布时间】:2011-08-0918:21:34【问题描述】:在我的aspx页面上,我使用javascript在客户端动态创建html控件。例如,... 查看详情

如何使用 Javascript 从输入框值中获取总和?

】如何使用Javascript从输入框值中获取总和?【英文标题】:HowgettotalsumfrominputboxvaluesusingJavascript?【发布时间】:2012-11-1212:10:38【问题描述】:我在Javascript方面并不完美。我想在不刷新页面的下一个名为total的输入框中显示在qty... 查看详情

如何使用 JavaScript 从数据库/模型中获取数据

】如何使用JavaScript从数据库/模型中获取数据【英文标题】:HowtogetdatafromDatabase/ModelwithJavaScript【发布时间】:2017-06-1415:16:49【问题描述】:我是ASP.NET、MVC和AngularJS的新手,所以我还在努力解决这一切。我有一个名为Words.cs的模... 查看详情

如何使用 php 和 javascript 从目录中获取文件名

】如何使用php和javascript从目录中获取文件名【英文标题】:Howtogetafilenamefromadirectoryusingphpandjavascript【发布时间】:2017-03-0618:56:26【问题描述】:我正在尝试使用php更新我的旧Flash画廊网站。我想知道如何在单击鼠标中键后从存... 查看详情

使用扩展脚本(javascript)如何从 Photoshop 颜色表中获取颜色值

】使用扩展脚本(javascript)如何从Photoshop颜色表中获取颜色值【英文标题】:Usingextendscript(javascript)howcanIgetthecolorvaluesfromthePhotoshopcolortable【发布时间】:2013-09-0708:18:16【问题描述】:我正在用extendscript/javascript编写一个Photoshop... 查看详情

如何使用 JavaScript 函数从 Select Option 标记中获取值

】如何使用JavaScript函数从SelectOption标记中获取值【英文标题】:HowtoIgetvaluefromSelectOptiontagusingJavaScriptfunction【发布时间】:2021-12-1503:26:47【问题描述】:我有一个这样的下拉列表:<selectid="itemsList"onchange="gettingList()"><option&... 查看详情

如何从 MySQL 数据库中获取数据并在 javascript 自动完成中使用?

】如何从MySQL数据库中获取数据并在javascript自动完成中使用?【英文标题】:HowtofetchdatafromMySQLdatabaseanduseinajavascriptautocomplete?【发布时间】:2018-10-2314:08:31【问题描述】:我正在使用jQueryautocomplete构建自动完成功能。为此,我在... 查看详情

Openpyxl如何按索引从工作表中获取行

】Openpyxl如何按索引从工作表中获取行【英文标题】:OpenpyxlHowtogetrowfromworksheetbyindex【发布时间】:2017-03-2611:48:45【问题描述】:使用Openpyxl和python3.5,我尝试使用下标从excel工作表中获取第一行,但出现错误。#aftergettingfilename#af... 查看详情

如何使用 JavaScript / PHP 从图像中获取地理位置数据?

】如何使用JavaScript/PHP从图像中获取地理位置数据?【英文标题】:HowdoIgetthegeolocationdatafromanimageusingJavaScript/PHP?【发布时间】:2011-06-2707:50:42【问题描述】:我正在制作一个自定义的Google地图应用程序。我想在地图上显示我所有... 查看详情

如何使用 JavaScript/AngularJS 从数据库/模型中获取数据

】如何使用JavaScript/AngularJS从数据库/模型中获取数据【英文标题】:HowtogetdatafromDatabase/ModelwithJavaScript/AngularJS【发布时间】:2017-06-1412:41:57【问题描述】:我是ASP.NET、MVC和AngularJS的新手,所以我还在努力解决这一切。我有一个... 查看详情

如何使用 javascript 或 jquery 仅从字符串中获取所有 HTML 标记? [关闭]

】如何使用javascript或jquery仅从字符串中获取所有HTML标记?[关闭]【英文标题】:HowtogetonlyallHTMLtagstolistfromstringusingjavascriptorjquery?[closed]【发布时间】:2018-10-3105:01:20【问题描述】:如何从字符串中获取仅包含所有HTML标记的列表... 查看详情

使用角度 6 从对象数组中获取百分比

】使用角度6从对象数组中获取百分比【英文标题】:getpercentagefroarrayofobjectsusingangular6【发布时间】:2020-05-1321:48:31【问题描述】:我想获取特定对象的百分比,例如:我有一个选项数组:-options:Array(2)0:id:1,choice:"Yes",answer_count:11... 查看详情