JavaScript 颜色渐变

发布于 2024-09-06 01:08:27 字数 280 浏览 8 评论 0原文

使用带或不带 Jquery 的 javascript,我需要根据开始和结束颜色创建颜色渐变。这可以通过编程来完成吗?

结束颜色只会是开始颜色的较暗阴影,并且它用于无序列表,我无法控制 li 项目的数量。我正在寻找一种解决方案,允许我选择开始和结束颜色,将十六进制值转换为 RGB,以便可以在代码中对其进行操作。起始 RGB 值按根据项目数量计算的步长值递增。

因此,如果列表有 8 个项目,则需要分 8 步递增单独的红绿蓝值才能获得最终颜色。有没有更好的方法来做到这一点,如果有的话,我在哪里可以找到一些示例代码?

Using javascript with or without Jquery, I need to a create a gradient of colours based on a start and finish color. Is this possible to do programmatically?

The end colour is only ever going to be darker shade of the start colour and it's for an unordered list which I have no control over the number of li items. I'm looking for a solution that allows me to pick a start and end color, convert the hex value into RGB so it can be manipulated in code. The starting RGB values gets incremented by a step value calculated based upon the number of items.

so if the list had 8 items then the it needs to increment the seperate Red Green Blue values in 8 steps to achieve the final colour. Is there a better way to do it and if so where can I find some sample code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

開玄 2024-09-13 01:08:27

我创建了一个 JS 库 RainbowVis-JS 来解决这个普遍问题。您只需使用 setNumberRange 设置项目数量,并使用 setSpectrum 设置开始和结束颜色。然后您可以使用 colourAt 获取十六进制颜色代码。

var numberOfItems = 8;
var rainbow = new Rainbow(); 
rainbow.setNumberRange(1, numberOfItems);
rainbow.setSpectrum('red', 'black');
var s = '';
for (var i = 1; i <= numberOfItems; i++) {
    var hexColour = rainbow.colourAt(i);
    s += '#' + hexColour + ', ';
}
document.write(s); 
// gives:
// #ff0000, #db0000, #b60000, #920000, #6d0000, #490000, #240000, #000000, 

欢迎您查看该库的源代码。 :)

I created a JS library, RainbowVis-JS to solve this general problem. You just have to set the number of items using setNumberRange and set the start and end colour using setSpectrum. Then you get the hex colour code with colourAt.

var numberOfItems = 8;
var rainbow = new Rainbow(); 
rainbow.setNumberRange(1, numberOfItems);
rainbow.setSpectrum('red', 'black');
var s = '';
for (var i = 1; i <= numberOfItems; i++) {
    var hexColour = rainbow.colourAt(i);
    s += '#' + hexColour + ', ';
}
document.write(s); 
// gives:
// #ff0000, #db0000, #b60000, #920000, #6d0000, #490000, #240000, #000000, 

You are welcome to look at the library's source code. :)

雪落纷纷 2024-09-13 01:08:27

这是一个生成颜色数组的函数!

function hex(c) {
  var s = "0123456789abcdef";
  var i = parseInt(c);

  if (i == 0 || isNaN(c))
    return "00";

  i = Math.round(Math.min(Math.max(0, i), 255));
  return s.charAt((i - i % 16) / 16) + s.charAt(i % 16);
}

/* Convert an RGB triplet to a hex string */
function convertToHex(rgb) {
  return hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}

/* Remove '#' in color hex string */
function trim(s) {
  return (s.charAt(0) == '#') ? s.substring(1, 7) : s
}

/* Convert a hex string to an RGB triplet */
function convertToRGB(hex) {
  var color = [];
  color[0] = parseInt((trim(hex)).substring(0, 2), 16);
  color[1] = parseInt((trim(hex)).substring(2, 4), 16);
  color[2] = parseInt((trim(hex)).substring(4, 6), 16);
  return color;
}

function generateColor(colorStart, colorEnd, colorCount) {

  // The beginning of your gradient
  var start = convertToRGB(colorStart);

  // The end of your gradient
  var end = convertToRGB(colorEnd);

  // The number of colors to compute
  var len = colorCount;

  //Alpha blending amount
  var alpha = 0.0;

  var saida = [];

  for (i = 0; i < len; i++) {
    var c = [];
    alpha += (1.0 / len);

    c[0] = start[0] * alpha + (1 - alpha) * end[0];
    c[1] = start[1] * alpha + (1 - alpha) * end[1];
    c[2] = start[2] * alpha + (1 - alpha) * end[2];

    saida.push(convertToHex(c));

  }

  return saida;
}

// Usage example
var tmp = generateColor('#000000', '#ff0ff0', 10);

for (cor in tmp) {
  $('#result_show').append("<div style='padding:8px;color:#FFF;background-color:#" + tmp[cor] + "'>COLOR " + cor + "° - #" + tmp[cor] + "</div>")
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result_show"></div>

Here is a function to generate an array of colors!

function hex(c) {
  var s = "0123456789abcdef";
  var i = parseInt(c);

  if (i == 0 || isNaN(c))
    return "00";

  i = Math.round(Math.min(Math.max(0, i), 255));
  return s.charAt((i - i % 16) / 16) + s.charAt(i % 16);
}

/* Convert an RGB triplet to a hex string */
function convertToHex(rgb) {
  return hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}

/* Remove '#' in color hex string */
function trim(s) {
  return (s.charAt(0) == '#') ? s.substring(1, 7) : s
}

/* Convert a hex string to an RGB triplet */
function convertToRGB(hex) {
  var color = [];
  color[0] = parseInt((trim(hex)).substring(0, 2), 16);
  color[1] = parseInt((trim(hex)).substring(2, 4), 16);
  color[2] = parseInt((trim(hex)).substring(4, 6), 16);
  return color;
}

function generateColor(colorStart, colorEnd, colorCount) {

  // The beginning of your gradient
  var start = convertToRGB(colorStart);

  // The end of your gradient
  var end = convertToRGB(colorEnd);

  // The number of colors to compute
  var len = colorCount;

  //Alpha blending amount
  var alpha = 0.0;

  var saida = [];

  for (i = 0; i < len; i++) {
    var c = [];
    alpha += (1.0 / len);

    c[0] = start[0] * alpha + (1 - alpha) * end[0];
    c[1] = start[1] * alpha + (1 - alpha) * end[1];
    c[2] = start[2] * alpha + (1 - alpha) * end[2];

    saida.push(convertToHex(c));

  }

  return saida;
}

// Usage example
var tmp = generateColor('#000000', '#ff0ff0', 10);

for (cor in tmp) {
  $('#result_show').append("<div style='padding:8px;color:#FFF;background-color:#" + tmp[cor] + "'>COLOR " + cor + "° - #" + tmp[cor] + "</div>")
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result_show"></div>

初熏 2024-09-13 01:08:27

是的,绝对是。

我在 Java 中完成此操作,在 JavaScript 中也应该相当简单。

首先,您需要将颜色分解为 RGB 分量。

然后计算组件的开始和结束之间的差异。

最后,计算百分比差异并乘以每个分量的起始颜色,然后将其添加到起始颜色。

假设您可以获得 RGB 值,这应该可以做到:

var diffRed = endColor.red - startColor.red;
var diffGreen = endColor.green - startColor.green;
var diffBlue = endColor.blue - startColor.blue;

diffRed = (diffRed * percentFade) + startColor.red;
diffGreen = (diffGreen * percentFade) + startColor.green;
diffBlue = (diffBlue * percentFade) + startColor.blue;

“percentFade”是一个浮动小数,表示淡入“endColor”的程度。 1 将是完全淡入淡出(从而创建最终颜色)。 0 表示不褪色(起始颜色)。

Yes, absolutely.

I do this in Java, should be fairly simple to do in JavaScript too.

First, you'll need to break the colors up into RGB components.

Then calculate the differences between start and finish of the components.

Finally, calculate percentage difference and multiply by the start color of each component, then add it to the start color.

Assuming you can get the RGB values, this should do it:

var diffRed = endColor.red - startColor.red;
var diffGreen = endColor.green - startColor.green;
var diffBlue = endColor.blue - startColor.blue;

diffRed = (diffRed * percentFade) + startColor.red;
diffGreen = (diffGreen * percentFade) + startColor.green;
diffBlue = (diffBlue * percentFade) + startColor.blue;

The "percentFade" is a floating decimal, signifying how far to fade into the "endColor". 1 would be a full fade (thus creating the end color). 0 would be no fade (the starting color).

强辩 2024-09-13 01:08:27

我根据@desau 的回答使用这个函数:

getGradientColor = function(start_color, end_color, percent) {
  // strip the leading # if it's there
  start_color = start_color.replace(/^\s*#|\s*$/g, '');
  end_color = end_color.replace(/^\s*#|\s*$/g, '');

  // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
  if (start_color.length == 3) {
    start_color = start_color.replace(/(.)/g, '$1$1');
  }

  if (end_color.length == 3) {
    end_color = end_color.replace(/(.)/g, '$1$1');
  }

  // get colors
  var start_red = parseInt(start_color.substr(0, 2), 16),
    start_green = parseInt(start_color.substr(2, 2), 16),
    start_blue = parseInt(start_color.substr(4, 2), 16);

  var end_red = parseInt(end_color.substr(0, 2), 16),
    end_green = parseInt(end_color.substr(2, 2), 16),
    end_blue = parseInt(end_color.substr(4, 2), 16);

  // calculate new color
  var diff_red = end_red - start_red;
  var diff_green = end_green - start_green;
  var diff_blue = end_blue - start_blue;

  diff_red = ((diff_red * percent) + start_red).toString(16).split('.')[0];
  diff_green = ((diff_green * percent) + start_green).toString(16).split('.')[0];
  diff_blue = ((diff_blue * percent) + start_blue).toString(16).split('.')[0];

  // ensure 2 digits by color
  if (diff_red.length == 1) diff_red = '0' + diff_red
  if (diff_green.length == 1) diff_green = '0' + diff_green
  if (diff_blue.length == 1) diff_blue = '0' + diff_blue

  return '#' + diff_red + diff_green + diff_blue;
};

console.log(getGradientColor('#FF0000', '#00FF00', 0.4));

I use this function based on @desau answer:

getGradientColor = function(start_color, end_color, percent) {
  // strip the leading # if it's there
  start_color = start_color.replace(/^\s*#|\s*$/g, '');
  end_color = end_color.replace(/^\s*#|\s*$/g, '');

  // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
  if (start_color.length == 3) {
    start_color = start_color.replace(/(.)/g, '$1$1');
  }

  if (end_color.length == 3) {
    end_color = end_color.replace(/(.)/g, '$1$1');
  }

  // get colors
  var start_red = parseInt(start_color.substr(0, 2), 16),
    start_green = parseInt(start_color.substr(2, 2), 16),
    start_blue = parseInt(start_color.substr(4, 2), 16);

  var end_red = parseInt(end_color.substr(0, 2), 16),
    end_green = parseInt(end_color.substr(2, 2), 16),
    end_blue = parseInt(end_color.substr(4, 2), 16);

  // calculate new color
  var diff_red = end_red - start_red;
  var diff_green = end_green - start_green;
  var diff_blue = end_blue - start_blue;

  diff_red = ((diff_red * percent) + start_red).toString(16).split('.')[0];
  diff_green = ((diff_green * percent) + start_green).toString(16).split('.')[0];
  diff_blue = ((diff_blue * percent) + start_blue).toString(16).split('.')[0];

  // ensure 2 digits by color
  if (diff_red.length == 1) diff_red = '0' + diff_red
  if (diff_green.length == 1) diff_green = '0' + diff_green
  if (diff_blue.length == 1) diff_blue = '0' + diff_blue

  return '#' + diff_red + diff_green + diff_blue;
};

console.log(getGradientColor('#FF0000', '#00FF00', 0.4));

七秒鱼° 2024-09-13 01:08:27

desau 的回答很棒。这是 JavaScript 中的:

function hexToRgb(hex) {
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

function map(value, fromSource, toSource, fromTarget, toTarget) {
  return (value - fromSource) / (toSource - fromSource) * (toTarget - fromTarget) + fromTarget;
}

function getColour(startColour, endColour, min, max, value) {
  var startRGB = hexToRgb(startColour);
  var endRGB = hexToRgb(endColour);
  var percentFade = map(value, min, max, 0, 1);

  var diffRed = endRGB.r - startRGB.r;
  var diffGreen = endRGB.g - startRGB.g;
  var diffBlue = endRGB.b - startRGB.b;

  diffRed = (diffRed * percentFade) + startRGB.r;
  diffGreen = (diffGreen * percentFade) + startRGB.g;
  diffBlue = (diffBlue * percentFade) + startRGB.b;

  var result = "rgb(" + Math.round(diffRed) + ", " + Math.round(diffGreen) + ", " + Math.round(diffBlue) + ")";
  return result;
}

function changeBackgroundColour() {
  var count = 0;
  window.setInterval(function() {
    count = (count + 1) % 200;

    var newColour = getColour("#00FF00", "#FF0000", 0, 200, count);

    document.body.style.backgroundColor = newColour;
  }, 20);
}

changeBackgroundColour();

desau's answer is great. Here it is in javascript:

function hexToRgb(hex) {
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

function map(value, fromSource, toSource, fromTarget, toTarget) {
  return (value - fromSource) / (toSource - fromSource) * (toTarget - fromTarget) + fromTarget;
}

function getColour(startColour, endColour, min, max, value) {
  var startRGB = hexToRgb(startColour);
  var endRGB = hexToRgb(endColour);
  var percentFade = map(value, min, max, 0, 1);

  var diffRed = endRGB.r - startRGB.r;
  var diffGreen = endRGB.g - startRGB.g;
  var diffBlue = endRGB.b - startRGB.b;

  diffRed = (diffRed * percentFade) + startRGB.r;
  diffGreen = (diffGreen * percentFade) + startRGB.g;
  diffBlue = (diffBlue * percentFade) + startRGB.b;

  var result = "rgb(" + Math.round(diffRed) + ", " + Math.round(diffGreen) + ", " + Math.round(diffBlue) + ")";
  return result;
}

function changeBackgroundColour() {
  var count = 0;
  window.setInterval(function() {
    count = (count + 1) % 200;

    var newColour = getColour("#00FF00", "#FF0000", 0, 200, count);

    document.body.style.backgroundColor = newColour;
  }, 20);
}

changeBackgroundColour();

夏の忆 2024-09-13 01:08:27

有一个 JavaScript 库可以创建颜色渐变:

javascript-color-gradient

import Gradient from "javascript-color-gradient";
const colorGradient = new Gradient();
colorGradient.setGradient("#e6062d", "#408247"); // from red to green
colorGradient.setMidpoint(8); // set to 8 color steps
colorGradient.getArray(); // get all 8 colors: [ "#d11630", "#bd2534", ... ]
colorGradient.getColor(1); // #bd2534

< a href="https://i.sstatic.net/LayRx.png" rel="noreferrer">结果颜色渐变

There is a JavaScript library which can create color gradients:

javascript-color-gradient

import Gradient from "javascript-color-gradient";
const colorGradient = new Gradient();
colorGradient.setGradient("#e6062d", "#408247"); // from red to green
colorGradient.setMidpoint(8); // set to 8 color steps
colorGradient.getArray(); // get all 8 colors: [ "#d11630", "#bd2534", ... ]
colorGradient.getColor(1); // #bd2534

resulting color gradient

逆光飞翔i 2024-09-13 01:08:27

基于 @drinor 的回答 - TypeScript 支持

const getGradientColor = (startColor: string, endColor: string, percent: number) => {
    // strip the leading # if it's there
    startColor = startColor.replace(/^\s*#|\s*$/g, '');
    endColor = endColor.replace(/^\s*#|\s*$/g, '');

    // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
    if (startColor.length === 3) {
      startColor = startColor.replace(/(.)/g, '$1$1');
    }

    if (endColor.length === 3) {
      endColor = endColor.replace(/(.)/g, '$1$1');
    }

    // get colors
    const startRed = parseInt(startColor.substr(0, 2), 16),
      startGreen = parseInt(startColor.substr(2, 2), 16),
      startBlue = parseInt(startColor.substr(4, 2), 16);

    const endRed = parseInt(endColor.substr(0, 2), 16),
      endGreen = parseInt(endColor.substr(2, 2), 16),
      endBlue = parseInt(endColor.substr(4, 2), 16);

    // calculate new color
    let diffRed = endRed - startRed;
    let diffGreen = endGreen - startGreen;
    let diffBlue = endBlue - startBlue;

    diffRed = ((diffRed * percent) + startRed);
    diffGreen = ((diffGreen * percent) + startGreen);
    diffBlue = ((diffBlue * percent) + startBlue);

    let diffRedStr = diffRed.toString(16).split('.')[0];
    let diffGreenStr = diffGreen.toString(16).split('.')[0];
    let diffBlueStr = diffBlue.toString(16).split('.')[0];

    // ensure 2 digits by color
    if (diffRedStr.length === 1) diffRedStr = '0' + diffRedStr;
    if (diffGreenStr.length === 1) diffGreenStr = '0' + diffGreenStr;
    if (diffBlueStr.length === 1) diffBlueStr = '0' + diffBlueStr;

    return '#' + diffRedStr + diffGreenStr + diffBlueStr;
}

示例:

getGradientColor('#FF0000', '#00FF00', 0.4);

=> “#996600”

Based on @drinor's answer - TypeScript support

const getGradientColor = (startColor: string, endColor: string, percent: number) => {
    // strip the leading # if it's there
    startColor = startColor.replace(/^\s*#|\s*$/g, '');
    endColor = endColor.replace(/^\s*#|\s*$/g, '');

    // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
    if (startColor.length === 3) {
      startColor = startColor.replace(/(.)/g, '$1$1');
    }

    if (endColor.length === 3) {
      endColor = endColor.replace(/(.)/g, '$1$1');
    }

    // get colors
    const startRed = parseInt(startColor.substr(0, 2), 16),
      startGreen = parseInt(startColor.substr(2, 2), 16),
      startBlue = parseInt(startColor.substr(4, 2), 16);

    const endRed = parseInt(endColor.substr(0, 2), 16),
      endGreen = parseInt(endColor.substr(2, 2), 16),
      endBlue = parseInt(endColor.substr(4, 2), 16);

    // calculate new color
    let diffRed = endRed - startRed;
    let diffGreen = endGreen - startGreen;
    let diffBlue = endBlue - startBlue;

    diffRed = ((diffRed * percent) + startRed);
    diffGreen = ((diffGreen * percent) + startGreen);
    diffBlue = ((diffBlue * percent) + startBlue);

    let diffRedStr = diffRed.toString(16).split('.')[0];
    let diffGreenStr = diffGreen.toString(16).split('.')[0];
    let diffBlueStr = diffBlue.toString(16).split('.')[0];

    // ensure 2 digits by color
    if (diffRedStr.length === 1) diffRedStr = '0' + diffRedStr;
    if (diffGreenStr.length === 1) diffGreenStr = '0' + diffGreenStr;
    if (diffBlueStr.length === 1) diffBlueStr = '0' + diffBlueStr;

    return '#' + diffRedStr + diffGreenStr + diffBlueStr;
}

example:

getGradientColor('#FF0000', '#00FF00', 0.4);

=> "#996600"

忆伤 2024-09-13 01:08:27

chroma.js

chroma.scale(['#fafa6e','#2A4858']).mode('lch').colors(6)

chroma.js:

chroma.scale(['#fafa6e','#2A4858']).mode('lch').colors(6)
终遇你 2024-09-13 01:08:27

xolor 库具有渐变功能。这将创建一个具有从起始颜色到结束颜色渐变的 8 种颜色的数组:

var gradientColors = []
var startColor = "rgb(100,200,50)", endColor = "green"
var start = xolor(startColor)
for(var n=0; n<8; n++) {
   gradientColors.push(start.gradient(endColor, n/8))
}  

请在 github 上查看更多信息:https ://github.com/fresheneesz/xolor

The xolor library has a gradient function. This will create an array with 8 colors in a gradient from a start color to an end color:

var gradientColors = []
var startColor = "rgb(100,200,50)", endColor = "green"
var start = xolor(startColor)
for(var n=0; n<8; n++) {
   gradientColors.push(start.gradient(endColor, n/8))
}  

See more on github: https://github.com/fresheneesz/xolor

桜花祭 2024-09-13 01:08:27

不是那么强大,但在大多数情况下都可以工作,并且您不必为以下代码包含除 jQuery 之外的任何其他库:

HTML:

<div id="colors"></div>

JavaScript:

function rainbow(value, s, l, max, min, start, end) {
    value = ((value - min) * (start - end) / max)+end;
    return 'hsl(' + value + ','+s+'%,'+l+'%)';
}

function createRainbowDiv(start,end){
    var gradient = $("<div>").css({display:"flex", "flex-direction":"row",height:"100%"});
    for (var i = start; ((i <= end) && (i >= start)) || ((i >= end) && (i <= start)); 
        i += (end-start) / Math.abs(end-start)){
            gradient.append($("<div>").css({float:"left","background-color":rainbow(i, 100,50, Math.max(start,end), Math.min(start,end), start,end),flex:1}));
    }

    return gradient;
}

$("#colors").append(createRainbowDiv(0,150));
$("#colors").css("width","100%").css("height","10px");

这应该创建一个包含彩虹的 div。请参阅http://jsfiddle.net/rootandy/54rV7/

Not such mighty but in most cases working and you do not have to include any other libraries except jQuery for the following code:

HTML:

<div id="colors"></div>

JavaScript:

function rainbow(value, s, l, max, min, start, end) {
    value = ((value - min) * (start - end) / max)+end;
    return 'hsl(' + value + ','+s+'%,'+l+'%)';
}

function createRainbowDiv(start,end){
    var gradient = $("<div>").css({display:"flex", "flex-direction":"row",height:"100%"});
    for (var i = start; ((i <= end) && (i >= start)) || ((i >= end) && (i <= start)); 
        i += (end-start) / Math.abs(end-start)){
            gradient.append($("<div>").css({float:"left","background-color":rainbow(i, 100,50, Math.max(start,end), Math.min(start,end), start,end),flex:1}));
    }

    return gradient;
}

$("#colors").append(createRainbowDiv(0,150));
$("#colors").css("width","100%").css("height","10px");

This should make an div that contains a rainbow. See http://jsfiddle.net/rootandy/54rV7/

一片旧的回忆 2024-09-13 01:08:27

我需要为一组未知的动态元素创建足够大的颜色选项数组,但我需要每个元素通过开始颜色和结束颜色递增它们的方式。这种方法遵循“百分比褪色”方法,只是我很难遵循这种逻辑。这就是我使用两个 RGB 颜色值的输入并计算页面上元素数量的方法。

这里有一个 codepen 链接,演示了这个概念。

下面是问题的代码片段。

    <style>
      #test {
          width:200px;
          height:100px;
          border:solid 1px #000;
      }

      .test {
          width:49%;
          height:100px;
          border:solid 1px #000;
          display: inline-block;
      }
    </style>
</head>
<body>

<div id="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

    <script>

      var GColor = function(r,g,b) {
          r = (typeof r === 'undefined')?0:r;
          g = (typeof g === 'undefined')?0:g;
          b = (typeof b === 'undefined')?0:b;
          return {r:r, g:g, b:b};
      };


      // increases each channel by the difference of the two
      // divided by 255 (the number of colors stored in the range array)
      // but only stores a whole number
      // This should respect any rgb combinations
      // for start and end colors

      var createColorRange = function(c1) {
          var colorList = [], tmpColor, rr = 0, gg = 0, bb = 0;
          for (var i=0; i<255; i++) {
            tmpColor = new GColor();
              if (rExp >= 0) {

                tmpColor.r = Math.floor(c1.r - rr);
                rr += rAdditive;

              } else {

                tmpColor.r = Math.floor(c1.r + rr);
                rr += rAdditive;
              }

              if (gExp >= 0) {

                tmpColor.g = Math.floor(c1.g - gg);
                gg += gAdditive;

              } else {

                tmpColor.g = Math.floor(c1.g + gg);
                gg += gAdditive;
              }

              if (bExp >= 0) {

                tmpColor.b = Math.floor(c1.b - bb);
                bb += bAdditive;

              } else {

                tmpColor.b = Math.floor(c1.b + bb);
                bb += bAdditive;

              }

              console.log(tmpColor);


              colorList.push(tmpColor);
          }
          return colorList;
      };

      /* ==================
         Testing Code Below
         ================== */


      var firstColor = new GColor(255, 24, 0);
      var secondColor = new GColor(255, 182, 0);

      // Determine the difference
      var rExp = firstColor.r - secondColor.r;

      // Divide that difference by length of the array
      // you would like to create (255 in this case)
      var rAdditive = Math.abs(rExp)/255;

      var gExp = firstColor.g - secondColor.g;
      var gAdditive = Math.abs(gExp)/255;

      var bExp = firstColor.b - secondColor.b;
      var bAdditive = Math.abs(bExp)/255;

      var range = createColorRange(firstColor, secondColor);
      console.log(range);
      var pointer = 0;


      // This gently cycles through
      // all the colors on a single element
      function rotateColors() {
          var currentColor = range[pointer];
          document.getElementById("test").style.backgroundColor = "rgb("+currentColor.r+","+currentColor.g+","+currentColor.b+")";
          pointer++;
          if (pointer < range.length) window.setTimeout(rotateColors, 5);
      }

       rotateColors();

      // say I have 5 elements
      // so I need 5 colors
      // I already have my first and last colors
      // but I need to locate the colors between
      // my start color and my end color
      // inside of this range
      // so I divide the range's length by the
      // number of colors I need
      // and I store the index values of the middle values

      // those index numbers will then act as my keys to retrieve those values
      // and apply them to my element

      var myColors = {};
      var objects = document.querySelectorAll('.test');
        myColors.num = objects.length;


      var determineColors = function(numOfColors, colorArray) {
        var colors = numOfColors;

        var cRange = colorArray;
        var distance = Math.floor(cRange.length/colors);
        var object = document.querySelectorAll('.test');

        var j = 0;
        for (var i = 0; i < 255; i += distance) {

          if ( (i === (distance*colors)) ) {
            object[j].style.backgroundColor = "rgb(" + range[255].r + ", " + range[255].g + ", " + range[255].b + ")";

            j = 0;
            // console.log(range[i]);
          } else {

                // Apply to color to the element
                 object[j].style.backgroundColor = "rgb(" + range[i].r + ", " + range[i].g + ", " + range[i].b + ")";


                  // Have each element bleed into the next with a gradient
               // object[j].style.background = "linear-gradient( 90deg, rgb(" + range[i].r + ", " + range[i].g + ", " + range[i].b + "), rgb(" + range[i+distance].r + ", " + range[i+distance].g + ", " + range[i+distance].b + "))";

            j++;
          }

        }
      };


      setTimeout( determineColors(myColors.num, range), 2000);

    </script>
</body>

I needed to create a large enough array of color options for an unknown set of dynamic elements, but I needed each element to increment their way through a beginning color and an ending color. This sort of follows the "percent fade" approach except I had a difficult time following that logic. This is how I approached it using inputs of two rgb color values and calculating the number of elements on the page.

Here is a link to a codepen that demonstrates the concept.

Below is a code snippet of the problem.

    <style>
      #test {
          width:200px;
          height:100px;
          border:solid 1px #000;
      }

      .test {
          width:49%;
          height:100px;
          border:solid 1px #000;
          display: inline-block;
      }
    </style>
</head>
<body>

<div id="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

<div class="test"></div>

    <script>

      var GColor = function(r,g,b) {
          r = (typeof r === 'undefined')?0:r;
          g = (typeof g === 'undefined')?0:g;
          b = (typeof b === 'undefined')?0:b;
          return {r:r, g:g, b:b};
      };


      // increases each channel by the difference of the two
      // divided by 255 (the number of colors stored in the range array)
      // but only stores a whole number
      // This should respect any rgb combinations
      // for start and end colors

      var createColorRange = function(c1) {
          var colorList = [], tmpColor, rr = 0, gg = 0, bb = 0;
          for (var i=0; i<255; i++) {
            tmpColor = new GColor();
              if (rExp >= 0) {

                tmpColor.r = Math.floor(c1.r - rr);
                rr += rAdditive;

              } else {

                tmpColor.r = Math.floor(c1.r + rr);
                rr += rAdditive;
              }

              if (gExp >= 0) {

                tmpColor.g = Math.floor(c1.g - gg);
                gg += gAdditive;

              } else {

                tmpColor.g = Math.floor(c1.g + gg);
                gg += gAdditive;
              }

              if (bExp >= 0) {

                tmpColor.b = Math.floor(c1.b - bb);
                bb += bAdditive;

              } else {

                tmpColor.b = Math.floor(c1.b + bb);
                bb += bAdditive;

              }

              console.log(tmpColor);


              colorList.push(tmpColor);
          }
          return colorList;
      };

      /* ==================
         Testing Code Below
         ================== */


      var firstColor = new GColor(255, 24, 0);
      var secondColor = new GColor(255, 182, 0);

      // Determine the difference
      var rExp = firstColor.r - secondColor.r;

      // Divide that difference by length of the array
      // you would like to create (255 in this case)
      var rAdditive = Math.abs(rExp)/255;

      var gExp = firstColor.g - secondColor.g;
      var gAdditive = Math.abs(gExp)/255;

      var bExp = firstColor.b - secondColor.b;
      var bAdditive = Math.abs(bExp)/255;

      var range = createColorRange(firstColor, secondColor);
      console.log(range);
      var pointer = 0;


      // This gently cycles through
      // all the colors on a single element
      function rotateColors() {
          var currentColor = range[pointer];
          document.getElementById("test").style.backgroundColor = "rgb("+currentColor.r+","+currentColor.g+","+currentColor.b+")";
          pointer++;
          if (pointer < range.length) window.setTimeout(rotateColors, 5);
      }

       rotateColors();

      // say I have 5 elements
      // so I need 5 colors
      // I already have my first and last colors
      // but I need to locate the colors between
      // my start color and my end color
      // inside of this range
      // so I divide the range's length by the
      // number of colors I need
      // and I store the index values of the middle values

      // those index numbers will then act as my keys to retrieve those values
      // and apply them to my element

      var myColors = {};
      var objects = document.querySelectorAll('.test');
        myColors.num = objects.length;


      var determineColors = function(numOfColors, colorArray) {
        var colors = numOfColors;

        var cRange = colorArray;
        var distance = Math.floor(cRange.length/colors);
        var object = document.querySelectorAll('.test');

        var j = 0;
        for (var i = 0; i < 255; i += distance) {

          if ( (i === (distance*colors)) ) {
            object[j].style.backgroundColor = "rgb(" + range[255].r + ", " + range[255].g + ", " + range[255].b + ")";

            j = 0;
            // console.log(range[i]);
          } else {

                // Apply to color to the element
                 object[j].style.backgroundColor = "rgb(" + range[i].r + ", " + range[i].g + ", " + range[i].b + ")";


                  // Have each element bleed into the next with a gradient
               // object[j].style.background = "linear-gradient( 90deg, rgb(" + range[i].r + ", " + range[i].g + ", " + range[i].b + "), rgb(" + range[i+distance].r + ", " + range[i+distance].g + ", " + range[i+distance].b + "))";

            j++;
          }

        }
      };


      setTimeout( determineColors(myColors.num, range), 2000);

    </script>
</body>
紫罗兰の梦幻 2024-09-13 01:08:27

您可以检索元素列表。我不熟悉 jQuery,但prototypejs 有 Element.childElements() 它将返回一个数组。一旦知道了数组的长度,您就可以确定每一步要改变多少像素分量。以下一些代码我尚未以我所呈现的形式进行测试,但希望它能给您一个想法。

function hex (c) {
  var s = "0123456789abcdef";
  var i = parseInt (c);
  if (i == 0 || isNaN (c))
    return "00";
  i = Math.round (Math.min (Math.max (0, i), 255));
  return s.charAt ((i - i % 16) / 16) + s.charAt (i % 16);
}

/* Convert an RGB triplet to a hex string */
function convertToHex (rgb) {
  return hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}

/* Remove '#' in color hex string */
function trim (s) { return (s.charAt(0) == '#') ? s.substring(1, 7) : s }

/* Convert a hex string to an RGB triplet */
function convertToRGB (hex) {
  var color[];
  color[0] = parseInt ((trim(hex)).substring (0, 2), 16);
  color[1] = parseInt ((trim(hex)).substring (2, 4), 16);
  color[2] = parseInt ((trim(hex)).substring (4, 6), 16);
}


/* The start of your code. */
var start = convertToRGB ('#000000');    /* The beginning of your gradient */
var end   = convertToRGB ('#ffffff');    /* The end of your gradient */
var arr = $('.gradientList').childElements();
var len = arr.length();                  /* The number of colors to compute */
var alpha = 0.5;                         /* Alpha blending amount */

for (i = 0; i < len; i++) {
    var c = [];

    c[0] = start[0] * alpha + (1 - alpha) * end[0];
    c[1] = start[1] * alpha + (1 - alpha) * end[1];
    c[2] = start[2] * alpha + (1 - alpha) * end[2];

    /* Set the background color of this element */
    arr[i].setStyle ({ 'background-color': convertToHex (c) });
}

You can retrieve the list of elements. I'm not familiar with jQuery, but prototypejs has Element.childElements() which will return an array. Once you know the length of the array, you can determine how much to change the pixel components for each step. Some of the following code I haven't tested out in the form I'm presenting it in, but it should hopefully give you an idea.

function hex (c) {
  var s = "0123456789abcdef";
  var i = parseInt (c);
  if (i == 0 || isNaN (c))
    return "00";
  i = Math.round (Math.min (Math.max (0, i), 255));
  return s.charAt ((i - i % 16) / 16) + s.charAt (i % 16);
}

/* Convert an RGB triplet to a hex string */
function convertToHex (rgb) {
  return hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}

/* Remove '#' in color hex string */
function trim (s) { return (s.charAt(0) == '#') ? s.substring(1, 7) : s }

/* Convert a hex string to an RGB triplet */
function convertToRGB (hex) {
  var color[];
  color[0] = parseInt ((trim(hex)).substring (0, 2), 16);
  color[1] = parseInt ((trim(hex)).substring (2, 4), 16);
  color[2] = parseInt ((trim(hex)).substring (4, 6), 16);
}


/* The start of your code. */
var start = convertToRGB ('#000000');    /* The beginning of your gradient */
var end   = convertToRGB ('#ffffff');    /* The end of your gradient */
var arr = $('.gradientList').childElements();
var len = arr.length();                  /* The number of colors to compute */
var alpha = 0.5;                         /* Alpha blending amount */

for (i = 0; i < len; i++) {
    var c = [];

    c[0] = start[0] * alpha + (1 - alpha) * end[0];
    c[1] = start[1] * alpha + (1 - alpha) * end[1];
    c[2] = start[2] * alpha + (1 - alpha) * end[2];

    /* Set the background color of this element */
    arr[i].setStyle ({ 'background-color': convertToHex (c) });
}
自在安然 2024-09-13 01:08:27

基本 Javascript - 背景渐变

这里有一个现成的函数,可以

使用 CSS

Element.prototype.setGradient = function( from, to, vertical ){
   this.style.background = 'linear-gradient(to '+(vertical ? 'top' : 'left')+', '+from+', '+to+' 100%)';
}

将元素背景设置为渐变和用法:

document.querySelector('.mydiv').setGradient('red','green');

更新其他浏览器

这是使用 chrome 进行测试的,我将尝试使用 Canvas

最基本的水平是:

Element.prototype.setGradient = function( fromColor, toColor ){

    var canvas = document.createElement('canvas');
    var ctx    = canvas.getContext('2d');
    var b      = this.getBoundingClientRect();
    var grd    = ctx.createLinearGradient(0, 0, b.width, 0);

    canvas.width = b.width;
    canvas.height = b.height;

    grd.addColorStop(0, fromColor);
    grd.addColorStop(1, toColor);

    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, b.width, b.height);

    this.style.backgroundImage = 'url('+canvas.toDataURL()+')';
}

和用法:

document.querySelector('.mydiv').setGradient('red','green');

小提琴:
https://jsfiddle.net/jch39bey/

-

添加垂直渐变

一个简单的标志来设置垂直

Element.prototype.setGradient = function( fromColor, toColor, vertical ){

    var canvas = document.createElement('canvas');
    var ctx    = canvas.getContext('2d');
    var b      = this.getBoundingClientRect();
    var grd    = ctx.createLinearGradient(0, 0, vertical ? 0 : b.width, vertical ? b.height : 0);

    canvas.width = b.width;
    canvas.height = b.height;

    grd.addColorStop(0, fromColor);
    grd.addColorStop(1, toColor);

    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, b.width, b.height);

    this.style.backgroundImage = 'url('+canvas.toDataURL()+')';
}

和用法:

document.querySelector('.mydiv').setGradient('red','green',true);

Basic Javascript - Background Gradient

Here's a ready-made function to set an elements background to be a gradient

Using CSS

Element.prototype.setGradient = function( from, to, vertical ){
   this.style.background = 'linear-gradient(to '+(vertical ? 'top' : 'left')+', '+from+', '+to+' 100%)';
}

And Usage :

document.querySelector('.mydiv').setGradient('red','green');

This was tested working with chrome, I'll try to update for other browsers

Using Canvas

The most basic horizontal would be :

Element.prototype.setGradient = function( fromColor, toColor ){

    var canvas = document.createElement('canvas');
    var ctx    = canvas.getContext('2d');
    var b      = this.getBoundingClientRect();
    var grd    = ctx.createLinearGradient(0, 0, b.width, 0);

    canvas.width = b.width;
    canvas.height = b.height;

    grd.addColorStop(0, fromColor);
    grd.addColorStop(1, toColor);

    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, b.width, b.height);

    this.style.backgroundImage = 'url('+canvas.toDataURL()+')';
}

And Usage :

document.querySelector('.mydiv').setGradient('red','green');

A Fiddle :
https://jsfiddle.net/jch39bey/

-

Adding Vertical Gradient

A simple flag to set vertical

Element.prototype.setGradient = function( fromColor, toColor, vertical ){

    var canvas = document.createElement('canvas');
    var ctx    = canvas.getContext('2d');
    var b      = this.getBoundingClientRect();
    var grd    = ctx.createLinearGradient(0, 0, vertical ? 0 : b.width, vertical ? b.height : 0);

    canvas.width = b.width;
    canvas.height = b.height;

    grd.addColorStop(0, fromColor);
    grd.addColorStop(1, toColor);

    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, b.width, b.height);

    this.style.backgroundImage = 'url('+canvas.toDataURL()+')';
}

And Usage :

document.querySelector('.mydiv').setGradient('red','green',true);
聊慰 2024-09-13 01:08:27

基于 @desau 的回答和其他地方的一些代码,这里有一个 jQuery 分步演练:

function coloursBetween(fromColour, toColour, numberOfColours){

    var colours = []; //holds output
    var fromSplit = getRGBAValues(hexToRGBA(fromColour, 1.0)); //get raw values from hex
    var toSplit = getRGBAValues(hexToRGBA(toColour, 1.0));
    
    var fromRed = fromSplit[0]; //the red value as integer
    var fromGreen = fromSplit[1];
    var fromBlue = fromSplit[2];
    
    var toRed = toSplit[0];
    var toGreen = toSplit[1];
    var toBlue = toSplit[2];
    
    var difRed = toRed - fromRed; //difference between the two
    var difGreen = toGreen - fromGreen;
    var difBlue = toBlue - fromBlue;
    
    var incrementPercentage = 1 / (numberOfColours-1); //how much to increment percentage by
    
    for (var n = 0; n < numberOfColours; n++){

        var percentage = n * incrementPercentage; //calculate percentage 
        var red = (difRed * percentage + fromRed).toFixed(0); //round em for legibility
        var green = (difGreen * percentage + fromGreen).toFixed(0);
        var blue = (difBlue * percentage + fromBlue).toFixed(0);
        var colour = 'rgba(' + red + ',' + green + ',' + blue + ',1)'; //create string literal
        colours.push(colour); //push home
        
    }
    
    return colours;
}
function getRGBAValues(string) {
    
  var cleaned = string.substring(string.indexOf('(') +1, string.length-1);
  var split = cleaned.split(",");
  var intValues = [];
  for(var index in split){
      intValues.push(parseInt(split[index]));
  }
  return intValues;
}
function hexToRGBA(hex, alpha){
    var c;
    if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
        c= hex.substring(1).split('');
        if(c.length== 3){
            c= [c[0], c[0], c[1], c[1], c[2], c[2]];
        }
        c= '0x'+c.join('');
        return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+alpha+')';
    }
    return rgba(0,0,0,1);
    //throw new Error('Bad Hex');
}

共有三个函数:

  1. coloursBetween(fromColour, toColour, numberOfColours)
  2. getRGBAValues(string) code>
  3. hexToRGBA(hex, alpha)

调用主函数coloursBetween()传入起始颜色和结束颜色,以及你想要的颜色总数已经回来了。因此,如果您请求返回十种颜色,您将获得第一个颜色 + 8 个渐变颜色 + 最后一个颜色。

colorsBetween 函数首先将传入的十六进制颜色(例如#FFFFFF、#000000)转换为 rgba(例如 rgba(255,255,255,1) rgba(0,0,0,1)),然后从中减去红色、绿色和蓝色值每个。

然后计算红色、绿色和蓝色之间的差异。在此示例中,每种情况均为 -255。计算增量并将其用于乘以红色、绿色和蓝色的新增量值。 Alpha 始终假定为 1(完全不透明)。然后将新值添加到颜色数组中,并在 for 循环完成后将其返回。

最后,像这样调用(从红色到蓝色):

var gradientColours = coloursBetween("#FF0000", "#0000FF", 5);

您可以使用它来执行以下操作:
输入图片此处描述

Based on @desau's answer and some code from elsewhere, here's a jQuery step-by-step walkthrough:

function coloursBetween(fromColour, toColour, numberOfColours){

    var colours = []; //holds output
    var fromSplit = getRGBAValues(hexToRGBA(fromColour, 1.0)); //get raw values from hex
    var toSplit = getRGBAValues(hexToRGBA(toColour, 1.0));
    
    var fromRed = fromSplit[0]; //the red value as integer
    var fromGreen = fromSplit[1];
    var fromBlue = fromSplit[2];
    
    var toRed = toSplit[0];
    var toGreen = toSplit[1];
    var toBlue = toSplit[2];
    
    var difRed = toRed - fromRed; //difference between the two
    var difGreen = toGreen - fromGreen;
    var difBlue = toBlue - fromBlue;
    
    var incrementPercentage = 1 / (numberOfColours-1); //how much to increment percentage by
    
    for (var n = 0; n < numberOfColours; n++){

        var percentage = n * incrementPercentage; //calculate percentage 
        var red = (difRed * percentage + fromRed).toFixed(0); //round em for legibility
        var green = (difGreen * percentage + fromGreen).toFixed(0);
        var blue = (difBlue * percentage + fromBlue).toFixed(0);
        var colour = 'rgba(' + red + ',' + green + ',' + blue + ',1)'; //create string literal
        colours.push(colour); //push home
        
    }
    
    return colours;
}
function getRGBAValues(string) {
    
  var cleaned = string.substring(string.indexOf('(') +1, string.length-1);
  var split = cleaned.split(",");
  var intValues = [];
  for(var index in split){
      intValues.push(parseInt(split[index]));
  }
  return intValues;
}
function hexToRGBA(hex, alpha){
    var c;
    if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
        c= hex.substring(1).split('');
        if(c.length== 3){
            c= [c[0], c[0], c[1], c[1], c[2], c[2]];
        }
        c= '0x'+c.join('');
        return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+alpha+')';
    }
    return rgba(0,0,0,1);
    //throw new Error('Bad Hex');
}

There are three functions:

  1. coloursBetween(fromColour, toColour, numberOfColours)
  2. getRGBAValues(string)
  3. hexToRGBA(hex, alpha)

Call the main function coloursBetween() passing in the starting colour and the ending colour, as well as the total number of colours you want to have returned. So if you request ten colours returned, you get the first from colour + 8 gradient colours + the final to colour.

The coloursBetween function starts by converting the incoming hex colours (e.g. #FFFFFF, #000000) into rgba (e.g. rgba(255,255,255,1) rgba(0,0,0,1)) and then subtracting the Red, Green and Blue values from each.

The difference between the Reds, Greens and Blues is then calculated. In this example it's -255 in each case. An increment is calculated and used to multiply new incremental values for the Red, Green and Blue. Alpha is always assumed to be one (full opacity). The new value is then added to the colours array and after the for loop has completed, it's returned.

Finally, call like this (going from Red to Blue):

var gradientColours = coloursBetween("#FF0000", "#0000FF", 5);

which you can use to for something like this:
enter image description here

赢得她心 2024-09-13 01:08:27

这是一个可以满足您要求的脚本:
https://gist.github.com/av01d/538b3fffc78fdc273894d173a83c563f

非常易于使用:

let colors;
colors = ColorSteps.getColorSteps('#000', 'rgba(255,0,0,0.1)', 10);
colors = ColorSteps.getColorSteps('red', 'blue', 5);
colors = ColorSteps.getColorSteps('hsl(180, 50%, 50%)', 'rgba(200,100,20,0.5)', 10);

Here's a script that does just what you're asking for:
https://gist.github.com/av01d/538b3fffc78fdc273894d173a83c563f

Very easy to use:

let colors;
colors = ColorSteps.getColorSteps('#000', 'rgba(255,0,0,0.1)', 10);
colors = ColorSteps.getColorSteps('red', 'blue', 5);
colors = ColorSteps.getColorSteps('hsl(180, 50%, 50%)', 'rgba(200,100,20,0.5)', 10);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文