使用 JavaScript 控制 CSS 中的顏色
背景知識:顏色模型
點開這篇文章的你,肯定是想要學習怎樣控制顏色的——我們後面就會講具體操作。但首先,我們需要對 CSS 如何標記顏色有一個基本的認識。CSS 使用的是兩種顏色模型:RGB 和 HSL,我們先簡單瞭解一下。
RGB
RGB 就是“紅色,綠色,藍色”的簡稱。這個模型由三個數字組成,每個數字表示其所代表的顏色在最終生成的顏色中有多高的亮度。在 CSS 中,每個數值的範圍都是 0-255,三個數值間用逗號分隔,作為 CSS rgb 函式的引數,例如:rgb(50,100,0)。
RGB 是一種“增量”顏色系統。這意味著每個數字越高,最終生成的顏色就越亮。如果所有值都相等就生成灰度顏色;如果所有值都為零,結果為黑色;如果所有值都是 255,則結果為白色。
此外你也可以使用十六進位制表示法來標記 RGB 顏色,其中每種顏色的數值從 10 進位制轉換為 16 進位制。例如,rgb(50,100,0)用 16 進位制就寫成#326400。
雖然我個人比較習慣使用 RGB 模型(特別是十六進位制),但我也經常發現它不易閱讀,也不容易操作。下面來看 HSL 模型。
一個人學習會有迷茫,動力不足。這裡推薦一下我的前端學習交流群:731771211 ,裡面都是學習前端的,如果你想製作酷炫的網頁,想學習程式設計。自己整理了一份2019最全面前端學習資料,從最基礎的HTML+CSS+JS【炫酷特效,遊戲,外掛封裝,設計模式】到移動端HTML5的專案實戰的學習資料都有整理,送給每一位前端小夥伴,有想學習web前端的,或是轉行,或是大學生,還有工作中想提升自己能力的,正在學習的小夥伴歡迎加入學習。
HSL
HSL是“色調,飽和度,光線”的簡稱,HSL 也包含三個值。色調值對應於色輪上的點,由 CSS 角度值表示,最常用的是度數單位。
飽和度以百分比表示,是指顏色的強度。當飽和度為 100%時顏色最深,飽和度越低,顏色越淺,直到灰度為 0%。
亮度也以百分比表示,指的是顏色有多亮。 “常規”的亮度是 50%。無論色調和飽和度值如何,100%的亮度都是純白色,0%的亮度就是純黑色。
我覺得 HSL 模型更直觀一些,顏色.之間的關係更加明顯,控制顏色時只要簡單地調整幾個數字就可以了。
顏色模型之間的轉換
RGB 和 HSL 顏色模型都將顏色分解為各種屬性。要在不同模型之間進行轉換,我們首先需要計算這些屬性。
除了色調,上面提到的所有數值都可以表示為百分比。就連 RGB 值也是用位元組表示的百分比。 在下面提到的公式和函式中,這些百分比將由 0 到 1 之間的小數來表示。
這裡提一下,我並不會深入探討這些數學知識;相比之下,我將簡要介紹一遍原始數學公式,然後將其轉換為 JavaScript 格式。
從 RGB 模型中計算亮度
亮度是三個 HSL 值中最容易計算的一個。其數學式如下,其中 M 是 RGB 值的最大值,m 是最小值:
用 JavaScript 函式寫成下面的形式:
const rgbToLightness =(r,g,b)=> 1/2 *(Math.max(r,g,b)+ Math.min(r,g,b));
從 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)); };
從 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 的演算法是將結果從弧度轉換為度。
計算 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]; }
從 HSL 模型中計算 RGB 值
開始計算 RGB 之前,我們需要一些前提值。
首先是“色度”值:
還有一個臨時的色調值,我們將用它來確定我們所屬的色調圈的“段”:
接下來,我們設一個“x”值,它將用作中間(第二大)元件值:
我們再設一個“m”值,用於調整各個亮度值:
根據色調區間值,r,g 和 b 值將對映到 C,X 和 0:
最後,我們需要對映每個值以調整亮度:
將上面這些都寫到 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); } }
建立顏色物件
為了便於在操作屬性時訪問,我們將建立一個 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}; }
顏色控制
現在我們已經知道怎樣在顏色模型之間進行轉換了,那麼就來看看該如何控制這些顏色!
更新屬性
我們提到的所有顏色屬性都可以單獨控制,返回一個新的顏色物件。例如,我們可以編寫一個旋轉色調角度的函式:
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) });
顏色謂詞
除了顏色控制以外,你還可以編寫“謂詞”——亦即返回布林值的函式。
const isGrayscale = ({saturation}) => saturation === 0; const isDark = ({lightness}) => lightness < .5;
處理顏色陣列
過濾器
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');
結論
顏色是網路不可或缺的一部分。將顏色分解為屬性就可以靈活控制它們,並創造出無限的可能。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2646463/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- CSS樣式中顏色與顏色值的應用CSS
- CSS 中的顏色、背景和剪下CSS
- css顏色CSS
- CSS顏色表示CSS
- CSS顏色程式碼CSS
- CSS 顏色與字型CSS
- css 更改svg顏色CSSSVG
- CSS 顏色值型別CSS型別
- CSS設定元素的背景顏色CSS
- CSS 顏色混合的N種方式CSS
- VC 對話方塊背景顏色、控制元件顏色控制元件
- JavaScript WebGL 設定顏色JavaScriptWeb
- JavaScript 十六進位制顏色和RGB顏色值的相互轉換JavaScript
- css顏色單位表示法CSS
- 強大的CSS:顏色、背景和剪下CSS
- JavaScript生成隨機顏色值JavaScript隨機
- CSS設定選中網頁文字時的背景和顏色CSS網頁
- RGBa顏色 css3的Alpha通道支援CSSS3
- CSS 設定字型顏色和大小CSS
- CSS-背景顏色|background-colorCSS
- css3背景顏色漸變CSSS3
- CSS 實現字型顏色漸變CSS
- switch控制元件(變更顏色)控制元件
- win10 更改控制檯預設顏色方法 win10怎麼更改控制檯顏色Win10
- ReSharper 顯示使用的顏色
- Shader 中的顏色計算
- CSS設定滑鼠選中文字的顏色CSS
- css文字顏色漸變的3種實現CSS
- 神奇的 CSS,讓文字智慧適配背景顏色CSS
- CSS 設定文字框游標顏色CSS
- HTML-CSS顏色樣式(推薦)HTMLCSS
- QTreeView使用總結14,自定義model,控制對齊和顏色QTView
- JavaScript 生成十六進位制顏色值JavaScript
- 利用CSS改變圖片顏色的100種方法!CSS
- 利用CSS改變圖片顏色的多種方法!CSS
- 【Web前端基礎知識】css表示顏色的方法Web前端CSS
- 使用CSS混合模式和SVG來動態更改產品圖片的顏色CSS模式SVG
- Shader專題:卡通著色(一)控制顏色的藝術