2010-06-20 16 views
36

Używając javascript z Jquery lub bez, muszę utworzyć gradient kolorów na podstawie koloru początkowego i końcowego. Czy można to zrobić programowo?Gradient koloru JavaScript

Końcowym kolorem będzie tylko ciemniejszy odcień koloru początkowego i jest to lista nieuporządkowana, której nie mam wpływu na liczbę pozycji li. Szukam rozwiązania, które pozwala mi wybrać kolor początkowy i końcowy, przekonwertować wartość heksadecymalną na RGB, aby można było manipulować w kodzie. Początkowe wartości RGB zostaną zwiększone o wartość kroku obliczoną na podstawie liczby elementów.

, więc jeśli lista zawiera 8 elementów, to należy zwiększyć oddzielne wartości Red Green Blue w 8 krokach, aby uzyskać ostateczny kolor. Czy istnieje lepszy sposób na zrobienie tego, a jeśli tak, to gdzie mogę znaleźć przykładowy kod?

+1

Co można opisać to sposób by to zrobić: wystarczy zrobić interpolacji liniowej pomiędzy początkowym i końcowym dla każdego z trzech składowych koloru. – Pointy

+2

Należy pamiętać, że istnieją różne typy gradientów: jeśli chcesz utworzyć gradient przechodzący przez czerwony -> żółty -> zielony -> niebieski, prawdopodobnie będziesz musiał uzyskać wartości HSL zamiast wartości RGB. – vaab

Odpowiedz

20

Tak, absolutnie.

Robię to w Javie, powinno być dość proste do zrobienia również w JavaScript.

Najpierw należy podzielić kolory na elementy RGB.

Następnie obliczyć różnice między początkiem i końcem komponentów.

Na koniec obliczyć różnicę procentową i pomnożyć przez kolor początkowy każdego składnika, a następnie dodać do koloru początkowego.

Zakładając można uzyskać wartości RGB, należy to zrobić:

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; 

W „percentFade” to pływający dziesiętny, oznaczający ile zanikać w „endColor”. 1 byłby pełnym zaniknięciem (tworząc w ten sposób kolor końcowy). 0 oznacza brak zanikania (kolor początkowy).

+1

że drugi zestaw przydziałów jest zbiorem nowych kolorów – alxndr

0

Możesz pobrać listę elementów. Nie znam jQuery, ale prototypej ma element Element.childElements(), który zwróci tablicę. Po poznaniu długości tablicy można określić, jak wiele elementów piksela należy zmienić dla każdego kroku. Niektóre z poniższych kodów nie zostały przetestowane w formularzu, w którym je prezentuję, ale mam nadzieję, że dam ci pomysł.

function hex (c) { 
    var s = "abcdef"; 
    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) }); 
} 
+2

Rozważ zastąpienie swojej funkcji 'hex' po prostu' .toString (16) '. – haylem

+1

Jest w tym wiele błędów. Na przykład convertToRGB tak naprawdę nie zwraca niczego :) –

67

Utworzono bibliotekę JS, RainbowVis-JS, aby rozwiązać ten ogólny problem. Trzeba tylko ustawić liczbę elementów za pomocą setNumberRange i ustawić kolor początkowy i końcowy za pomocą setSpectrum. Następnie otrzymasz kod koloru heksadecymalnego z numerem 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, 

Zapraszamy do zapoznania się z kodem źródłowym biblioteki. :)

+3

Idealnie! Właśnie tego szukałem. Dziękuję –

+0

To naprawdę przydatny skrypt, dobra robota. –

+1

Dzięki, bardzo pomocne. Wykorzystuje go do zbliżających się wyborów w Iranie. ;) – pp19dd

1

Nie takie potężne, ale w większości przypadków działa i nie musi zawierać żadnych innych bibliotek wyjątkiem jQuery dla następującego kodu:

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

To powinno zrobić div, który zawiera tęczę.Zobacz http://jsfiddle.net/rootandy/54rV7/

10

mogę używać tej funkcji w oparciu o @desau odpowiedź:

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

Przykład:

getGradientColor('#FF0000', '#00FF00', 0.4); 
=> "#996600" 
23

prawidłowe funkcjonowanie wygenerować tablicę kolorów!

function hex (c) { 
 
    var s = "abcdef"; 
 
    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){ 
 

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

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

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

 
\t //Alpha blending amount 
 
\t var alpha = 0.0; 
 

 
\t var saida = []; 
 
\t 
 
\t for (i = 0; i < len; i++) { 
 
\t \t var c = []; 
 
\t \t alpha += (1.0/len); 
 
\t \t 
 
\t \t c[0] = start[0] * alpha + (1 - alpha) * end[0]; 
 
\t \t c[1] = start[1] * alpha + (1 - alpha) * end[1]; 
 
\t \t c[2] = start[2] * alpha + (1 - alpha) * end[2]; 
 

 
\t \t saida.push(convertToHex (c)); 
 
\t \t 
 
\t } 
 
\t 
 
\t return saida; 
 
\t 
 
} 
 

 
// Exemplo de como usar 
 

 

 
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>") 
 
    
 
} 
 
\t
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="result_show"></div>

+1

Jesteś współczesnym picasso. To jest głupie!!! – lol

+0

dokładnie to, czego szukałem. Dziękuję Ci. – DolceVita

1

Musiałem stworzyć wystarczająco duży wachlarz opcji kolorów dla nieznanego zestaw elementów dynamicznych, ale potrzebowałem każdy element, aby zwiększyć swoją drogę przez początkującego koloru i kończąc kolor . Ten rodzaj podejścia jest zgodny z podejściem "procentowego zanikania", z tym, że miałem trudny czas podążania za tą logiką. W ten sposób zbliżyłem się do niego za pomocą danych wejściowych o dwóch wartościach kolorów rgb i obliczeniu liczby elementów na stronie.

Oto link to a codepen, który demonstruje koncepcję.

Poniżej znajduje się fragment kodu problemu.

<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> 
1

Funkcja xolor library ma funkcję gradientu. Pozwoli to stworzyć tablicę z 8 kolorów w gradiencie od koloru początkowego do końcowego koloru:

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

Zobacz więcej na github: https://github.com/fresheneesz/xolor

0

desau's answer jest wielki. Tutaj jest to w 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();