2010-06-20 40 views
36

Sử dụng javascript có hoặc không có Jquery, tôi cần tạo một gradient màu dựa trên màu bắt đầu và màu kết thúc. Điều này có thể thực hiện theo chương trình không?Độ dốc màu Javascript

Màu cuối chỉ bao giờ có bóng tối hơn của màu bắt đầu và nó cho một danh sách không có thứ tự mà tôi không kiểm soát được số lượng mục li. Tôi đang tìm một giải pháp cho phép tôi chọn một màu bắt đầu và kết thúc, chuyển đổi giá trị hex thành RGB để nó có thể được thao tác trong mã. Giá trị RGB bắt đầu được tăng lên bằng giá trị bước được tính dựa trên số lượng mục.

vì vậy nếu danh sách có 8 mục thì nó cần tăng giá trị Red Green Blue riêng biệt trong 8 bước để đạt được màu cuối cùng. Có cách nào tốt hơn để làm điều đó và nếu như vậy, nơi tôi có thể tìm thấy một số mã mẫu?

+1

gì bạn mô tả là cách tôi sẽ làm điều đó: chỉ cần làm một phép nội suy tuyến tính giữa điểm bắt đầu và điểm kết thúc cho mỗi người trong số ba thành phần màu. – Pointy

+2

Xin lưu ý rằng có nhiều loại khác nhau của gradient: nếu bạn làm cho một gradient mà đi qua màu đỏ -> vàng -> xanh lá cây -> màu xanh, có thể bạn sẽ cần phải nhận được các giá trị HSL chứ không phải là giá trị RGB. – vaab

Trả lời

20

Có, tuyệt đối.

Tôi làm điều này trong Java, nên khá đơn giản để làm trong JavaScript quá.

Trước tiên, bạn cần phải chia màu thành các thành phần RGB.

Sau đó tính toán sự khác biệt giữa bắt đầu và kết thúc của các thành phần.

Cuối cùng, tính chênh lệch tỷ lệ phần trăm và nhân với màu bắt đầu của mỗi thành phần, sau đó thêm nó vào màu bắt đầu.

Giả sử bạn có thể nhận được các giá trị RGB, điều này sẽ làm điều đó:

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; 

Các "percentFade" là một chữ số thập phân nổi, biểu hiện bao xa mờ dần vào "endColor". 1 sẽ là một fade đầy đủ (do đó tạo ra màu sắc kết thúc). 0 sẽ không bị mờ dần (màu bắt đầu).

+1

tập thứ hai của bài tập là tập hợp các màu mới – alxndr

0

Bạn có thể truy xuất danh sách các phần tử. Tôi không quen thuộc với jQuery, nhưng prototypejs có Element.childElements() sẽ trả về một mảng. Khi bạn biết độ dài của mảng, bạn có thể xác định số lượng thay đổi thành phần pixel cho mỗi bước. Một số mã sau đây tôi đã không được thử nghiệm trong các hình thức tôi trình bày nó trong, nhưng nó hy vọng sẽ cung cấp cho bạn một ý tưởng.

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

Cân nhắc việc thay thế hàm 'hex' của bạn chỉ bằng' .toString (16) '. – haylem

+1

Có nhiều lỗi trong trường hợp này. Ví dụ convertToRGB không thực sự trả lại bất cứ điều gì :) –

67

Tôi đã tạo thư viện JS, RainbowVis-JS để giải quyết vấn đề chung này. Bạn chỉ cần đặt số lượng mục bằng cách sử dụng setNumberRange và đặt màu bắt đầu và màu kết thúc bằng cách sử dụng setSpectrum. Sau đó, bạn nhận được mã màu hex với 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, 

Bạn có thể xem mã nguồn của thư viện. :)

+3

Hoàn hảo! Đó chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn –

+0

Đây là một kịch bản thực sự hữu ích, công việc tốt đẹp. –

+1

Cảm ơn, rất hữu ích. Sử dụng nó cho cuộc bầu cử sắp tới ở Iran. ;) – pp19dd

1

Không như hùng mạnh nhưng trong nhiều trường hợp làm việc và bạn không cần phải bao gồm bất kỳ thư viện nào khác ngoài jQuery cho đoạn mã sau:

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

Điều này sẽ tạo một div chứa cầu vồng.Xem http://jsfiddle.net/rootandy/54rV7/

10

tôi sử dụng chức năng này dựa trên câu trả lời @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; 
}; 

Ví dụ:

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

chức năng đúng để tạo ra mảng màu sắc!

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

Bạn là một picasso hiện đại. Đây là DOPE !!! – lol

+0

chính xác những gì tôi đã tìm kiếm. Cảm ơn bạn. – DolceVita

1

tôi cần phải tạo ra một mảng đủ lớn các tùy chọn màu sắc cho một bộ không rõ của yếu tố năng động, nhưng tôi cần mỗi yếu tố để tăng theo cách của họ thông qua một màu bắt đầu và màu kết thúc . Loại tiếp cận này theo phương pháp "phai nhạt" trừ khi tôi có một khoảng thời gian khó khăn sau logic đó. Đây là cách tôi tiếp cận nó bằng cách sử dụng đầu vào của hai giá trị màu rgb và tính toán số lượng các yếu tố trên trang.

Đây là số link to a codepen minh họa khái niệm.

Dưới đây là đoạn mã của sự cố.

<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

xolor library có chức năng gradient. Điều này sẽ tạo ra một mảng với 8 màu sắc trong một gradient từ màu đầu đến một màu kết thúc:

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

Xem thêm trên github: https://github.com/fresheneesz/xolor

0

desau's answer là rất tốt. Dưới đây là trong 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();

Các vấn đề liên quan