Программно осветить или затемнить гексагон (или цвета rgb и blend)
Вот функция, над которой я работал, чтобы программно осветлить или затемнить гексаговый цвет на определенную сумму. Просто передайте строку типа "3F6D2A"
для цвета (col
) и base10 integer (amt
) для уменьшения или затемнения. Чтобы затемнить, проведите отрицательное число (т.е. -20).
Причина, по которой я это сделала, была из-за всех решений, которые я нашел, до сих пор они, казалось, слишком усложняли проблему. И у меня было ощущение, что это можно сделать только с помощью пары строк кода. Пожалуйста, дайте мне знать, если у вас возникнут какие-либо проблемы или какие-либо корректировки, чтобы ускорить его.
function LightenDarkenColor(col,amt) {
col = parseInt(col,16);
return (((col & 0x0000FF) + amt) | ((((col>> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16);
}
Для разработки используйте здесь более читаемую версию:
function LightenDarkenColor(col,amt) {
var num = parseInt(col,16);
var r = (num >> 16) + amt;
var b = ((num >> 8) & 0x00FF) + amt;
var g = (num & 0x0000FF) + amt;
var newColor = g | (b << 8) | (r << 16);
return newColor.toString(16);
}
И, наконец, версия для обработки цветов, которые могут (или не могут) иметь "#" в начале. Плюс регулировка для неправильных значений цвета:
function LightenDarkenColor(col,amt) {
var usePound = false;
if ( col[0] == "#" ) {
col = col.slice(1);
usePound = true;
}
var num = parseInt(col,16);
var r = (num >> 16) + amt;
if ( r > 255 ) r = 255;
else if (r < 0) r = 0;
var b = ((num >> 8) & 0x00FF) + amt;
if ( b > 255 ) b = 255;
else if (b < 0) b = 0;
var g = (num & 0x0000FF) + amt;
if ( g > 255 ) g = 255;
else if ( g < 0 ) g = 0;
return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}
ОК, так что теперь это не просто пара строк, но это кажется намного проще, и если вы не используете "#" и не нуждаетесь в проверке цветов вне диапазона, это всего лишь пара строк.
Если вы не используете "#", вы можете просто добавить его в код, например:
var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);
Думаю, мой главный вопрос: я исправлю здесь? Разве это не охватывает некоторые (обычные) ситуации?
Ответы
Ответ 1
Ну, этот ответ стал своим собственным зверем. Много новых версий, это было глупо долго. Большое спасибо всем великим авторам этого ответа. Но, чтобы все было просто для масс. Я заархивировал все версии/историю развития этого ответа на свой github. И началось все заново на Qaru с самой новой версией. Особая благодарность Майку 'Pomax' Kamermans за эту версию. Он дал мне новую математику.
Эта функция (pSBC
) будет принимать веб-цвет HEX или RGB. pSBC
может затенить его темнее или светлее или смешать со вторым цветом, а также может передать его прямо через него, но конвертировать из шестнадцатеричного в RGB (Hex2RGB) или из шестнадцатеричного RGB в RGB (RGB2Hex). Все без вас, даже не зная, какой цветовой формат вы используете.
Это работает очень быстро, вероятно, самый быстрый, особенно учитывая его многочисленные функции. Это было долгое время в процессе создания. Смотрите всю историю на моем github. Если вы хотите абсолютно наименьший и самый быстрый способ затенения или смешивания, посмотрите Микро-функции ниже и используйте одного из демонов скорости с 2-мя слоями. Они отлично подходят для интенсивной анимации, но эта версия достаточно быстра для большинства анимаций.
Эта функция использует Log Blending или Linear Blending. Тем не менее, он не конвертируется в HSL, чтобы правильно осветлить или затемнить цвет. Следовательно, результаты этой функции будут отличаться от тех функций, которые намного больше и медленнее, использующих HSL.
jsFiddle with pSBC
github > pSBC Wiki
Особенности:
- Автоматически определяет и принимает стандартные шестнадцатеричные цвета в виде строк. Например:
"#AA6622"
или "#bb551144"
.
- Автоматически определяет и принимает стандартные цвета RGB в виде строк. Например:
"rgb(123,45,76)"
или "rgba(45,15,74,0.45)"
.
- Оттенки цветов к белому или черному в процентах.
- Смешивает цвета вместе в процентах.
- Выполняет ли преобразование Hex2RGB и RGB2Hex одновременно или соло.
- Принимает 3-значные (или 4-значные w/alpha) цветовые коды HEX в форме #RGB (или #RGBA). Это расширит их. Например:
"#C41"
становится "#CC4411"
.
- Принимает и (линейный) смешивает альфа-каналы. Если либо цвет
c0
(from), либо цвет c1
(to) имеет альфа-канал, то возвращаемый цвет будет иметь альфа-канал. Если оба цвета имеют альфа-канал, то возвращаемый цвет будет представлять собой линейную смесь двух альфа-каналов с использованием заданного процента (как если бы это был обычный цветовой канал). Если только один из двух цветов имеет альфа-канал, эта альфа будет просто передана возвращаемому цвету. Это позволяет смешивать/затенять прозрачный цвет, сохраняя уровень прозрачности. Или, если уровни прозрачности также должны смешиваться, убедитесь, что оба цвета имеют альфа. Когда затенение, это пройдет альфа-канал прямо через. Если вам нужна базовая заливка, которая также затеняет альфа-канал, тогда используйте rgb(0,0,0,1)
или rgb(255,255,255,1)
в качестве цвета c1
(to) (или их шестнадцатеричных эквивалентов). Для цветов RGB возвращаемый альфа-канал цвета будет округлен до 3 десятичных знаков.
- Преобразования RGB2Hex и Hex2RGB неявны при использовании смешивания. Независимо от цвета
c0
(от); возвращаемый цвет всегда будет в формате цвета c1
(to), если он существует. Если цвет c1
(to) отсутствует, то передайте 'c'
в качестве цвета c1
, и он закрасит и преобразует любой цвет c0
. Если требуется только преобразование, то передайте 0
в процентах (p
). Если цвет c1
пропущен или передан ложный текст, он не будет преобразован.
- Вторичная функция также добавлена к глобальной.
pSBCr
может передаваться цвет Hex или RGB, и он возвращает объект, содержащий эту информацию о цвете. Это в форме: {r: XXX, g: XXX, b: XXX, a: X.XXX}. Где .r
, .g
и .b
имеют диапазон от 0 до 255. А когда нет альфа: .a
равно -1. В противном случае: .a
имеет диапазон от 0,000 до 1000.
- Для вывода RGB выводится
rgba()
через rgb()
, когда цвет с альфа-каналом был передан в c0
(from) и/или c1
(to).
- Была добавлена проверка незначительных ошибок. Это не идеально. Это все еще может привести к сбою или созданию тряски. Но это поймает некоторые вещи. По сути, если структура в некотором смысле неверна, или если процент не является числом или выходит за рамки, он вернет
null
. Пример: pSBC(0.5,"salt") == null
, где, как он думает, #salt
является допустимым цветом. Удалите четыре строки, заканчивающиеся на return null;
, чтобы удалить эту функцию и сделать ее быстрее и меньше.
- Использует смешивание журналов. Передайте
true
для l
(четвертый параметр), чтобы использовать линейное смешивание.
Код:
// Version 4.0
const pSBC=(p,c0,c1,l)=>{
let r,g,b,P,f,t,h,i=parseInt,m=Math.round,a=typeof(c1)=="string";
if(typeof(p)!="number"||p<-1||p>1||typeof(c0)!="string"||(c0[0]!='r'&&c0[0]!='#')||(c1&&!a))return null;
if(!this.pSBCr)this.pSBCr=(d)=>{
let n=d.length,x={};
if(n>9){
[r,g,b,a]=d=d.split(","),n=d.length;
if(n<3||n>4)return null;
x.r=i(r[3]=="a"?r.slice(5):r.slice(4)),x.g=i(g),x.b=i(b),x.a=a?parseFloat(a):-1
}else{
if(n==8||n==6||n<4)return null;
if(n<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(n>4?d[4]+d[4]:"");
d=i(d.slice(1),16);
if(n==9||n==5)x.r=d>>24&255,x.g=d>>16&255,x.b=d>>8&255,x.a=m((d&255)/0.255)/1000;
else x.r=d>>16,x.g=d>>8&255,x.b=d&255,x.a=-1
}return x};
h=c0.length>9,h=a?c1.length>9?true:c1=="c"?!h:false:h,f=pSBCr(c0),P=p<0,t=c1&&c1!="c"?pSBCr(c1):P?{r:0,g:0,b:0,a:-1}:{r:255,g:255,b:255,a:-1},p=P?p*-1:p,P=1-p;
if(!f||!t)return null;
if(l)r=m(P*f.r+p*t.r),g=m(P*f.g+p*t.g),b=m(P*f.b+p*t.b);
else r=m((P*f.r**2+p*t.r**2)**0.5),g=m((P*f.g**2+p*t.g**2)**0.5),b=m((P*f.b**2+p*t.b**2)**0.5);
a=f.a,t=t.a,f=a>=0||t>=0,a=f?a<0?t:t<0?a:a*P+t*p:0;
if(h)return"rgb"+(f?"a(":"(")+r+","+g+","+b+(f?","+m(a*1000)/1000:"")+")";
else return"#"+(4294967296+r*16777216+g*65536+b*256+(f?m(a*255):0)).toString(16).slice(1,f?undefined:-2)
}
Использование:
// Setup:
let color1 = "rgb(20,60,200)";
let color2 = "rgba(20,60,200,0.67423)";
let color3 = "#67DAF0";
let color4 = "#5567DAF0";
let color5 = "#F3A";
let color6 = "#F3A9";
let color7 = "rgb(200,60,20)";
let color8 = "rgba(200,60,20,0.98631)";
// Tests:
/*** Log Blending ***/
// Shade (Lighten or Darken)
pSBC ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(166,171,225)
pSBC ( -0.4, color5 ); // #F3A + [40% Darker] => #c62884
pSBC ( 0.42, color8 ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(225,171,166,0.98631)
// Shade with Conversion (use "c" as your "to" color)
pSBC ( 0.42, color2, "c" ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #a6abe1ac
// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
pSBC ( 0, color6, "c" ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)
// Blending
pSBC ( -0.5, color2, color8 ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(142,60,142,0.83)
pSBC ( 0.7, color2, color7 ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(168,60,111,0.67423)
pSBC ( 0.25, color3, color7 ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(134,191,208)
pSBC ( 0.75, color7, color3 ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #86bfd0
/*** Linear Blending ***/
// Shade (Lighten or Darken)
pSBC ( 0.42, color1, false, true ); // rgb(20,60,200) + [42% Lighter] => rgb(119,142,223)
pSBC ( -0.4, color5, false, true ); // #F3A + [40% Darker] => #991f66
pSBC ( 0.42, color8, false, true ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(223,142,119,0.98631)
// Shade with Conversion (use "c" as your "to" color)
pSBC ( 0.42, color2, "c", true ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #778edfac
// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
pSBC ( 0, color6, "c", true ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)
// Blending
pSBC ( -0.5, color2, color8, true ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.83)
pSBC ( 0.7, color2, color7, true ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423)
pSBC ( 0.25, color3, color7, true ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(127,179,185)
pSBC ( 0.75, color7, color3, true ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #7fb3b9
/*** Other Stuff ***/
// Error Checking
pSBC ( 0.42, "#FFBAA" ); // #FFBAA + [42% Lighter] => null (Invalid Input Color)
pSBC ( 42, color1, color5 ); // rgb(20,60,200) + #F3A + [4200% Blend] => null (Invalid Percentage Range)
pSBC ( 0.42, {} ); // [object Object] + [42% Lighter] => null (Strings Only for Color)
pSBC ( "42", color1 ); // rgb(20,60,200) + ["42"] => null (Numbers Only for Percentage)
pSBC ( 0.42, "salt" ); // salt + [42% Lighter] => null (A Little Salt is No Good...)
// Error Check Fails (Some Errors are not Caught)
pSBC ( 0.42, "#salt" ); // #salt + [42% Lighter] => #a5a5a500 (...and a Pound of Salt is Jibberish)
// Ripping
pSBCr ( color4 ); // #5567DAF0 + [Rip] => [object Object] => {'r':85,'g':103,'b':218,'a':0.941}
Картинка ниже поможет показать разницу в двух методах наложения:
Микро-функции
Если вы действительно хотите скорость и размер, вам придется использовать RGB, а не HEX. RGB более прост и прост, HEX пишет слишком медленно и имеет слишком много разновидностей для простого двухстрочного (т.е. это может быть 3, 4, 6 или 8-значный код HEX). Вам также придется пожертвовать некоторыми функциями, без проверки ошибок, без HEX2RGB и RGB2HEX. Кроме того, вам нужно будет выбрать конкретную функцию (на основе ее имени ниже) для математики смешивания цветов, а также, если вы хотите, чтобы затемнение или смешивание. Эти функции поддерживают альфа-каналы. И когда оба входных цвета имеют альфы, они будут линейно смешаны. Если только у одного из двух цветов есть альфа, он передаст его прямо к полученному цвету. Ниже приведены две невероятно быстрые и небольшие функции лайнера:
const RGB_Linear_Blend=(p,c0,c1)=>{
var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,d=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
return"rgb"+(x?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+i(e[3]=="a"?e.slice(5):e.slice(4))*p)+","+r(i(b)*P+i(f)*p)+","+r(i(c)*P+i(g)*p)+d;
}
const RGB_Linear_Shade=(p,c)=>{
var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:255*p,P=P?1+p:1-p;
return"rgb"+(d?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+t)+","+r(i(b)*P+t)+","+r(i(c)*P+t)+(d?","+d:")");
}
const RGB_Log_Blend=(p,c0,c1)=>{
var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,d=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
return"rgb"+(x?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+p*i(e[3]=="a"?e.slice(5):e.slice(4))**2)**0.5)+","+r((P*i(b)**2+p*i(f)**2)**0.5)+","+r((P*i(c)**2+p*i(g)**2)**0.5)+d;
}
const RGB_Log_Shade=(p,c)=>{
var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:p*255**2,P=P?1+p:1-p;
return"rgb"+(d?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+t)**0.5)+","+r((P*i(b)**2+t)**0.5)+","+r((P*i(c)**2+t)**0.5)+(d?","+d:")");
}
Хотите узнать больше? Прочитайте полный текст статьи на github.
PT
(P.s. Если у кого-то есть математика для другого метода смешивания, пожалуйста, поделитесь.)
Ответ 2
Я сделал решение, которое работает очень хорошо для меня:
function shadeColor(color, percent) {
var R = parseInt(color.substring(1,3),16);
var G = parseInt(color.substring(3,5),16);
var B = parseInt(color.substring(5,7),16);
R = parseInt(R * (100 + percent) / 100);
G = parseInt(G * (100 + percent) / 100);
B = parseInt(B * (100 + percent) / 100);
R = (R<255)?R:255;
G = (G<255)?G:255;
B = (B<255)?B:255;
var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));
return "#"+RR+GG+BB;
}
Пример Lighten:
shadeColor("#63C6FF",40);
Пример Darken:
shadeColor("#63C6FF",-40);
Ответ 3
Вы подумали о преобразовании rgb > hsl? то просто переместите Светимость вверх и вниз? вот как я пойду.
Быстрый поиск некоторых алгоритмов дал мне следующие сайты.
PHP:
http://serennu.com/colour/rgbtohsl.php
Javascript:
http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
EDIT вышеуказанная ссылка больше не действительна. Вы можете просмотреть концентратор git для источника страницы или gist
В качестве альтернативы вам может понадобиться другой StackOverflow question.
Несмотря на то, что это не правильный выбор для OP, это приближение кода, который я изначально предлагал. (Предполагая, что у вас есть функции преобразования rgb/hsl)
var SHADE_SHIFT_AMOUNT = 0.1;
function lightenShade(colorValue)
{
if(colorValue && colorValue.length >= 6)
{
var redValue = parseInt(colorValue.slice(-6,-4), 16);
var greenValue = parseInt(colorValue.slice(-4,-2), 16);
var blueValue = parseInt(colorValue.slice(-2), 16);
var hsl = rgbToHsl(redValue, greenValue, blueValue);
hsl[2]= Math.min(hsl[2] + SHADE_SHIFT_AMOUNT, 1);
var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
}
return null;
}
function darkenShade(colorValue)
{
if(colorValue && colorValue.length >= 6)
{
var redValue = parseInt(colorValue.slice(-6,-4), 16);
var greenValue = parseInt(colorValue.slice(-4,-2), 16);
var blueValue = parseInt(colorValue.slice(-2), 16);
var hsl = rgbToHsl(redValue, greenValue, blueValue);
hsl[2]= Math.max(hsl[2] - SHADE_SHIFT_AMOUNT, 0);
var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
}
return null;
}
Это предполагает:
- У вас есть функции
hslToRgb
и rgbToHsl
.
- Параметр
colorValue
представляет собой строку в форме #RRGGBB
Хотя, если мы обсуждаем css, есть синтаксис для указания hsl/hsla для IE9/Chrome/Firefox.
Ответ 4
Я попробовал вашу функцию, и была небольшая ошибка: если какое-то окончательное значение "r" имеет только 1 разряд, результат возникает, например: "a0a0a", когда правое значение - "0a0a0a", например.
Я просто быстро исправил это, добавив это вместо вашего возврата:
var rStr = (r.toString(16).length < 2)?'0'+r.toString(16):r.toString(16);
var gStr = (g.toString(16).length < 2)?'0'+g.toString(16):g.toString(16);
var bStr = (b.toString(16).length < 2)?'0'+b.toString(16):b.toString(16);
return (usePound?"#":"") + rStr + gStr + bStr;
Возможно, это не так хорошо, но это делает работу. Отличная функция, BTW. Только то, что мне было нужно.:)
Ответ 5
Это то, что я использовал на основе вашей функции. Я предпочитаю использовать шаги по проценту, потому что это более интуитивно для меня.
Например, 20% от значения 200 синих сильно отличаются от 20% от значения 40 синих.
В любом случае, здесь моя модификация, спасибо за вашу оригинальную функцию.
function adjustBrightness(col, amt) {
var usePound = false;
if (col[0] == "#") {
col = col.slice(1);
usePound = true;
}
var R = parseInt(col.substring(0,2),16);
var G = parseInt(col.substring(2,4),16);
var B = parseInt(col.substring(4,6),16);
// to make the colour less bright than the input
// change the following three "+" symbols to "-"
R = R + amt;
G = G + amt;
B = B + amt;
if (R > 255) R = 255;
else if (R < 0) R = 0;
if (G > 255) G = 255;
else if (G < 0) G = 0;
if (B > 255) B = 255;
else if (B < 0) B = 0;
var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));
return (usePound?"#":"") + RR + GG + BB;
}
Ответ 6
Я хотел изменить цвет на определенный уровень яркости - независимо от того, какой яркостью был цвет раньше - вот простая функция JS, которая, кажется, работает хорошо, хотя я уверен, что она может быть короче
function setLightPercentage(col: any, p: number) {
const R = parseInt(col.substring(1, 3), 16);
const G = parseInt(col.substring(3, 5), 16);
const B = parseInt(col.substring(5, 7), 16);
const curr_total_dark = (255 * 3) - (R + G + B);
// calculate how much of the current darkness comes from the different channels
const RR = ((255 - R) / curr_total_dark);
const GR = ((255 - G) / curr_total_dark);
const BR = ((255 - B) / curr_total_dark);
// calculate how much darkness there should be in the new color
const new_total_dark = ((255 - 255 * (p / 100)) * 3);
// make the new channels contain the same % of available dark as the old ones did
const NR = 255 - Math.round(RR * new_total_dark);
const NG = 255 - Math.round(GR * new_total_dark);
const NB = 255 - Math.round(BR * new_total_dark);
const RO = ((NR.toString(16).length === 1) ? "0" + NR.toString(16) : NR.toString(16));
const GO = ((NG.toString(16).length === 1) ? "0" + NG.toString(16) : NG.toString(16));
const BO = ((NB.toString(16).length === 1) ? "0" + NB.toString(16) : NB.toString(16));
return "#" + RO + GO + BO;}
Ответ 7
Вот супер простой вкладыш, основанный на ответе Эрика
function adjust(color, amount) {
return '#' + color.replace(/^#/, '').replace(/../g, color => ('0'+Math.min(255, Math.max(0, parseInt(color, 16) + amount)).toString(16)).substr(-2));
}
Примеры:
adjust('#ffffff', -20) => "#ebebeb"
adjust('000000', 20) => "#141414"
Ответ 8
Версия С#...
обратите внимание, что я получаю цветные строки в этом формате # FF12AE34, и вам нужно вырезать #FF.
private string GetSmartShadeColorByBase(string s, float percent)
{
if (string.IsNullOrEmpty(s))
return "";
var r = s.Substring(3, 2);
int rInt = int.Parse(r, NumberStyles.HexNumber);
var g = s.Substring(5, 2);
int gInt = int.Parse(g, NumberStyles.HexNumber);
var b = s.Substring(7, 2);
int bInt = int.Parse(b, NumberStyles.HexNumber);
var t = percent < 0 ? 0 : 255;
var p = percent < 0 ? percent*-1 : percent;
int newR = Convert.ToInt32(Math.Round((t - rInt) * p) + rInt);
var newG = Convert.ToInt32(Math.Round((t - gInt) * p) + gInt);
var newB = Convert.ToInt32(Math.Round((t - bInt) * p) + bInt);
return String.Format("#{0:X2}{1:X2}{2:X2}", newR, newG, newB);
}
Ответ 9
Следующий способ позволит вам осветлить или затемнить значение экспозиции шестнадцатеричной (шестнадцатеричной) цветовой строки:
private static string GetHexFromRGB(byte r, byte g, byte b, double exposure)
{
exposure = Math.Max(Math.Min(exposure, 1.0), -1.0);
if (exposure >= 0)
{
return "#"
+ ((byte)(r + ((byte.MaxValue - r) * exposure))).ToString("X2")
+ ((byte)(g + ((byte.MaxValue - g) * exposure))).ToString("X2")
+ ((byte)(b + ((byte.MaxValue - b) * exposure))).ToString("X2");
}
else
{
return "#"
+ ((byte)(r + (r * exposure))).ToString("X2")
+ ((byte)(g + (g * exposure))).ToString("X2")
+ ((byte)(b + (b * exposure))).ToString("X2");
}
}
Для последнего значения параметра в GetHexFromRGB() Pass в двойном значении где-то между -1 и 1 (-1 черный, 0 не изменяется, 1 - белый):
// split color (#e04006) into three strings
var r = Convert.ToByte("e0", 16);
var g = Convert.ToByte("40", 16);
var b = Convert.ToByte("06", 16);
GetHexFromRGB(r, g, b, 0.25); // Lighten by 25%;
Ответ 10
Как простой цвет тени в PHP?
<?php
function shadeColor ($color='#cccccc', $percent=-25) {
$color = Str_Replace("#",Null,$color);
$r = Hexdec(Substr($color,0,2));
$g = Hexdec(Substr($color,2,2));
$b = Hexdec(Substr($color,4,2));
$r = (Int)($r*(100+$percent)/100);
$g = (Int)($g*(100+$percent)/100);
$b = (Int)($b*(100+$percent)/100);
$r = Trim(Dechex(($r<255)?$r:255));
$g = Trim(Dechex(($g<255)?$g:255));
$b = Trim(Dechex(($b<255)?$b:255));
$r = ((Strlen($r)==1)?"0{$r}":$r);
$g = ((Strlen($g)==1)?"0{$g}":$g);
$b = ((Strlen($b)==1)?"0{$b}":$b);
return (String)("#{$r}{$g}{$b}");
}
echo shadeColor(); // #999999
Ответ 11
Я сделал порт превосходной библиотеки xcolor, чтобы удалить его зависимость jQuery. Там есть множество функций, включая светящиеся и затемняющие цвета.
Действительно, преобразование hex в RGB является полностью отдельной функцией от осветления или затемнения цветов. Держите вещи DRY, пожалуйста. В любом случае, если у вас есть цвет RGB, вы можете просто добавить разницу между желаемым уровнем света и уровнем освещенности, который у вас есть, для каждого из значений RGB:
var lightness = function(level) {
if(level === undefined) {
return Math.max(this.g,this.r,this.b)
} else {
var roundedLevel = Math.round(level) // fractions won't work here
var levelChange = roundedLevel - this.lightness()
var r = Math.max(0,this.r+levelChange)
var g = Math.max(0,this.g+levelChange)
var b = Math.max(0,this.b+levelChange)
if(r > 0xff) r = 0xff
if(g > 0xff) g = 0xff
if(b > 0xff) b = 0xff
return xolor({r: r, g: g, b: b})
}
}
var lighter = function(amount) {
return this.lightness(this.lightness()+amount)
}
Подробнее см. https://github.com/fresheneesz/xolor.
Ответ 12
Я давно хотел иметь возможность создавать оттенки/оттенки цветов, вот мое решение для JavaScript:
const varyHue = function (hueIn, pcIn) {
const truncate = function (valIn) {
if (valIn > 255) {
valIn = 255;
} else if (valIn < 0) {
valIn = 0;
}
return valIn;
};
let red = parseInt(hueIn.substring(0, 2), 16);
let green = parseInt(hueIn.substring(2, 4), 16);
let blue = parseInt(hueIn.substring(4, 6), 16);
let pc = parseInt(pcIn, 10); //shade positive, tint negative
let max = 0;
let dif = 0;
max = red;
if (pc < 0) { //tint: make lighter
if (green < max) {
max = green;
}
if (blue < max) {
max = blue;
}
dif = parseInt(((Math.abs(pc) / 100) * (255 - max)), 10);
return leftPad(((truncate(red + dif)).toString(16)), '0', 2) + leftPad(((truncate(green + dif)).toString(16)), '0', 2) + leftPad(((truncate(blue + dif)).toString(16)), '0', 2);
} else { //shade: make darker
if (green > max) {
max = green;
}
if (blue > max) {
max = blue;
}
dif = parseInt(((pc / 100) * max), 10);
return leftPad(((truncate(red - dif)).toString(16)), '0', 2) + leftPad(((truncate(green - dif)).toString(16)), '0', 2) + leftPad(((truncate(blue - dif)).toString(16)), '0', 2);
}
};