جاوااسکریپت - برنامهنویسی برای روشنتر یا تیرهتر کردن یک رنگ هگز (یا RGB، و ترکیب رنگها)
در اینجا یک تابع است که من روی آن کار میکردم تا بهصورت برنامهنویسی رنگ هگز را به میزان مشخصی روشنتر یا تیرهتر کند. فقط یک رشته مانند "3F6D2A" را برای رنگ (col) و یک عدد در پایه ۱۰ (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);
}
// TEST
console.log( LightenDarkenColor("3F6D2A",40) );برای توسعه، در اینجا نسخهای آسانتر برای خواندن وجود دارد:
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);
}
// TEST
console.log(LightenDarkenColor("3F6D2A", -40));و در نهایت نسخهای برای مدیریت رنگهایی که ممکن است (یا ممکن است نه) در ابتدا «#» داشته باشند. به علاوه تنظیم برای مقادیر رنگ نامناسب:
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);
حدس میزنم سوال اصلی من این است که آیا درست میگویم؟ آیا این شامل اکثر موقعیتهای (عادی) نمیشود؟ و اگر چنین است، سریعترین و کوچکترین راه برای انجام این کار چیست؟ من میخواهم این را در انیمیشنها و در یک محیط کوچک استفاده کنم، بنابراین سرعت اولین عامل مهم است، اندازه دوم، دقت سوم، خوانایی؟ ها؟ در لیست نیازها نیست (متاسفم، میدانم نصف شما همین الآن چشمتان را دارد میکند!).
پاسخ شماره ۱
خب، این جواب خودش به یک موجود مستقل تبدیل شده است. نسخههای جدید زیادی داشت و خیلی طولانی و احمقانه میشد. از تمام مشارکتکنندگان فوقالعاده در این جواب بسیار سپاسگزارم. اما برای اینکه آن را برای عموم ساده نگه داریم، من تمام نسخهها/تاریخچه تکامل این پاسخ را در گیتهاب خود آرشیو کردم. و دوباره در StackOverflow این پاسخ را با نسخهی جدید شروع کردم. تشکر ویژهای نثار مایک 'Pomax' کامرمنز برای این نسخه میکنم. او ریاضیات جدید را به من داد.
این تابع (pSBC) یک رنگ وب به صورت HEX یا RGB میگیرد. pSBC میتواند آن را تیرهتر یا روشنتر کند، یا با یک رنگ دوم ترکیب کند، و همچنین میتواند آن را مستقیماً عبور دهد اما از Hex به RGB (Hex2RGB) یا از RGB به Hex (RGB2Hex) تبدیل کند. همه اینها بدون اینکه شما حتی بدانید از چه فرمت رنگی استفاده میکنید.
این واقعاً سریع اجرا میشود، احتمالاً سریعترین است، به ویژه با در نظر گرفتن ویژگیهای متعدد آن. مدت زیادی طول کشید تا ساخته شود. کل داستان را در گیتهاب من ببینید. اگر میخواهید کوچکترین و سریعترین روش ممکن برای سایه زدن یا مخلوط کردن را داشته باشید، به توابع میکرو در زیر نگاه کنید و از یکی از شتابدهندههای دو خطی استفاده کنید. آنها برای انیمیشنهای شدید عالی هستند، اما این نسخه اینجا برای اکثر انیمیشنها کافی سریع است.
این تابع از ترکیب لگاریتمی یا ترکیب خطی استفاده میکند. با این حال، این تابع به HSL تبدیل نمیشود تا رنگ را به طور صحیح روشن یا تیره کند. بنابراین، نتایج این تابع ممکن است متفاوت باشند با آن توابع بسیار بزرگتر و کندتر که از HSL استفاده میکنند (مانند TinyColor؟ که در مقایسه نسبتاً بزرگ است).
jsFiddle با pSBC
گیتهاب > ویکی pSBC
ویژگیها:
- به صورت خودکار رنگهای هگز استاندارد را به شکل رشتهها تشخیص داده و میپذیرد. برای مثال:
"#AA6622"یا"#bb551144". - بهطور خودکار رنگهای استاندارد RGB را در قالب رشتهها تشخیص داده و میپذیرد. برای مثال:
"rgb(123,45,76)"یا"rgba(45,15,74,0.45)". - رنگها را با درصد به سفید یا سیاه تغییر میدهد.
- رنگها را با درصد با هم ترکیب میکند.
- آیا تبدیل Hex2RGB و RGB2Hex همزمان انجام میشود یا جداگانه.
- کدهای رنگ هگز ۳ رقمی (یا ۴ رقمی با حروف الفبا) را میپذیرد، به شکل #RGB (یا #RGBA). این کدها را گسترش خواهد داد. برای مثال:
"#C41"به"#CC4411"تبدیل میشود. - کانالهای آلفا را میپذیرد و ترکیبهای (خطی) آنها را انجام میدهد. اگر یکی از رنگهای
c0(مبدأ) یاc1(مقصد) دارای کانال آلفا باشد، رنگ بازگشتی نیز کانال آلفا خواهد داشت. اگر هر دو رنگ کانال آلفا داشته باشند، رنگ بازگشتی ترکیبی خطی از دو کانال آلفا با درصد داده شده خواهد بود (همانطور که اگر کانال رنگ عادی بود). اگر تنها یکی از دو رنگ کانال آلفا داشته باشد، این آلفا مستقیماً به رنگ بازگشتی منتقل خواهد شد. این امکان را میدهد تا یک رنگ شفاف را مخلوط/سایهدار کرد در حالی که سطح شفافیت حفظ شود. یا، اگر سطح شفافیتها نیز باید مخلوط شوند، اطمینان حاصل کنید که هر دو رنگ دارای آلفا هستند. هنگام سایه زدن، کانال آلفا به طور مستقیم عبور میکند. اگر سایه زدن سادهای میخواهید که همچنین کانال آلفا را هم سایه دهد، ازrgb(0,0,0,1)یاrgb(255,255,255,1)به عنوان رنگc1(به) استفاده کنید (یا معادلهای هگز آنها). برای رنگهای RGB، کانال آلفای رنگ بازگشتی تا سه رقم اعشار گرد میشود. - تبدیلهای RGB2Hex و Hex2RGB هنگام استفاده از ترکیببندی به صورت ضمنی انجام میشوند. بدون توجه به رنگ
c0(از)، رنگ بازگردانده شده همیشه در قالب رنگc1(به) خواهد بود، اگر چنین رنگی موجود باشد. اگر رنگc1(به) موجود نباشد، میتوانید'c'را به عنوان رنگc1وارد کنید و رنگ هرچهc0باشد، سایهدار و تبدیل خواهد شد. اگر فقط تبدیل مد نظر باشد، میتوانید مقدار0را به عنوان درصد (p) وارد کنید. اگر رنگc1حذف شود یا یک مقدار غیر ازstringوارد شود، تبدیل انجام نخواهد شد. - یک عملکرد ثانویه نیز به سطح جهانی اضافه شده است.
pSBCrمیتواند یک رنگ به صورت هگز یا RGB دریافت کند و یک شی حاوی اطلاعات این رنگ را برمیگرداند. این اطلاعات به شکل زیر است: {r: XXX, g: XXX, b: XXX, a: X.XXX}. جایی که.r،.gو.bدر بازه ۰ تا ۲۵۵ هستند. و زمانی که آلفا وجود ندارد:.aبرابر با -۱ است. در غیر این صورت:.aدر بازه ۰.۰۰۰ تا ۱.۰۰۰ قرار دارد. - برای خروجی RGB، زمانی که یک رنگ با کانال آلفا به
c0(از) و/یاc1(به) داده شود،rgba()را به جایrgb()خروجی میدهد. - بررسی خطاهای جزئی اضافه شده است. این کامل نیست. هنوز ممکن است خراب شود یا خروجی نامفهوم تولید کند. اما برخی موارد را میتواند شناسایی کند. اساساً، اگر ساختار به برخی روشها اشتباه باشد یا درصد عدد نباشد یا خارج از محدوده باشد،
nullبرمیگرداند. یک مثال:pSBC(0.5,"salt") == null، در حالی که فکر میکند#saltیک رنگ معتبر است. برای حذف این ویژگی و افزایش سرعت و کوچکتر کردن، چهار خطی که باreturn null;پایان مییابند را حذف کنید. - از ادغام لگاریتمی استفاده میکند. برای
l(چهارمین پارامتر) مقدارtrueرا وارد کنید تا از ادغام خطی استفاده شود.
کد :
// 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=this.pSBCr(c0),P=p<0,t=c1&&c1!="c"?this.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 خیلی کند مینویسد و برای یک دو خط ساده حالتهای زیادی دارد (به عنوان مثال، میتواند یک کد 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,j=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)+j;
}
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,j=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)+j;
}
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:")");
}
میخواهید اطلاعات بیشتری داشته باشید؟ نوشته کامل را در گیتهاب بخوانید.
پیتی
(پ.ن. اگر کسی فرمول ریاضی روش ترکیب دیگری دارد، لطفاً به اشتراک بگذارد.)
پاسخ شماره ۲
من یک راهحل درست کردم که برای من خیلی خوب کار میکند:
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;
R = Math.round(R)
G = Math.round(G)
B = Math.round(B)
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;
}
مثال روشن کردن:
shadeColor("#63C6FF",40);
مثال تار کردن:
shadeColor("#63C6FF",-40);
پاسخ شماره ۳
در اینجا یک خط ساده فوقالعاده بر اساس جواب اریک وجود دارد
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"
پاسخ شماره ۴
من اینجا دو سنت خودم را اضافه میکنم، ترکیبی رضایتبخش و کوچک از پاسخهای مختلف:
const colorShade = (col, amt) => {
col = col.replace(/^#/, '')
if (col.length === 3) col = col[0] + col[0] + col[1] + col[1] + col[2] + col[2]
let [r, g, b] = col.match(/.{2}/g);
([r, g, b] = [parseInt(r, 16) + amt, parseInt(g, 16) + amt, parseInt(b, 16) + amt])
r = Math.max(Math.min(255, r), 0).toString(16)
g = Math.max(Math.min(255, g), 0).toString(16)
b = Math.max(Math.min(255, b), 0).toString(16)
const rr = (r.length < 2 ? '0' : '') + r
const gg = (g.length < 2 ? '0' : '') + g
const bb = (b.length < 2 ? '0' : '') + b
return `#${rr}${gg}${bb}`
}
یک رنگ که با # شروع میشود را قبول میکند یا نه، با ۶ کاراکتر یا ۳ کاراکتر.
نمونه استفاده: colorShade('#54b946', -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;
}

