Простое изменение цвета

Я создаю пользовательский интерфейс, в котором пользователи могут изменять значения цвета своих страниц. Я хотел бы присвоить значение, присвоенное их цвету фона, и уменьшить его на определенную величину. Я просто ищу, чтобы достичь линии выделения, не создавая новых изображений каждый раз.

Пример: пользователь установил цвет фона на #ECECEC. Теперь я хочу, чтобы граница определенных элементов стала # F4F4F4 (цвет ближе к белому).

Пожалуйста, дайте мне знать, если это хороший способ сделать это с помощью Javascript, PHP или даже jQuery.

Более простым решением может быть использование конструктора цветов rgba () в CSS:

border: 1px solid rgba(255,255,255,0.7) 

Это создало бы белую границу с непрозрачностью 70%. К сожалению, это не поддерживается в Firefox 2, Opera 9 или любой версии IE. Нетрудно создавать альтернативные версии для этих браузеров. Пример jQuery:

 $('body').append('<div id="rgbatest" style="color:rgba(0,0,0,0);position:absolute;visibility:hidden">&nbsp;</div>"'); if(!$('#rgbatest').css('color').match(/^rgba/)){ $('body').addClass('no-rgba'); } $('#rgbatest').remove(); 

Отсюда вы можете использовать класс .no-rgba для переопределения цветов rgba.

 #thisDiv{border: 1px solid rgba(255,255,255,0.7)} .no-rgba #thisDiv{border: 1px solid #FFF} 

В стороне: RGB не является перцепционно линейным цветовым пространством. Я рекомендую конвертировать из RGB в HSL, интерполировать, а затем преобразовывать обратно в RGB. Я написал следующий код PHP для генерации произвольных перцепционно-правильных градиентов; Я предлагаю превратить его в службу, которая затем может быть вызвана из PHP или AJAX при необходимости.

Вы можете получить свой последний шестнадцатеричный вывод как

 $hexcol = col2string( RGBinterpolate("#ececec", "#ffffff", 0.5) ); // "#f4f4f4" 

Код:

 // Input: // $start as RGB color string, // $end as RGB color string, // $dist as float in [0.0 .. 1.0] being % distance between start and end colors // Output: // array(int, int, int) being the resulting color in RGB) function RGBinterpolate( $start, $end, $dist ) { $hsl_start = rgb2hsl( getCol($start) ); $hsl_end = rgb2hsl( getCol($end) ); // choose the shorter arc of the hue wheel! if ($hsl_start[0] > $hsl_end[0]) { if ($hsl_start[0] > $hsl_end[0] + 0.5) $hsl_start[0] -= 1.0; } else { if ($hsl_end[0] > $hsl_start[0] + 0.5) $hsl_end[0] -= 1.0; } // do linear interpolation in hsl color space $hs = interp( $hsl_start[0], $hsl_end[0], $dist ); $ss = interp( $hsl_start[1], $hsl_end[1], $dist ); $ls = interp( $hsl_start[2], $hsl_end[2], $dist ); return hsl2rgb( array( $hs, $ss, $ls ) ); } // Input: start-value, end-value, % distance as float in [0.0 .. 1.0] // Output: result of interpolation as float function interp($start, $end, $dist) { return $start + ($end - $start)*$dist; } // Input: string in one of the following formats: // #XXXXXX (standard hex code as used in CSS) // 0xXXXXXX (same thing written as C longint) // #XXX (equivalent to each-digit-doubled, ie #abc is #aabbcc) // 000, 000, 000 (decimal triad, each value in 0..255) // colorname (Netscape defined color names) // Output: array(int, int, int) for legal values, else default value function getCol($str, $default=array(0,0,0)) { global $namedcolors; // convert named color to #xxxxxx code if( isset($namedcolors[$str]) ) $str = $namedcolors[$str]; // turn named color into a hex value $str = trim($str); // remove leading and trailing whitespace $hex = "[0-9a-z]"; // attempt to match #XXXXXX $pat = "/(#)($hex{2})($hex{2})($hex{2})/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = hexdec($arr[2]); $g = hexdec($arr[3]); $b = hexdec($arr[4]); return array($r, $g, $b); } // attempt to match 0xXXXXXX $pat = "/(0x)($hex{2})($hex{2})($hex{2})/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = hexdec($arr[2]); $g = hexdec($arr[3]); $b = hexdec($arr[4]); return array($r, $g, $b); } // attempt to match #XXX $pat = "/(#)($hex)($hex)($hex)/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = hexdec($arr[2]) * 17; $g = hexdec($arr[3]) * 17; $b = hexdec($arr[4]) * 17; return array($r, $g, $b); } // attempt to match int, int, int $pat = "/(\d{1,3})\\s*,\\s*(\d{1,3})\\s*,\\s*(\d{1,3})/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = 0 + $arr[2]; // implicit cast to int - make explicit? $g = 0 + $arr[3]; $b = 0 + $arr[4]; return array($r, $g, $b); } // if none of the above worked, return default value return $default; } // Input: array(int,int,int) being RGB color in { [0..255], [0..255], [0..255] } // Output array(float,float,float) being HSL color in { [0.0 .. 1.0), [0.0 .. 1.0), [0.0 .. 1.0) } function rgb2hsl($rgbtrio) { $r = $rgbtrio[0] / 256.0; // Normalize {r,g,b} to [0.0 .. 1.0) $g = $rgbtrio[1] / 256.0; $b = $rgbtrio[2] / 256.0; $h = 0.0; $s = 0.0; $L = 0.0; $min = min($r, $g, $b); $max = max($r, $g, $b); $delta = $max - $min; $L = 0.5 * ( $max + $min ); if ( $delta < 0.001 ) // This is a gray, no chroma... { $h = 0.0; // ergo, hue and saturation are meaningless $s = 0.0; } else // Chromatic data... { if ( $L < 0.5 ) $s = ($max - $min) / ( $max + $min ); else $s = ($max - $min) / ( 2 - $max - $min ); $dr = ( (($max - $r) / 6.0) + ($max / 2.0) ) / $max; $dg = ( (($max - $g) / 6.0) + ($max / 2.0) ) / $max; $db = ( (($max - $b) / 6.0) + ($max / 2.0) ) / $max; if ($r == $max) $h = $db - $dg; elseif ($g == $max) $h = (0.3333) + $dr - $db; elseif ($b == $max) $h = (0.6666) + $dg - $dr; if ( $h < 0.0 ) $h += 1.0; if ( $h > 1.0 ) $h -= 1.0; } return array($h, $s, $L); } function Hue_2_RGB( $v1, $v2, $vH ) { $v1 = 0.0+$v1; $v2 = 0.0+$v2; $vH = 0.0+$vH; if ( $vH < 0.0 ) $vH += 1.0; elseif ( $vH >= 1.0 ) $vH -= 1.0; // 0.0 <= vH < 1.0 if ( $vH < 0.1667 ) return ( $v1 + 6.0*$vH*($v2 - $v1) ); elseif ( $vH < 0.5 ) return ( $v2 ); elseif ( $vH < 0.6667 ) return ( $v1 + (4.0-(6.0*$vH ))*($v2 - $v1) ); else return ( $v1 ); } // Input: array(float,float,float) being HSL color in { [0.0 .. 1.0), [0.0 .. 1.0), [0.0 .. 1.0) } // Output: array(int,int,int) being RGB color in { [0..255], [0..255], [0..255] } function hsl2rgb($hsltrio) { $h = $hsltrio[0]; $s = $hsltrio[1]; $L = $hsltrio[2]; if ( $s < 0.001 ) //HSL from 0 to 1 { $r = $L; $g = $L; $b = $L; } else { if ( $L < 0.5 ) $j = $L * ( 1.0 + $s ); else $j = ($L + $s) - ($s * $L); $i = (2.0 * $L) - $j; $r = Hue_2_RGB( $i, $j, $h + 0.3333 ); $g = Hue_2_RGB( $i, $j, $h ); $b = Hue_2_RGB( $i, $j, $h - 0.3333 ); } return array( floor(256.0 * $r), floor(256.0 * $g), floor(256.0 * $b) ); } function col2string($rgbtrio) { global $colornames; $r = floor( $rgbtrio[0] ); $g = floor( $rgbtrio[1] ); $b = floor( $rgbtrio[2] ); $str = sprintf("#%02x%02x%02x", $r, $g, $b); if( isset($colornames[$str]) ) return $colornames[$str]; else return $str; } // All Netscape named colors $namedcolors = array( "aliceblue" => "#f0f8ff", "antiquewhite" => "#faebd7", "aqua" => "#00ffff", "aquamarine" => "#7fffd4", "azure" => "#f0ffff", "beige" => "#f5f5dc", "bisque" => "#ffe4c4", "black" => "#000000", "blanchedalmond" => "#ffebcd", "blue" => "#0000ff", "blueviolet" => "#8a2be2", "brown" => "#a52a2a", "burlywood" => "#deb887", "cadetblue" => "#5f9ea0", "chartreuse" => "#7fff00", "chocolate" => "#d2691e", "coral" => "#ff7f50", "cornflowerblue" => "#6495ed", "cornsilk" => "#fff8dc", "crimson" => "#dc143c", "cyan" => "#00ffff", "darkblue" => "#00008b", "darkcyan" => "#008b8b", "darkgoldenrod" => "#b8860b", "darkgray" => "#a9a9a9", "darkgreen" => "#006400", "darkgrey" => "#a9a9a9", "darkkhaki" => "#bdb76b", "darkmagenta" => "#8b008b", "darkolivegreen" => "#556b2f", "darkorange" => "#ff8c00", "darkorchid" => "#9932cc", "darkred" => "#8b0000", "darksalmon" => "#e9967a", "darkseagreen" => "#8fbc8f", "darkslateblue" => "#483d8b", "darkslategray" => "#2f4f4f", "darkslategrey" => "#2f4f4f", "darkturquoise" => "#00ced1", "darkviolet" => "#9400d3", "deeppink" => "#ff1493", "deepskyblue" => "#00bfff", "dimgray" => "#696969", "dimgrey" => "#696969", "dodgerblue" => "#1e90ff", "firebrick" => "#b22222", "floralwhite" => "#fffaf0", "forestgreen" => "#228b22", "fuchsia" => "#ff00ff", "gainsboro" => "#dcdcdc", "ghostwhite" => "#f8f8ff", "gold" => "#ffd700", "goldenrod" => "#daa520", "gray" => "#808080", "green" => "#008000", "greenyellow" => "#adff2f", "grey" => "#808080", "honeydew" => "#f0fff0", "hotpink" => "#ff69b4", "indianred" => "#cd5c5c", "indigo" => "#4b0082", "ivory" => "#fffff0", "khaki" => "#f0e68c", "lavender" => "#e6e6fa", "lavenderblush" => "#fff0f5", "lawngreen" => "#7cfc00", "lemonchiffon" => "#fffacd", "lightblue" => "#add8e6", "lightcoral" => "#f08080", "lightcyan" => "#e0ffff", "lightgoldenrodyellow" => "#fafad2", "lightgray" => "#d3d3d3", "lightgreen" => "#90ee90", "lightgrey" => "#d3d3d3", "lightpink" => "#ffb6c1", "lightsalmon" => "#ffa07a", "lightseagreen" => "#20b2aa", "lightskyblue" => "#87cefa", "lightslategray" => "#778899", "lightslategrey" => "#778899", "lightsteelblue" => "#b0c4de", "lightyellow" => "#ffffe0", "lime" => "#00ff00", "limegreen" => "#32cd32", "linen" => "#faf0e6", "magenta" => "#ff00ff", "maroon" => "#800000", "mediumaquamarine" => "#66cdaa", "mediumblue" => "#0000cd", "mediumorchid" => "#ba55d3", "mediumpurple" => "#9370db", "mediumseagreen" => "#3cb371", "mediumslateblue" => "#7b68ee", "mediumspringgreen" => "#00fa9a", "mediumturquoise" => "#48d1cc", "mediumvioletred" => "#c71585", "midnightblue" => "#191970", "mintcream" => "#f5fffa", "mistyrose" => "#ffe4e1", "moccasin" => "#ffe4b5", "navajowhite" => "#ffdead", "navy" => "#000080", "oldlace" => "#fdf5e6", "olive" => "#808000", "olivedrab" => "#6b8e23", "orange" => "#ffa500", "orangered" => "#ff4500", "orchid" => "#da70d6", "palegoldenrod" => "#eee8aa", "palegreen" => "#98fb98", "paleturquoise" => "#afeeee", "palevioletred" => "#db7093", "papayawhip" => "#ffefd5", "peachpuff" => "#ffdab9", "peru" => "#cd853f", "pink" => "#ffc0cb", "plum" => "#dda0dd", "powderblue" => "#b0e0e6", "purple" => "#800080", "red" => "#ff0000", "rosybrown" => "#bc8f8f", "royalblue" => "#4169e1", "saddlebrown" => "#8b4513", "salmon" => "#fa8072", "sandybrown" => "#f4a460", "seagreen" => "#2e8b57", "seashell" => "#fff5ee", "sienna" => "#a0522d", "silver" => "#c0c0c0", "skyblue" => "#87ceeb", "slateblue" => "#6a5acd", "slategray" => "#708090", "slategrey" => "#708090", "snow" => "#fffafa", "springgreen" => "#00ff7f", "steelblue" => "#4682b4", "tan" => "#d2b48c", "teal" => "#008080", "thistle" => "#d8bfd8", "tomato" => "#ff6347", "turquoise" => "#40e0d0", "violet" => "#ee82ee", "wheat" => "#f5deb3", "white" => "#ffffff", "whitesmoke" => "#f5f5f5", "yellow" => "#ffff00", "yellowgreen" => "#9acd32" ); $colornames = array_flip($namedcolors); 

Вы можете использовать такую ​​функцию, чтобы осветлить цвет:

 function lighten(color, factor) { factor = factor || 0.4; var lighter = '#'; for(var i = 1; i < 6; i += 2) { var part = parseInt(color.substr(i, 2), 16); part += Math.round((255 - part) * 0.4); lighter += (part < 16 ? '0' : '') + part.toString(16); } return lighter; } lighten('#ececec'); // returns '#f4f4f4' 

Это равномерно осветляет цвета на процент, а не фиксированную сумму.

Вам нужно проверить шестерку, чтобы увидеть, если это 3 (444) или 6 дегт (444444), а затем разделить каждый RGB на целое число из шестнадцатеричного.

Затем выберите пороговое значение того, насколько ближе к тому, что вы хотите (предположите, что он разделяет разницу).

66hex = 102dec.

пол ((255-102) / 2) = 76.

правильный цвет 102 + 76 = 178

178дек = B2hex.

B2 будет вашим новым значением (а не 66)

Вам нужно будет сделать это для всех трех гексагонов.

 var colorString=$(selector).css("background-color"); var colorInt=parseInt(colorString.replace('#',''),16); colorInt+=parseInt("080808",16); var newColor = "#" + colorInt.toString(16); $(selector).css("border-color", newColor); 

Код Хью Ботвелла, кажется, дает иногда странные ответы. При преобразовании, т.е. RGB # eb69ff в HSL дает 0.751567320261 1.67763157895 0.703125

При функции rgb2hsl ($ rgbtrio)
if ( $L < 0.5 ) $s = $max / ( $max + $min );
else $s = $max / ( 2 - $max - $min );

Должен ли этот код

if ( $L < 0.5 ) $s = ($max - $min) / ( $max + $min );
else $s = ($max - $min) / ( 2 - $max - $min );

По крайней мере после этого я могу получить разумные значения RGB при использовании RGBinterpolate ($ start, $ end, $ dist)

Использование jQuery:

 $(selector).css('border-color', '#f4f4f4') 

Замените selector селектором, который будет соответствовать элементам, которые вы хотите изменить. Трудно написать это для вас без HTML-кода.

Я бы выполнил выбор цвета, как этот . Это наиболее удобное для пользователя действие и не сложно реализовать. С помощью метода onSubmit ().

 $(".picker").ColorPicker({ onSubmit: function(hsb, hex, rgb, el){ $(el).css({ 'background-color': '#' + hex }); $(el).ColorPickerHide(); } }); 

В моем случае «el» – это div, который я хочу изменить.

Недавно работая над добавлением цветовых схем на платформу Lablz webapp, нам нужно было решить ту же проблему. Решение, предложенное Хью Ботвелл, указывает в правильном направлении, но имеет проблему. Хью говорит, что после преобразования из RGB в HSL вам нужно интерполировать Hue, Saturation и Luminosity. Но для создания оттенков одного цвета вам нужно только управлять яркостью (яркостью), иначе вы получите другой цвет. Мы используем этот подход на стороне сервера (на Java), чтобы создавать вариации цветов, генерируемые http://colorschemedesigner.com . Мы также используем Luminosity для определения и корректировки контраста между цветами, чтобы мы никогда не заканчивали цветным текстом, нечитаемым на цветном фоне.

Прежде чем приступить к этому подходу, мы попытались манипулировать цветовым пространством RGB, как упоминалось во многих других ответах здесь, и переходом от RGB к HSB и изменением яркости. HSL дал наилучшие результаты, так как он доходит до малейших оттенков ближе к белому, в то время как манипуляция с яркостью в HSB приведет только к вам, например, к горчичному цвету, когда яркость, например, увеличена до максимума от коричневого.

Если хотите, я могу опубликовать код Java, который мы разработали.