者 | Adam Giese
譯者 | 王強
CSS 中有兩種顏色模型 RGB 和 HSL,如何用 JavaScript 控制它們?
點開這篇文章的你,肯定是想要學習怎樣控制顏色的——我們后面就會講具體操作。但首先,我們需要對 CSS 如何標記顏色有一個基本的認識。CSS 使用的是兩種顏色模型:RGB 和 HSL,我們先簡單了解一下。
1、RGB
RGB 就是“紅色,綠色,藍色”的簡稱。這個模型由三個數字組成,每個數字表示其所代表的顏色在最終生成的顏色中有多高的亮度。在 CSS 中,每個數值的范圍都是 0-255,三個數值間用逗號分隔,作為 CSS rgb 函數的參數,例如:rgb(50,100,0)。
RGB 是一種“增量”顏色系統。這意味著每個數字越高,最終生成的顏色就越亮。如果所有值都相等就生成灰度顏色;如果所有值都為零,結果為黑色;如果所有值都是 255,則結果為白色。
此外你也可以使用十六進制表示法來標記 RGB 顏色,其中每種顏色的數值從 10 進制轉換為 16 進制。例如,rgb(50,100,0)用 16 進制就寫成#326400。
雖然我個人比較習慣使用 RGB 模型(特別是十六進制),但我也經常發現它不易閱讀,也不容易操作。下面來看 HSL 模型。
2、HSL
HSL(https://codepen.io/AdamGiese/full/989988044f3b8cf6403e3c60f56dd612)是“色調,飽和度,光線”的簡稱,HSL 也包含三個值。色調值對應于色輪上的點,由 CSS 角度值表示,最常用的是度數單位。
飽和度以百分比表示,是指顏色的強度。當飽和度為 100%時顏色最深,飽和度越低,顏色越淺,直到灰度為 0%。
亮度也以百分比表示,指的是顏色有多亮。“常規”的亮度是 50%。無論色調和飽和度值如何,100%的亮度都是純白色,0%的亮度就是純黑色。
我覺得 HSL 模型更直觀一些,顏色之間的關系更加明顯,控制顏色時只要簡單地調整幾個數字就可以了。
3、顏色模型之間的轉換
RGB 和 HSL 顏色模型都將顏色分解為各種屬性。要在不同模型之間進行轉換,我們首先需要計算這些屬性。
除了色調,上面提到的所有數值都可以表示為百分比。就連 RGB 值也是用字節表示的百分比。在下面提到的公式和函數中,這些百分比將由 0 到 1 之間的小數來表示。
這里提一下,我并不會深入探討這些數學知識;相比之下,我將簡要介紹一遍原始數學公式,然后將其轉換為 JavaScript 格式。
4、從 RGB 模型中計算亮度
亮度是三個 HSL 值中最容易計算的一個。其數學式如下,其中 M 是 RGB 值的最大值,m 是最小值:
亮度的數學式
用 JavaScript 函數寫成下面的形式:
const rgbToLightness =(r,g,b)=> 1/2 *(Math.max(r,g,b)+ Math.min(r,g,b));
5、從 RGB 模型中計算飽和度
飽和度僅比亮度稍微復雜一些。如果亮度為 0 或 1,則飽和度值為 0;否則,它基于下面的數學公式計算得出,其中 L 表示亮度:
飽和度的數學式
寫成 JavaScript:
const rgbToSaturation = (r,g,b) => { const L = rgbToLightness(r,g,b); const max = Math.max(r,g,b); const min = Math.min(r,g,b); return (L === 0 || L === 1) ? 0 : (max - min)/(1 - Math.abs(2 * L - 1)); };
6、從 RGB 模型中計算色調
從 RGB 坐標中計算色調角度的公式有點復雜:
色調的數學式
寫成 JavaScript:
const rgbToHue = (r,g,b) => Math.round( Math.atan2( Math.sqrt(3) * (g - b), 2 * r - g - b, ) * 180 / Math.PI );
最后 180 / Math.PI 的算法是將結果從弧度轉換為度。
7、計算 HSL
上面這些函數都可以包含在同一個功能函數里:
const rgbToHsl = (r,g,b) => { const lightness = rgbToLightness(r,g,b); const saturation = rgbToSaturation(r,g,b); const hue = rgbToHue(r,g,b); return [hue, saturation, lightness]; }
8、從 HSL 模型中計算 RGB 值
開始計算 RGB 之前,我們需要一些前提值。
首先是“色度”值:
色度的數學式
還有一個臨時的色調值,我們將用它來確定我們所屬的色調圈的“段”:
色調區間的數學式
接下來,我們設一個“x”值,它將用作中間(第二大)組件值:
臨時“x”值的數學式
我們再設一個“m”值,用于調整各個亮度值:
亮度匹配的數學式
根據色調區間值,r,g 和 b 值將映射到 C,X 和 0:
RGB 值的數學式,不考慮亮度
最后,我們需要映射每個值以調整亮度:
用 RGB 來解釋亮度的數學式
將上面這些都寫到 JavaScript 函數中:
const hslToRgb = (h,s,l) => { const C = (1 - Math.abs(2 * l - 1)) * s; const hPrime = h / 60; const X = C * (1 - Math.abs(hPrime % 2 - 1)); const m = l - C/2; const withLight = (r,g,b) => [r+m, g+m, b+m]; if (hPrime <= 1) { return withLight(C,X,0); } else if (hPrime <= 2) { return withLight(X,C,0); } else if (hPrime <= 3) { return withLight(0,C,X); } else if (hPrime <= 4) { return withLight(0,X,C); } else if (hPrime <= 5) { return withLight(X,0,C); } else if (hPrime <= 6) { return withLight(C,0,X); } }
9、創建顏色對象
為了便于在操作屬性時訪問,我們將創建一個 JavaScript 對象。把前面提到的這些函數打包起來就能創建這個對象:
const rgbToObject = (red,green,blue) => { const [hue, saturation, lightness] = rgbToHsl(red, green, blue); return {red, green, blue, hue, saturation, lightness}; } const hslToObject = (hue, saturation, lightness) => { const [red, green, blue] = hslToRgb(hue, saturation, lightness); return {red, green, blue, hue, saturation, lightness}; }
10、示例
我強烈建議你花些時間看看這個示例:
https://codepen.io/AdamGiese/full/86b353c35a8bfe0868a8b48683faf668
從中了解調節各個屬性時其它屬性如何發生變化,這樣能幫助你更深入地了解兩種顏色模型是如何對應的。
現在我們已經知道怎樣在顏色模型之間進行轉換了,那么就來看看該如何控制這些顏色!
1、更新屬性
我們提到的所有顏色屬性都可以單獨控制,返回一個新的顏色對象。例如,我們可以編寫一個旋轉色調角度的函數:
const rotateHue = rotation => ({hue, ...rest}) => { const modulo = (x, n) => (x % n + n) % n; const newHue = modulo(hue + rotation, 360); return { ...rest, hue: newHue }; }
rotateHue 函數會接受一個旋轉參數并返回一個新函數,該函數接受并返回一個顏色對象。這樣就可以輕松創建新的“旋轉”函數:
const rotate30 = rotateHue(30); const getComplementary = rotateHue(180); const getTriadic = color => { const first = rotateHue(120); const second = rotateHue(-120); return [first(color), second(color)]; }
用這種方式,你也可以編寫加深或提亮顏色的函數——或者反過來,減淡或變暗也行。
const saturate = x => ({saturation, ...rest}) => ({ ...rest, saturation: Math.min(1, saturation + x), }); const desaturate = x => ({saturation, ...rest}) => ({ ...rest, saturation: Math.max(0, saturation - x), }); const lighten = x => ({lightness, ...rest}) => ({ ...rest, lightness: Math.min(1, lightness + x) }); const darken = x => ({lightness, ...rest}) => ({ ...rest, lightness: Math.max(0, lightness - x) });
2、顏色謂詞
除了顏色控制以外,你還可以編寫“謂詞”——亦即返回布爾值的函數。
const isGrayscale = ({saturation}) => saturation === 0; const isDark = ({lightness}) => lightness < .5;
3、處理顏色數組
過濾器
JavaScript [] .filter 方法會接受一個謂詞并返回一個新數組,其中包含所有“傳遞”的元素。我們在上一節中編寫的謂詞可以用在這里:
const colors = [/* ... an array of color objects ... */]; const isLight = ({lightness}) => lightness > .5; const lightColors = colors.filter(isLight);
排序
要對顏色數組進行排序,首先需要編寫一個“比較器”函數。此函數接受一個數組的兩個元素并返回一個數字來表示“贏家”。正數表示第一個元素應該先排序,而負數表示第二個元素應該先排序。零值表示平局。
例如,這是一個比較兩種顏色亮度的函數:
const compareLightness = (a,b) => a.lightness - b.lightness;
這是一個比較飽和度的函數:
const compareSaturation = (a,b) => a.saturation - b.saturation;
為了防止代碼重復,我們可以編寫一個高階函數來返回一個比較函數來對比各種屬性:
const compareAttribute = attribute => (a,b) => a[attribute] - b[attribute]; const compareLightness = compareAttribute('lightness'); const compareSaturation = compareAttribute('saturation'); const compareHue = compareAttribute('hue');
平均屬性
你可以搭配各種 JavaScript 數組方法來平衡顏色數組中的特定屬性。首先,你可以使用 reduce 求和并用 Array length 屬性分割來計算一個屬性的均值:
const colors = [/* ... an array of color objects ... */]; const toSum = (a,b) => a + b; const toAttribute = attribute => element => element[attribute]; const averageOfAttribute = attribute => array => array.map(toAttribute(attribute)).reduce(toSum) / array.length;
你可以用它來“規范化”一組顏色:
/* ... continuing */ const normalizeAttribute = attribute => array => { const averageValue = averageOfAttribute(attribute)(array); const normalize = overwriteAttribute(attribute)(averageValue); return normalize(array); } const normalizeSaturation = normalizeAttribute('saturation'); const normalizeLightness = normalizeAttribute('lightness'); const normalizeHue = normalizeAttribute('hue');
4、結論
顏色是網絡不可或缺的一部分。將顏色分解為屬性就可以靈活控制它們,并創造出無限的可能。
查看英文原文:
https://blog.logrocket.com/how-to-manipulate-css-colors-with-javascript-fb547113a1b8
福利推薦
前端領域的技術演進一直要比其他技術快一些,這給前端工程師帶來持續的挑戰。這里整理了從 Vue 到 React、iOS 到 Andoid、再到前端架構體系的干貨課程,帶你解讀從前端小工到專家的實戰心法,高效解決 80% 的開發難題。
tml代碼里,表示顏色一般用兩種方法,一種是直接寫出顏色的英文,另一種是前面寫個“#”后面再寫6個數字字母。
先說第一種表示方法,這個很簡單,如果要表示黑色直接就是black,紅色就red,藍色就blue。具體的我們看下面圖1,圖2
圖1
圖2
現在來說第二種,這也是我們這個文章要重點說的,因為這個也是最經常用的表示方法,很多人看到這個又是字數又是字母的就糊涂了,今天我們來詳細的把它講清楚。先用圖片來說明一下,先看下面圖3
圖3
圖3里的#000000表示的是黑色,#ff0000表示紅色,#00ff00表示綠色,所以說這個效果是和圖1一樣的。那要怎么理解這種表示顏色的方法呢,我們再來列出幾個顏色和它的表示法:
紅色:#ff0000,綠色:#00ff00,藍色:#0000ff, 大家仔細看一下就可發現,這個和我們平常說的RGB格式來表示顏色是一樣的,相當于紅綠藍三個光,而f是十六進制中的0,1,2,.....e,f中的f了 。f是里面的最大值了,ff代表該顏色光的值達到最大,所以#ff0000是紅色,#880000表示的也是紅色,只是沒有#ff0000這個那么紅了。其他的也是同理。所以#000000代表三個顏色光的值都為0,沒有任何光了,那就是黑色了,相反#ffffff代表三個顏色光的值都達到最大,混合在一起就成白色。我們也知道紅光和藍光混在一起是紫色的,所以#ff00ff表示的是紫色,同樣#ffff00表示的是黃色。講到這里相信大家應該都明白了怎樣用這種方法表示顏色了吧,如果要表示一種顏色,只要把相應的值增加或減小或者添加另一個顏色,這樣就可以得到千千萬萬種顏色了。
這兩種表示顏色的方法都講完了,尤其是第二種方法,大部分情況都是用這種方法來表示html里面的顏色的。如果大家有什么更好的更容易理解的想法,可以點擊關注【點點有你】一起來討論一下哦
最后,如果您覺得我寫的這些文章對您有幫助的話,您可以根據您的情況隨意給點賞金,我相信一分也是愛也是支持,下面兩圖是我的支付寶和微信收款碼。當然寫文章不是一定要讓您給賞金的,有您的支持和贊助,我會有更多動力來寫文章和大家分享的,再次感謝您的支持和理解!
官網是這樣介紹的:使用我們的顏色選擇器、顏色表和HTML顏色名稱來獲取HTML顏色代碼、Hex顏色代碼、RGB和HSL值。即刻開始吧!
尋找完美色彩從未如此簡單,使用我們的HTML顏色選擇器來瀏覽上百萬的顏色和色彩搭配。
顏色選擇器
顏色選擇器動圖
操作:
選取顏色
點擊左側顏色樣本將其添加到您的調色板。
保存顏色
在您的調色板上保存和撤銷保存顏色;下次您訪問時候它們會在這里。
導出顏色
將您當前的調色板以Hex、RGB、HTML、CSS和SCSS 格式輸出。試一下吧!
有了這些扁平化設計、Material Design和網頁安全顏色表,一定可以為您的網頁或應用程序找到完美的色彩方案 – 只需不停地尋找!
顏色表
顏色表動圖
現代瀏覽器支持140種已命名的顏色,如下所列。根據名稱、Hex代碼或RGB值將其用于您的HTML和CSS。
顏色名
如何使用HTML顏色名
之所以建立HTML顏色代碼,是因為我們認為設計工具本身有應有精良的設計。如果您喜歡這個網站或有何建議與反饋,歡迎您隨時發電子郵件與我們聯系
同時這個網站還有其他有趣好玩的分享,比如最佳調色板生成器(選擇完美的色彩方案是任何網站或項目的關鍵部分,為了幫助您找尋完美的顏色組合,我們已將今天最佳的調色板生成器和網絡工具收集在一起編成列表),終極指南免費庫存照片(每個網站都需要很好的創造力,所以我們將最喜愛的可獲得免版稅圖庫照片的地方匯集做成特贊的列表。沒錯,全部是魅力圖庫圖片,100%免費),如何根據顏色搜索圖片(搜索與您的顏色方案相匹配的圖片可能會相當耗時,所以我們把最愛的圖片搜索工具列成了一個簡短的清單,這些工具可以使用顏色對其搜索結果加以過濾或完善)等等
最后說一遍,這個網站有中文,有中文,有中文
網址分享,打開馨客棧導航:http://www.mackxin.com/nav.html
然后找到下圖所示:
在線HTML顏色代碼
更多分享,請關注馨客棧
關注分享,體驗樂趣
*請認真填寫需求信息,我們會在24小時內與您取得聯系。