Lập trình Làm sáng hoặc Làm tối một màu hex (hoặc rgb, và pha trộn màu)


504

Đây là một chức năng tôi đang làm việc để làm sáng hoặc làm tối màu lục giác theo một lượng cụ thể. Chỉ cần truyền vào một chuỗi như "3F6D2A"cho màu ( col) và số nguyên base10 ( amt) cho số lượng sáng hoặc tối. Để làm tối, chuyển qua một số âm (nghĩa là -20).

Lý do để tôi làm điều này là vì tất cả các giải pháp tôi tìm thấy, cho đến nay, chúng dường như quá phức tạp hóa vấn đề. Và tôi có cảm giác nó có thể được thực hiện chỉ với một vài dòng mã. Vui lòng cho tôi biết nếu bạn tìm thấy bất kỳ vấn đề nào, hoặc có bất kỳ điều chỉnh nào để làm cho nó tăng tốc.

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

Để phát triển sử dụng ở đây là một phiên bản dễ đọc hơn:

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

Và cuối cùng, một phiên bản để xử lý các màu có thể (hoặc không) có "#" ở đầu. Cộng với việc điều chỉnh các giá trị màu không phù hợp:

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

OK, vì vậy bây giờ không chỉ là một vài dòng, mà có vẻ đơn giản hơn nhiều và nếu bạn không sử dụng "#" và không cần kiểm tra màu ngoài phạm vi, thì đó chỉ là một vài dòng.

Nếu không sử dụng "#", bạn có thể thêm nó vào mã như:

var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);

Tôi đoán câu hỏi chính của tôi là, tôi có đúng ở đây không? Điều này không bao gồm một số tình huống (bình thường)?


1
Nếu bạn không nhận được kết quả mong đợi khi sửa đổi màu sắc, tôi khuyên bạn nên xem xét không gian màu LAB, gần với tầm nhìn của con người hơn. Nhiều ngôn ngữ có thư viện để chuyển đổi. Theo kinh nghiệm của tôi, đặc biệt là sắc thái của màu cam có thể có vấn đề khi tối hoặc sáng.
Henrik

Điểm rất tốt. Tuy nhiên, mục đích chính của câu hỏi này là tìm ra, thứ nhất, thời gian chạy nhanh nhất và công thức kích thước nhỏ nhất ... và thứ hai, độ chính xác của nó. Do đó, tại sao tôi không giải quyết việc chuyển đổi sang HSL hoặc bất cứ điều gì. Ở đây tốc độ và kích thước là quan trọng hơn. Nhưng, như bạn có thể thấy với phiên bản 2 của công thức. Sử dụng LERP để tạo bóng râm sẽ tạo ra những quả cam dễ chịu xuyên qua phạm vi bóng râm. Hãy nhìn vào biểu đồ màu bên dưới và cho tôi biết nếu phạm vi bóng râm đó không gần với độ chính xác thực tế.
Pimp Trizkit

Tôi đã có một chút nhầm lẫn với cấu trúc ở đây, nhưng bạn nói đúng, các mức độ màu cam cho bóng râmColor1 dường như là rất tốt.
Henrik

Lol, ý bạn là bóng râmColor2. Tôi đoán cấu trúc bạn đang nói là bố cục tổng thể của câu trả lời? Bất kỳ gợi ý để làm rõ hơn?
Pimp Trizkit

3
Chỉ có một vấn đề trong hàm với # ở trên là nó không tạo ra các số 0 đứng đầu nếu mã hex cuối cùng bắt đầu bằng số không. Ví dụ: nếu mã hex là # 00a6b7, nó sẽ xuất ra dưới dạng # a6b7, mã này sẽ không hoạt động nếu sử dụng như một css. Bạn có thể sửa lỗi đó bằng cách thay thế dòng trả về bằng cách này: var string = "000000" + (g | (b << 8) | (r << 16)). ToString (16); return (usePound? "#": "") + string.substr (string.length-6);
Rafael Levy

Câu trả lời:


877

Vâng, câu trả lời này đã trở thành con thú của riêng nó. Nhiều phiên bản mới, nó đã trở nên ngu ngốc từ lâu. Rất cám ơn tất cả những người đóng góp rất nhiều cho câu trả lời này. Nhưng, để giữ cho nó đơn giản cho công chúng. Tôi đã lưu trữ tất cả các phiên bản / lịch sử của sự tiến hóa của câu trả lời này cho github của tôi . Và bắt đầu làm sạch trên StackOverflow tại đây với phiên bản mới nhất. Một lời cảm ơn đặc biệt dành cho Mike 'Pomax' Kamermans cho phiên bản này. Ông cho tôi môn toán mới.


Hàm này ( pSBC) sẽ lấy màu web HEX hoặc RGB. pSBCcó thể tô màu tối hơn hoặc nhạt hơn, hoặc pha trộn nó với màu thứ hai, và cũng có thể chuyển nó qua đúng nhưng chuyển đổi từ Hex sang RGB (Hex2RGB) hoặc RGB sang Hex (RGB2Hex). Tất cả mà không cần bạn biết định dạng màu nào bạn đang sử dụng.

Điều này chạy rất nhanh, có thể là nhanh nhất, đặc biệt là xem xét nhiều tính năng của nó. Đó là một thời gian dài trong việc thực hiện. Xem toàn bộ câu chuyện trên github của tôi . Nếu bạn muốn cách nhỏ nhất và nhanh nhất có thể để tạo bóng hoặc pha trộn, hãy xem các Hàm Micro bên dưới và sử dụng một trong những con quỷ tốc độ 2 lớp. Chúng rất tuyệt cho hoạt hình cường độ cao, nhưng phiên bản này ở đây đủ nhanh cho hầu hết các hoạt hình.

Chức năng này sử dụng Blend Blending hoặc Blend Blend tuyến tính. Tuy nhiên, nó KHÔNG chuyển đổi sang HSL để làm sáng hoặc làm tối màu đúng cách. Do đó, kết quả từ chức năng này sẽ khác với các chức năng lớn hơn và chậm hơn nhiều sử dụng HSL.

jsFiddle với pSBC

github> pSBC Wiki

Đặc trưng:

  • Tự động phát hiện và chấp nhận màu Hex tiêu chuẩn ở dạng chuỗi. Ví dụ: "#AA6622"hoặc "#bb551144".
  • Tự động phát hiện và chấp nhận màu RGB tiêu chuẩn ở dạng chuỗi. Ví dụ: "rgb(123,45,76)"hoặc "rgba(45,15,74,0.45)".
  • Tô màu cho màu trắng hoặc đen theo tỷ lệ phần trăm.
  • Pha trộn màu sắc với nhau theo tỷ lệ phần trăm.
  • Có chuyển đổi Hex2RGB và RGB2Hex cùng một lúc, hoặc solo.
  • Chấp nhận mã màu HEX 3 chữ số (hoặc 4 chữ số w / alpha), dưới dạng #RGB (hoặc #RGBA). Nó sẽ mở rộng chúng. Ví dụ: "#C41"trở thành "#CC4411".
  • Chấp nhận và (Tuyến tính) pha trộn các kênh alpha. Nếu c0màu (từ) hoặc màu c1(đến) có kênh alpha, thì màu được trả về sẽ có kênh alpha. Nếu cả hai màu đều có kênh alpha, thì màu được trả về sẽ là hỗn hợp tuyến tính của hai kênh alpha sử dụng tỷ lệ phần trăm đã cho (giống như đó là kênh màu bình thường). Nếu chỉ một trong hai màu có kênh alpha, thì alpha này sẽ được chuyển qua màu được trả về. Điều này cho phép một người pha trộn / tô màu một màu trong suốt trong khi duy trì mức độ trong suốt. Hoặc, nếu các mức trong suốt cũng hòa trộn, hãy đảm bảo cả hai màu đều có bảng chữ cái. Khi tô bóng, nó sẽ vượt qua kênh alpha thông qua. Nếu bạn muốn tạo bóng cơ bản cũng làm mờ kênh alpha, thì hãy sử dụng rgb(0,0,0,1)hoặc rgb(255,255,255,1)làmc1(đến) màu (hoặc tương đương hex của chúng). Đối với màu RGB, kênh alpha của màu được trả về sẽ được làm tròn đến 3 chữ số thập phân.
  • Chuyển đổi RGB2Hex và Hex2RGB ẩn khi sử dụng trộn. Bất kể c0màu (từ); màu được trả về sẽ luôn ở định dạng màu của màu c1(to), nếu có. Nếu không có c1màu (to), sau đó chuyển qua 'c'làm c1màu và nó sẽ chuyển sang màu và chuyển đổi bất kể c0màu gì . Nếu chỉ chuyển đổi là mong muốn, thì cũng chuyển qua 0phần trăm ( p). Nếu c1màu bị bỏ qua hoặc không stringđược truyền vào, nó sẽ không chuyển đổi.
  • Một chức năng phụ cũng được thêm vào toàn cầu. pSBCrcó thể được chuyển qua màu Hex hoặc RGB và nó trả về một đối tượng có chứa thông tin màu này. Nó có dạng: {r: XXX, g: XXX, b: XXX, a: X.XXX}. Trong đó .r, .g.bcó phạm vi từ 0 đến 255. Và khi không có alpha: .alà -1. Mặt khác: .acó phạm vi 0.000 đến 1.000.
  • Đối với đầu ra RGB, nó sẽ tạo ra rgba()hơn rgb()khi một màu sắc với một kênh alpha đã được thông qua vào c0(từ) và / hoặc c1(to).
  • Kiểm tra lỗi nhỏ đã được thêm vào. Nó không hoàn hảo. Nó vẫn có thể sụp đổ hoặc tạo ra jibberish. Nhưng nó sẽ bắt được một số thứ. Về cơ bản, nếu cấu trúc sai theo một số cách hoặc nếu tỷ lệ phần trăm không phải là một số hoặc nằm ngoài phạm vi, nó sẽ trả về null. Một ví dụ : pSBC(0.5,"salt") == null, nơi mà nó nghĩ #saltlà một màu hợp lệ. Xóa bốn dòng kết thúc bằng return null;để loại bỏ tính năng này và làm cho nó nhanh hơn và nhỏ hơn.
  • Sử dụng Trộn Log. Vượt qua truetrong cho l(tham số thứ 4) để sử dụng tuyến tính Blending.

Mã số:

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

Sử dụng:

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

Hình dưới đây sẽ giúp hiển thị sự khác biệt trong hai phương pháp trộn:


Chức năng vi mô

Nếu bạn thực sự muốn tốc độ và kích thước, bạn sẽ phải sử dụng RGB chứ không phải HEX. RGB đơn giản và đơn giản hơn, HEX viết quá chậm và có quá nhiều hương vị cho một lớp lót đơn giản (IE. Nó có thể là mã HEX 3, 4, 6 hoặc 8 chữ số). Bạn cũng sẽ cần phải hy sinh một số tính năng, không kiểm tra lỗi, không có HEX2RGB cũng như RGB2HEX. Đồng thời, bạn sẽ cần chọn một hàm cụ thể (dựa trên tên hàm của nó bên dưới) cho phép toán trộn màu và nếu bạn muốn tô bóng hoặc trộn. Các chức năng này hỗ trợ các kênh alpha. Và khi cả hai màu đầu vào có bảng chữ cái, nó sẽ pha trộn chúng. Nếu chỉ một trong hai màu có alpha, nó sẽ chuyển thẳng qua màu kết quả. Dưới đây là hai chức năng lót cực kỳ nhanh và nhỏ:

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

Muốn biết thêm thông tin? Đọc toàn bộ bài viết trên github .

PT

(Ps Nếu ai có toán cho phương pháp trộn khác, vui lòng chia sẻ.)


8
Phiên bản PHP cho những người cần nó: gist.github.com/chaoszcat/5325115#file-gistfile1-php
Lionel Chan

28
Tôi đã sử dụng TinyColor -tinycolor.darken(color,amount);
FWrnr

4
Bài đăng tuyệt vời ... :) ... vừa tạo tiện ích mở rộng Swift của nó: gist.github.com/matejukmar/1da47f7a950d1ba68a95
Matej Ukmar

2
Đây là phiên bản PHP cho phiên bản bóng râm được cập nhật: function shadeColor2($color, $percent) { $color = str_replace("#", "", $color); $t=$percent<0?0:255; $p=$percent<0?$percent*-1:$percent; $RGB = str_split($color, 2); $R=hexdec($RGB[0]); $G=hexdec($RGB[1]); $B=hexdec($RGB[2]); return '#'.substr(dechex(0x1000000+(round(($t-$R)*$p)+$R)*0x10000+(round(($t-$G)*$p)+$G)*0x100+(round(($t-$B)*$p)+$B)),1); }
Kevin M

2
Xin lỗi, tôi rõ ràng đã bỏ lỡ điểm đó. Có thể có hai lý do. Điều đầu tiên và rõ ràng là tôi sử dụng Math.Round và bạn không được sử dụng số thập phân để tô màu chính xác (màu sắc không có số thập phân trong hex). Ví dụ: nếu kênh Red là 8, hãy thêm 10%bạn 8.8vào vòng nào 9. Sau đó lấy 9.09%đi 9và bạn nhận được 8.1819. Đó 8là một ví dụ tồi tệ. Nhưng nó vẫn cho thấy rằng bạn đang dùng 9.09%của 9và không 8.8. Vì vậy, có thể có một số con số trong đó không làm tròn chính xác như ví dụ của tôi ở đây.
Pimp Trizkit

122

Tôi đã thực hiện một giải pháp hoạt động rất tốt cho tôi:

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

Ví dụ Lighten:

shadeColor("#63C6FF",40);

Ví dụ Darken:

shadeColor("#63C6FF",-40);

4
Đẹp, tôi thích tỷ lệ phần trăm! +1 Tho, tôi có thể làm R = ((R<255)?R:255).toString(16);sau đó R = R.length==1 ? "0"+R : Rcho tốc độ. Và tôi không chắc chắn điểm của toUpperCase?
Pimp Trizkit

Nó không cần thiết. Tôi chỉ thêm rằng để in đẹp trong khi thử nghiệm. Tôi sẽ chỉnh sửa nó.
Pablo

Rất đẹp. Tuy nhiên, có nên sáng hơn 100% không trở thành màu trắng hoàn toàn và tối 100% luôn có màu đen, bất kể màu gì? Dường như -100 không làm cho bất kỳ màu đen nào, nhưng 100 (tích cực) không làm cho nó hoàn toàn trắng.
Kevin M

4
không hoạt động với các màu đơn sắc như # ff0000, # 00ff00, # 0000ff
Hitori

Để làm cho nó hoạt động với màu đen, tôi chỉ cần thực hiện bản hack này var R = parseInt(color.substring(1, 3), 16) var G = parseInt(color.substring(3, 5), 16) var B = parseInt(color.substring(5, 7), 16) if (R == 0) R = 32; if (G == 0) G = 32; if (B == 0) B = 32;
Irfan Raza

21

Đây là một lớp lót siêu đơn giản dựa trên câu trả lời của Eric

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

Ví dụ:

adjust('#ffffff', -20) => "#ebebeb"
adjust('000000', 20) => "#141414"

7
"Siêu đơn giản".
Andrew

5

Đây là những gì tôi sử dụng dựa trên chức năng của bạn. Tôi thích sử dụng các bước hơn tỷ lệ phần trăm vì nó trực quan hơn đối với tôi.

Ví dụ: 20% của 200 giá trị màu xanh khác nhiều so với 20% của giá trị 40 màu xanh.

Dù sao, đây là sửa đổi của tôi, cảm ơn cho chức năng ban đầu của bạn.

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;

}

Tìm thấy điều này hữu ích hơn nhiều so với câu trả lời hàng đầu bởi vì câu trả lời hàng đầu là làm cho màu sắc của tôi rất mãnh liệt thay vì chỉ tối hơn. Chúc mừng Eric
Worm

4

Tôi đã thử chức năng của bạn và có một lỗi nhỏ: ví dụ: nếu một số giá trị 'r' cuối cùng chỉ có 1 chữ số, kết quả sẽ xuất hiện như sau: 'a0a0a' khi giá trị đúng là '0a0a0a'. Tôi chỉ sửa nhanh nó bằng cách thêm cái này thay vì trả lại của bạn:

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;

Có thể nó không đẹp lắm nhưng nó làm được việc. Chức năng tuyệt vời, BTW. Đúng thứ tôi cần. :)


1
Cảm ơn đã gỡ lỗi và khen ngợi! Quá tệ, nó không phải là một câu trả lời cho dù có cách nào nhanh hơn hay không, đó là câu hỏi chính của tôi. Giống như có thể một người sử dụng tất cả hex và không có chuyển đổi cơ sở. Tho, tôi đoán bạn đã cho tôi biết nếu tôi có mã chính xác (+1). Thật không may, bản sửa lỗi đã thêm chi phí đáng kể (hiện tại bạn đang gọi tới 6 lần) và ít KISS hơn. Có lẽ sẽ nhanh hơn để kiểm tra xem số cơ sở10 là 15 hay ít hơn, trước khi chuyển đổi cơ sở16. Nhưng tôi thích!
Pimp Trizkit

4

Bạn đã nghĩ về một chuyển đổi rgb> hsl? Sau đó chỉ cần di chuyển Luminosity lên và xuống? đó là con đường tôi sẽ đi

Một cái nhìn nhanh cho một số thuật toán đã cho tôi các trang web sau.

PHP: http://serennu.com/colour/rgbtohsl.php

Javascript: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-alerskyms-in-javascript

EDIT liên kết trên không còn hiệu lực. Bạn có thể xem trung tâm git cho nguồn trang hoặc ý chính

Ngoài ra, một câu hỏi khác về StackOverflow có thể là một nơi tốt để xem xét.


Mặc dù đây không phải là lựa chọn đúng đắn cho OP, nhưng sau đây là xấp xỉ mã mà tôi đã đề xuất ban đầu. (Giả sử bạn có chức năng chuyển đổi 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;
}

Giả định này:

  1. Bạn có chức năng hslToRgbrgbToHsl .
  2. Tham số colorValuenày là một chuỗi ở dạng #RRGGBB

Mặc dù nếu chúng ta đang thảo luận về css, có một cú pháp để chỉ định hsl / hsla cho IE9 / Chrome / Firefox.


Thật thú vị, nhưng sau đó tôi sẽ không phải chuyển đổi từ chuỗi hex sang rgb sang hsl? Có vẻ như nó phức tạp hơn. Có lẽ tôi đang thiếu một cái gì đó. Nhưng, tôi đang tìm kiếm một cách KISS để làm điều đó, cũng như nhanh nhất có thể (thời gian thực hiện). Tôi cảm thấy lý tưởng, nếu tôi có thể làm tất cả trong hex sẽ là nhanh nhất. Nhưng, giải pháp tôi đã phát triển ở đây liên quan đến việc chuyển sang rgb để có thể thêm số tiền tăng dần.
Pimp Trizkit

Có, tôi cho rằng nó sẽ chậm hơn, phức tạp hơn và nếu bạn không sử dụng rgb để chuyển đổi hsl ở bất cứ nơi nào khác thì có lẽ đó sẽ không phải là giải pháp đơn giản nhất. Tuy nhiên, nó sẽ chính xác hơn so với việc thêm vào các giá trị rgb mặc dù bản thân tôi không phải là người nhiều màu sắc. Tất cả phụ thuộc vào mức độ chính xác mà bạn muốn trở thành tôi đoán.
James Khoury

Mất gì độ chính xác mà bạn đề cập? Tôi giả sử bạn có nghĩa là tất cả các màu [web] không thể truy cập bằng rgb hoặc một cái gì đó?
Pimp Trizkit

Như tôi đã nói tôi không biết nhiều về màu sắc: Lý thuyết màu wiki
James Khoury

@Pimp Trizkit: Nó kém chính xác hơn bởi vì (và đây chỉ là lý thuyết của tôi ... Tôi không phải là chuyên gia về màu sắc) bạn đang dịch chuyển từng kênh với cùng một lượng, bất kể màu đó có bắt đầu bằng bao nhiêu. Tôi nghĩ rằng điều đó sẽ dẫn đến việc giảm độ bão hòa vì bạn đang đưa các kênh lại gần nhau hơn (theo tỷ lệ phần trăm). Tất nhiên, nếu bạn tràn / tràn thì điều đó là không thể tránh khỏi.
Matthew Crumley

2

Phiên bản C # ... lưu ý rằng tôi đang nhận được chuỗi màu ở định dạng này # FF12AE34 và cần phải cắt bỏ #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);
    }

5
Chưa bao giờ sử dụng C # trước đây, nhưng có vẻ như ba khai báo biến cuối cùng là wierd. Một intvà hai varscho cùng một loại dữ liệu.
Pimp Trizkit

4
Từ khóa var trong C # có nghĩa là cho phép trình biên dịch suy ra kiểu tại thời gian biên dịch. Vì vậy, trong ví dụ trên int và var định nghĩa một biến cùng loại - int. Điều này hữu ích nếu bạn có một tên loại dài hoặc nếu bạn muốn tham chiếu một loại ẩn danh. Thật kỳ lạ vì user1618171 đã trộn lẫn hai kiểu khai báo biến - có thể là lỗi chính tả.
Daniel James Bryars

2

Tôi muốn thay đổi màu thành một mức độ sáng cụ thể - bất kể màu nào là độ sáng trước đó - đây là một hàm JS đơn giản có vẻ hoạt động tốt, mặc dù tôi chắc chắn rằng nó có thể ngắn hơn

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

Coolio! Tôi cho rằng pcó phạm vi 0-100? Tôi thậm chí không biết cách xác định chính xác độ sáng trong RGB, đó là một điều HSL. Chẳng hạn, #FF00FFsáng hơn #FF0000? Nếu vậy, điều đó có nghĩa là màu đỏ tươi gấp đôi màu đỏ. Do đó, thử nghiệm màu đỏ tinh khiết được sử dụng. Chuyển sang màu đỏ thuần #FF0000, được đặt ở độ sáng 50% và ở đây chúng tôi nhận được #FF4040, có đúng không? Tôi đoán là sẽ tạo ra độ sáng 50% màu đỏ, chúng ta sẽ ngày càng tối hơn, khi thấy rằng nó đã hoàn toàn sáng .. như trong #800000hoặc độ sáng 150% sẽ là #FF8080. Là màu hồng sáng hơn? hoặc là màu đỏ đã hoàn toàn sáng?
Pimp Trizkit

Bạn nói đúng - Tôi nên đề cập rằng p phải nằm trong phạm vi 1-100!
Torbjorn Josefsson

# FF00FF có 255 làm giá trị trong kênh màu đỏ, 0 trong kênh màu lục và 255 trong kênh màu xanh. Các giá trị kết hợp trong các kênh càng cao thì độ sáng của màu càng cao. Số p nói rằng chúng tôi muốn màu mới sáng hơn 50% so với màu gốc. Tôi không 100% rằng # FF4040 là câu trả lời chính xác cho "50% sáng nhất có thể". Tạo ra các màu tối hơn (trong trường hợp này, giá trị thấp hơn trong kênh màu đỏ) sẽ yêu cầu sửa đổi
Torbjorn Josefsson

Vâng, tôi chỉ chỉ ra sự mơ hồ khi nói về độ sáng trong RGB. Nếu được chuyển đổi thành HSL, Lkênh có nghĩa là độ sáng. Vấn đề [tinh thần cá nhân] của tôi ở đây là, với tôi, #FF0000là hoàn toàn sáng sủa. Và #FF4040là Nhẹ hơn nhưng không sáng hơn .... với tôi nhẹ hơn có nghĩa là gần với màu trắng hơn, giống như màu hồng. Và độ sáng là bao nhiêu của nó, và nó có màu đỏ đầy đủ, vì vậy màu đỏ, là ánh sáng đầy đủ. Do đó, #FF0000không thể làm cho nó sáng hơn .. mà là .. nhẹ hơn ... có lẽ tôi chỉ là một kẻ lập dị, lol !! Tôi thực sự không biết lý thuyết màu sắc, vì vậy, tôi thực sự chỉ đang nói ra một ...
Pimp Trizkit

Nhưng tôi biết rằng khi tôi thay đổi độ sáng trên màn hình, Quỷ đỏ không chuyển sang màu hồng ... với tôi. Vì vậy, đây có lẽ là nơi tôi bắt đầu logic của mình.
Pimp Trizkit

1

Phương pháp sau đây sẽ cho phép bạn làm sáng hoặc làm tối giá trị phơi sáng của chuỗi màu Hexadecimal (Hex):

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

}

Đối với giá trị tham số cuối cùng trong GetHexFromRGB (), Chuyển vào giá trị kép ở đâu đó giữa -1 và 1 (-1 là màu đen, 0 không thay đổi, 1 là màu trắng):

// 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%;

0

Làm thế nào để màu sắc đơn giản trong 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

Đây là phiên bản php của câu trả lời của Pablo. Thật không may, nó dài hơn và chậm hơn so với giải pháp cuối cùng và nó không làm sáng màu chính xác. Nó làm tối chúng chính xác tho. Thử nghiệm với màu đỏ thuần (# FF0000), độ sáng 25% phải là (# FF4040). Kiểm tra phần cuối câu trả lời của tôi cho phiên bản PHP của Kevin M về giải pháp cuối cùng v2.
Pimp Trizkit

0

Tôi đã tạo một cổng của thư viện xcolor tuyệt vời để loại bỏ sự phụ thuộc jQuery của nó. Có rất nhiều chức năng trong đó bao gồm màu sáng và tối.

Thực sự, chuyển đổi hex thành RGB là một chức năng hoàn toàn tách biệt với màu sáng hoặc tối. Giữ mọi thứ DRY vui lòng. Trong mọi trường hợp, một khi bạn có màu RGB, bạn có thể chỉ cần thêm sự khác biệt giữa mức độ ánh sáng bạn muốn và mức độ ánh sáng bạn có cho mỗi giá trị 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)
}

Xem https://github.com/fresheneesz/xolor để biết thêm nguồn.


Tôi chưa phân tích mã khi nó liên quan đến OP của tôi (tốc độ / kích thước / độ chính xác). Nhưng lúc đầu đọc, có một số ý kiến ​​được đưa ra: 1) Tôi đồng ý rằng việc chuyển đổi hex thành RGB có thể được xem là một chức năng hoàn toàn riêng biệt .. NẾU vấn đề của tôi được dự định giải quyết bằng một chức năng khô, không phải là một yêu cầu. Ý định ở đây là có một câu trả lời (xem Phiên bản 2 của tôi) siêu nhanh và siêu nhỏ (2 dòng!) Và một màu sáng và làm tối một màu lục giác ... cụ thể là ... độc lập chức năng. Vì vậy, trong lần sử dụng cuối cùng, nó sẽ là một cuộc gọi chức năng đơn giản. <
Cont

2) Và trường hợp với Phiên bản 3, theo nhu cầu phổ biến, là ý định có một chức năng phổ quát độc lập hoàn toàn độc lập, nhanh và nhỏ nhất có thể, có thể lấy màu hex hoặc RGB một cách mù quáng các biến thể. Do đó, việc chuyển đổi hex thành RGB là cần thiết. <cont.>
Pimp Trizkit

3) Khi phân tích đơn giản mã. Có vẻ như nó sẽ chạy chậm hơn nhiều và rõ ràng là lớn hơn nhiều so với Phiên bản 2 của tôi (đó là câu trả lời thực sự cho OP của tôi; phiên bản 3 dành cho số đông). Để công bằng, tôi nên so sánh mã này với Phiên bản RGB 2 của tôi không thực hiện chuyển đổi và dường như trả lời quan điểm của bạn về độ khô. Và nói thật, cổng của bạn không dễ hiểu hơn nhiều so với 2 lớp lót của tôi cho hex. Vì vậy, trong khi máy sấy của nó, nó không thực sự nhiều, nếu có, đơn giản hơn. (sự khô khan không giúp ích nhiều cho khả năng hiểu) <cont.>
Pimp Trizkit

4) My RGB Phiên bản 2 là chức năng không có chuyển đổi 2 dòng nếu bạn muốn điều đó. Giải pháp cụ thể của tôi cho OP ban đầu của tôi muốn hex. Đó là lý do tại sao có hai loại Phiên bản 2. Khác nhau, nhưng bạn đề cập đến điểm về độ khô và chuyển đổi hex để chúng tôi thực sự tập trung vào phiên bản 3. Phiên bản 3 xuất hiện muộn hơn nhiều; chỉ sau khi phiên bản 2 được phổ biến. <cont.>
Pimp Trizkit

5) Mặc dù tôi sẽ đồng ý rằng sự khô ráo thường giúp ích cho tính phổ quát. Và trong hầu hết các trường hợp, cho khả năng hiểu. Thật không may, nó có giá trong ví dụ này. Những chi phí này lớn hơn nhiều và dường như chậm hơn nhiều và dường như sử dụng nhiều bộ nhớ hơn trên cả ngăn xếp (với tính chất đệ quy của nó) và trong toàn cầu (2 hàm; so với v2).
Pimp Trizkit

0

Từ lâu tôi đã muốn có thể tạo ra các sắc độ / sắc thái màu, đây là giải pháp JavaScript của tôi:

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

Một số ví dụ sử dụng sẽ giúp. Và có thể một số giải thích về lý do tại sao phiên bản này hơn các phiên bản khác. Phiên bản này dường như chạy chậm hơn đáng kể. Và nó dài hơn nhiều. Và nó dường như không che bóng chính xác. Có vẻ như bạn sử dụng LERP, hoặc một cái gì đó tương tự..những gì là tốt. Thật không may, nó chỉ từ một kênh, sau đó cùng một giá trị được sử dụng trên tất cả các kênh. Điều này là không đúng, để có được độ chính xác cao hơn, bạn nên LERP từng kênh riêng lẻ. Như câu trả lời của tôi cho câu hỏi này. Cộng với nó nhỏ hơn và nhanh hơn và kiểm tra lỗi và xử lý rgb, và thực hiện chuyển đổi, tôi có thể tiếp tục
Pimp Trizkit

Một ví dụ sử dụng: differHue ("6e124c", 77) trong đó đối số đầu tiên là màu ở dạng hex và phần trăm thay đổi phần trăm. Tỷ lệ phần trăm thay đổi dương (làm tối) trong khi kết quả giá trị âm (làm sáng) kết quả. Tôi đã viết thói quen như là nỗ lực đầu tiên của tôi chỉ một vài giờ trước khi tôi đến trang này và đăng nó đơn giản là một vấn đề quan tâm. Tôi đã không nhận thức được rằng tôi phải nỗ lực tốt hơn hoặc tôi cần sự chấp thuận của bạn trước khi làm như vậy. Nó hoàn toàn là công việc của riêng tôi mà không cần tham khảo cho bất cứ ai khác. Tôi chưa nghe nói về LERP Tôi sẽ kiểm tra nó, cảm ơn vì lời đề nghị.
dùng2655360

Hehe, tốt, tất nhiên bạn không phải làm gì cả! Và tất cả chúng tôi cảm ơn bạn vì những nỗ lực của bạn! Mối quan tâm chính đầu tiên của tôi là những người được liệt kê đầu tiên. Cố gắng giúp bạn với câu trả lời của bạn để nó có thể nhận được phiếu bầu. (hiển thị cách sử dụng và giải thích về cách thức hoạt động của nó, v.v.) Những thứ khác rõ ràng là một phân tích nhanh để giúp hiểu biết thêm của mọi người . Xin lỗi, nếu nó có vẻ hơi tích cực. Nhưng một đề nghị khác là làm cho nó chấp nhận #màu hex. Xin lỗi nếu nó có vẻ như .. "phê duyệt" ... Tôi thấy đó là đánh giá ngang hàng. Nếu bạn không muốn ai đó phân tích mã của mình hoặc đưa ra phản hồi, tôi xin lỗi.
Pimp Trizkit

0

Cách tiếp cận của bạn là ok :) Tôi đơn giản hóa phiên bản ngắn nhất của bạn một chút (để kiểm soát bão hòa xem tại đây )

(col,amt)=> (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0)

Và phiên bản với # và phạm vi màu kiểm tra


0

Tôi đã làm một gói đơn giản quá. Tôi đã sử dụng độ lồi của IR ^ 3, tất nhiên, các giá trị RGB nằm trong IN ^ 3 không phải là lồi nên điều này không thực sự hoàn hảo

Để làm tối tôi sử dụng như sau

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.floor(rgb[i] - ratio * rgb[i]);
}

Và để làm sáng

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.ceil(rgb[i] + ratio * (255 - rgb[i]));
}

Đây là gói https://github.com/MarchWorks/colortone

Bản giới thiệu https://colortone.now.sh/

với cách mà tôi đang làm nếu bạn vượt qua tỷ lệ -1, bạn sẽ kết thúc với màu đen, Trắng nếu tỷ lệ là 1. Vượt qua 0 vì tỷ lệ sẽ không thay đổi màu sắc


0

Tôi cần nó trong C #, nó có thể giúp các nhà phát triển .net

public static string LightenDarkenColor(string color, int amount)
    {
        int colorHex = int.Parse(color, System.Globalization.NumberStyles.HexNumber);
        string output = (((colorHex & 0x0000FF) + amount) | ((((colorHex >> 0x8) & 0x00FF) + amount) << 0x8) | (((colorHex >> 0xF) + amount) << 0xF)).ToString("x6");
        return output;
    }

Bạn đã chuyển đổi chức năng "không hoạt động" không xử lý các số 0 đứng đầu và có thể vượt lên trên FF trong các khoản tiền, = sửa đổi thành phần màu ở trên ...
B. Đi vào

Khi tôi thử chức năng này, nó không hoạt động vì các giá trị không hex (16 = 0xF) và (8 = 0x8) và cho màu ở 8 vị trí, nhưng bây giờ nó hoạt động rất tốt
Nassim

Bạn đã thử tăng từ FF? (nói từ 0xFFFFFF + 0x000004): mã của bạn cuộn qua giá trị tối đa đó (nói với 0x1000003), thay vì không tăng và đặc biệt là đặt 2 thành phần màu trên thành 00, đây là thay đổi lớn nhất họ có thể làm ...
B. Đi

bạn đã đúng, cảm ơn bạn đã nhận xét, ngoại trừ đầu vào của giới hạn arround fff và 000 nó sẽ hoạt động tốt.
Nassim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.