JavaScript рассчитать более яркий цвет - PullRequest
39 голосов
/ 22 июня 2011

У меня есть значение цвета в JS в виде строки

#ff0000

Как бы я мог выполнить программный расчет более яркой / светлой версии этого цвета, например #ff4848, и иметь возможность рассчитатьяркость в процентах, например

increase_brightness('#ff0000', 50); // would make it 50% brighter

Ответы [ 9 ]

69 голосов
/ 22 июня 2011
function increase_brightness(hex, percent){
    // strip the leading # if it's there
    hex = hex.replace(/^\s*#|\s*$/g, '');

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

    var r = parseInt(hex.substr(0, 2), 16),
        g = parseInt(hex.substr(2, 2), 16),
        b = parseInt(hex.substr(4, 2), 16);

    return '#' +
       ((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
       ((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
       ((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1);
}

/**
 * ('#000000', 50) --> #808080
 * ('#EEEEEE', 25) --> #F2F2F2
 * ('EEE     , 25) --> #F2F2F2
 **/
17 голосов
/ 22 июня 2011

Обновление

@ zyklus ответ проще и имеет тот же эффект. Пожалуйста, обращайтесь к этому ответу, только если вы заинтересованы в конвертации между RGB и HSL.


Чтобы установить яркость RGB:

  1. Конвертировать RGB в HSL

  2. Установка яркости HSL

  3. Преобразование обратно из HSL в RGB

Эта ссылка имела код для преобразования RGB в HSL и обратно: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

/**
 * Converts an RGB color value to HSL. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes r, g, and b are contained in the set [0, 255] and
 * returns h, s, and l in the set [0, 1].
 *
 * @param   Number  r       The red color value
 * @param   Number  g       The green color value
 * @param   Number  b       The blue color value
 * @return  Array           The HSL representation
 */
function rgbToHsl(r, g, b){
    r /= 255, g /= 255, b /= 255;
    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if(max == min){
        h = s = 0; // achromatic
    }else{
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch(max){
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }

    return [h, s, l];
}

/**
 * Converts an HSL color value to RGB. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes h, s, and l are contained in the set [0, 1] and
 * returns r, g, and b in the set [0, 255].
 *
 * @param   Number  h       The hue
 * @param   Number  s       The saturation
 * @param   Number  l       The lightness
 * @return  Array           The RGB representation
 */
function hslToRgb(h, s, l){
    var r, g, b;

    if(s == 0){
        r = g = b = l; // achromatic
    }else{
        function hue2rgb(p, q, t){
            if(t < 0) t += 1;
            if(t > 1) t -= 1;
            if(t < 1/6) return p + (q - p) * 6 * t;
            if(t < 1/2) return q;
            if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
            return p;
        }

        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }

    return [r * 255, g * 255, b * 255];
}

Я сделал несколько примеров с этим. Проверьте эту ссылку: http://jsfiddle.net/sangdol/euSLy/4/

А это функция increase_brightness():

function increase_brightness(rgbcode, percent) {
    var r = parseInt(rgbcode.slice(1, 3), 16),
        g = parseInt(rgbcode.slice(3, 5), 16),
        b = parseInt(rgbcode.slice(5, 7), 16),
        HSL = rgbToHsl(r, g, b),
        newBrightness = HSL[2] + HSL[2] * (percent / 100), 
        RGB;

    RGB = hslToRgb(HSL[0], HSL[1], newBrightness);
    rgbcode = '#'
        + convertToTwoDigitHexCodeFromDecimal(RGB[0])
        + convertToTwoDigitHexCodeFromDecimal(RGB[1])
        + convertToTwoDigitHexCodeFromDecimal(RGB[2]);

    return rgbcode;
}

function convertToTwoDigitHexCodeFromDecimal(decimal){
    var code = Math.round(decimal).toString(16);

    (code.length > 1) || (code = '0' + code);
    return code;
}

Вы можете передать отрицательное значение в качестве аргумента percent, чтобы сделать его темнее.

4 голосов
/ 16 мая 2012

Если кому-то это понадобится, я конвертировал код JavaScript яркости цвета в ASP / VBScript для проекта и решил поделиться им с вами:

'::Color Brightness (0-100)
'ex.     ColorBrightness("#FF0000",25)  'Darker
'ex.     ColorBrightness("#FF0000",50)  'Mid
'ex.     ColorBrightness("#FF0000",75)  'Lighter
Function ColorBrightness(strRGB,intBrite)
    strRGB = Replace(strRGB,"#","")

    r = CInt("&h" & Mid(strRGB,1,2))
    g = CInt("&h" & Mid(strRGB,3,2))
    b = CInt("&h" & Mid(strRGB,5,2))

    arrHSL = RGBtoHSL(r, g, b)
    dblOrigBrite = CDbl(arrHSL(2) * 100)

    arrRGB = HSLtoRGB(arrHSL(0), arrHSL(1), intBrite/100)
    newRGB = "#" & HEXtoDEC(arrRGB(0)) & HEXtoDEC(arrRGB(1)) & HEXtoDEC(arrRGB(2))

    ColorBrightness = newRGB
End Function


'::RGB to HSL Function
Function RGBtoHSL(r,g,b)
    r = CDbl(r/255)
    g = CDbl(g/255)
    b = CDbl(b/255)

    max = CDbl(MaxCalc(r & "," & g & "," & b))
    min = CDbl(MinCalc(r & "," & g & "," & b))

    h = CDbl((max + min) / 2)
    s = CDbl((max + min) / 2)
    l = CDbl((max + min) / 2)

    If max = min Then
        h = 0
        s = 0
    Else
        d = max - min
        s = IIf(l > 0.5, d / (2 - max - min), d / (max + min))
        Select Case CStr(max)
            Case CStr(r)
                h = (g - b) / d + (IIf(g < b, 6, 0))
            Case CStr(g)
                h = (b - r) / d + 2
            Case CStr(b)
                h = (r - g) / d + 4
        End Select
        h = h / 6
    End If

    RGBtoHSL = Split(h & "," & s & "," & l, ",")
End Function


'::HSL to RGB Function
Function HSLtoRGB(h,s,l)
    If s = 0 Then
        r = l
        g = l
        b = l
    Else
        q = IIf(l < 0.5, l * (1 + s), l + s - l * s)
        p = 2 * l - q
        r = HUEtoRGB(p, q, h + 1/3)
        g = HUEtoRGB(p, q, h)
        b = HUEtoRGB(p, q, h - 1/3)
    End If

    HSLtoRGB = Split(r * 255 & "," & g * 255 & "," & b * 255, ",")
End Function


'::Hue to RGB Function
Function HUEtoRGB(p,q,t)
    If CDbl(t) < 0 Then t = t + 1
    If CDbl(t) > 1 Then t = t - 1

    If CDbl(t) < (1/6) Then
        HUEtoRGB = p + (q - p) * 6 * t
        Exit Function
    End If

    If CDbl(t) < (1/2) Then
        HUEtoRGB = q
        Exit Function
    End If

    If CDbl(t) < (2/3) Then
        HUEtoRGB = p + (q - p) * (2/3 - t) * 6
        Exit Function
    End If

    HUEtoRGB = p
End Function


'::Hex to Decimal Function
Function HEXtoDEC(d)
    h = Hex(Round(d,0))
    h = Right(String(2,"0") & h,2)
    HEXtoDEC = h
End Function


'::Max Function
Function MaxCalc(valList)
    valList = Split(valList,",")
    b = 0
    For v = 0 To UBound(valList)
        a = valList(v)
        If CDbl(a) > CDbl(b) Then b = a
    Next
    MaxCalc = b
End Function


'::Min Function
Function MinCalc(valList)
    valList = Split(valList,",")
    For v = 0 To UBound(valList)
        a = valList(v)
        If b = "" Then b = a
        If CDbl(a) < CDbl(b) AND b <> "" Then b = a
    Next
    MinCalc = b
End Function


'::IIf Emulation Function
Function IIf(condition,conTrue,conFalse)
    If (condition) Then
        IIf = conTrue
    Else
        IIf = conFalse
    End If
End Function
1 голос
/ 22 июня 2011

Вот функция увеличения яркости с методом RGB-> HSL-> RGB. «сумма» должна быть в процентах.

HSL <-> Функции преобразования RGB, взятые из http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

function increaseBrightness( color, amount ) {
    var r = parseInt(color.substr(1, 2), 16);
    var g = parseInt(color.substr(3, 2), 16);
    var b = parseInt(color.substr(5, 2), 16);
    hsl = rgbToHsl( r, g, b );
    hsl.l += hsl.l + (amount / 100);
    if( hsl.l > 1 ) hsl.l = 1;
    rgb = hslToRgb( hsl.h, hsl.s, hsl.l );

    var v = rgb.b | (rgb.g << 8) | (rgb.r << 16);
    return '#' + v.toString(16);
}

function rgbToHsl(r, g, b){
    r /= 255, g /= 255, b /= 255;
    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if(max == min){
        h = s = 0; // achromatic
    }else{
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch(max){
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }
    return {'h':h, 's':s, 'l':l};
}

function hslToRgb(h, s, l){
    var r, g, b;

    if(s == 0){
        r = g = b = l; // achromatic
    }else{
        function hue2rgb(p, q, t){
            if(t < 0) t += 1;
            if(t > 1) t -= 1;
            if(t < 1/6) return p + (q - p) * 6 * t;
            if(t < 1/2) return q;
            if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
            return p;
        }

        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }

    return { 'r':r * 255, 'g':g * 255, 'b':b * 255 };
}
1 голос
/ 22 июня 2011
// color is a hex color like #aaaaaa and percent is a float, 1.00=100%
// increasing a color by 50% means a percent value of 1.5
function brighten(color, percent) {
    var r=parseInt(color.substr(1,2),16);
    var g=parseInt(color.substr(3,2),16);
    var b=parseInt(color.substr(5,2),16);

    return '#'+
       Math.min(255,Math.floor(r*percent)).toString(16)+
       Math.min(255,Math.floor(g*percent)).toString(16)+
       Math.min(255,Math.floor(b*percent)).toString(16);
}

Живой образец: http://jsfiddle.net/emM55/

0 голосов
/ 30 августа 2018

Упрощенная версия принятого решения с lodash:

// colorIncreaseBrightness('#EBEDF0', 30)
colorIncreaseBrightness(hex, percent) {
  return '#' + _(hex.replace('#', '')).chunk(2)
    .map(v => parseInt(v.join(''), 16))
    .map(v => ((0 | (1 << 8) + v + (256 - v) * percent / 100).toString(16))
    .substr(1)).join('');
}
0 голосов
/ 06 августа 2018

Я нашел вариант ответа Санхьюна Ли, дающий лучший результат.

  1. Конвертировать RGB в HSL
  2. Установить яркость HSL
  3. Конвертировать из HSLtoRGB

Разница / вариация заключается в том, как вы увеличиваете / уменьшаете яркость.

newBrightness = HSL[2] + HSL[2] * (percent / 100) // Original code

Вместо применения процента к текущей яркости, он работает лучше, если его обрабатывать какабсолютное увеличение / уменьшение.Поскольку диапазон яркости составляет от 0 до 1, проценты могут применяться ко всему диапазону (1 - 0) * процентов / 100.

newBrightness = HSL[2] + (percent / 100);
newBrightness = Math.max(0, Math.min(1, newBrightness));

Другим приятным свойством этого подхода является увеличение и уменьшение, сводящие друг с другом,

На рисунке ниже показаны более темные и светлые цвета с шагом 5%.Обратите внимание, что палитра достаточно гладкая и часто заканчивается черным и белым.

Color Palette

Палитра с оригинальным подходом - застревает в определенных цветах.

enter image description here

0 голосов
/ 28 октября 2015

Таким образом, вам не нужно преобразовывать исходный цвет.проверить эту скрипку: https://jsfiddle.net/4c47otou/

increase_brightness = function(color,percent){

    var ctx = document.createElement('canvas').getContext('2d');

    ctx.fillStyle = color;
    ctx.fillRect(0,0,1,1);

    var color = ctx.getImageData(0,0,1,1);
    var r = color.data[0] + Math.floor( percent / 100 * 255 );
    var g = color.data[1] + Math.floor( percent / 100 * 255 );
    var b = color.data[2] + Math.floor( percent / 100 * 255 );

    return 'rgb('+r+','+g+','+b+')';
}

Пример использования:

increase_brightness('#0000ff',20);
increase_brightness('khaki',20);
increase_brightness('rgb(12, 7, 54)',20);
0 голосов
/ 22 июня 2011

Сначала получите быстрое понимание шестнадцатеричных цветовых кодов .

Затем будет довольно легко разбить значение вашего цвета на RGB, внести коррективы и затем вернуть новый цветовой код.

...