JavaScript中顏色模型的基礎(chǔ)知識(shí)與應(yīng)用詳解
介紹
顏色模型,是用來(lái)表示顏色的數(shù)學(xué)模型。比如最常見(jiàn)的 RGB模型,使用 紅綠藍(lán) 三色來(lái)表示顏色。
一般的顏色模型,可以按照如下分類(lèi):
- 面向硬件設(shè)備的顏色模型:RGB,CMYK,YCrCb。
- 面向視覺(jué)感知的顏色模型:HSL,HSV(B),HSI,Lab。
不同的顏色模型有不同的應(yīng)用場(chǎng)景,而RGB模型適合于顯示器這樣的的設(shè)備。
其中,前端支持的是 RGB、HSL,即在前端頁(yè)面中只有這兩種模型的顏色值可以有效展示出來(lái)。
而對(duì)于 HSV,則是我們?cè)趧?chuàng)建顏色選擇器插件時(shí)所需要了解的一種模型。
目前,chrome 瀏覽器,實(shí)現(xiàn) H5 的顏色色盤(pán),就是基于 HSV 模型:

注意:fixfore 瀏覽器支持的仍然是電腦系統(tǒng)色盤(pán)(如win系統(tǒng)下,與畫(huà)圖軟件中編輯顏色的色盤(pán)一樣)。
本文將主要介紹 RGB、HSL、HSV 這三種模型。
RGB模型
RGB 即常說(shuō)的 紅(R)、綠(G)、藍(lán)(B) 三原色模型,是運(yùn)用最廣泛的顏色模型。
特別是在前端開(kāi)發(fā)中,幾乎都使用該模型處理顏色。如:rgb(0, 0, 255),#d3d3d3。
該模型通過(guò)紅綠藍(lán)三個(gè)顏色通道的變化和相互之間的混合疊加,使用不同的強(qiáng)度,表現(xiàn)出不同的顏色。
它是一種加色混色模型,在疊加混合的過(guò)程中,亮度等于色彩亮度的綜合,混合的越多亮度就越高。
根據(jù)三色的取值不同,一般有以下幾種類(lèi)型:
- R5G5B5(A1):16位,各色都用5位表示,取值范圍
0-31(2^5 - 1),剩余1位作Alpha通道或者不用。 - R5G6B5:16位,R和B占用5位,取值范圍
0-31(2^5);G占用6位,取值范圍0-63(2^6 - 1)。 - R8G8B8:24位,各色都用8位表示,取值范圍為
0-255(2^8 - 1)。
最多能有2^24種顏色,從24位開(kāi)始的顏色就是真彩色,基本達(dá)到人眼極限。 - R8G8B8(A8):32位,各色都用8位表示,取值范圍為
0-255(2^8 - 1),剩余8位作Alpha通道或者不用。
這其中,最常見(jiàn)的當(dāng)然就是24位和32位的類(lèi)型。
三色通道中每個(gè)顏色有256階的亮度,為0時(shí)最暗,255時(shí)最亮。
如果三色的數(shù)值都相同時(shí),就會(huì)產(chǎn)生不同灰度值的灰度色調(diào),都為0時(shí)最暗黑色,都為255時(shí)最亮白色。
RGB顏色值
先看下 RGB 顏色值在前端的展現(xiàn),如紅色:
'rgb(255, 0, 0)' 'rgba(255, 0, 0, 1)' // 帶透明度 '#ff0000' '#f00' // 縮寫(xiě) 'red' // 顏色名稱(chēng)
描述RGB模型,使用的顏色值,有 rgb 和 hex16 進(jìn)制兩種方式。
rgb(0,0,0) 表示法,一般情況下,紅綠藍(lán)三色分別取值范圍 0-255,如果加上 alpha 透明通道,則為 rgba(0,0,0,1) 。
hex 16進(jìn)制表示法,采用十六進(jìn)制對(duì)24比特的一種展示方式,如 #000000,共6位,每?jī)晌环謩e對(duì)應(yīng)紅綠藍(lán),相同時(shí)可縮寫(xiě)為 #000。
hex也可以使用 #00000000,后面加上透明度的十六進(jìn)制數(shù)值。
此外,在前端開(kāi)發(fā)中,還可以使用顏色名稱(chēng)如 red、green、gray 等標(biāo)識(shí)顏色。
實(shí)際上,這里的顏色名稱(chēng)仍然是對(duì)應(yīng)的一個(gè)RGB顏色值,有一個(gè)規(guī)定的顏色名稱(chēng)與值的關(guān)系表。大部分的顏色單詞基本都能使用。
上面兩種表示法的簡(jiǎn)單轉(zhuǎn)換關(guān)系,如下所示。
rgb 轉(zhuǎn) hex
function getHex (num) {
let val = num.toString(16)
val = (val.length === 1) ? ('0' + val) : val
return val
}
function rgbaToHexa (red, green, blue, alpha) {
red = getHex(red)
green = getHex(green)
blue = getHex(blue)
alpha = Math.round(alpha * 255)
alpha = getHex(alpha)
return '#' + red + green + blue + alpha
}hex 轉(zhuǎn) rgb
function hexaToRgba (color) {
const value = color.slice(color.indexOf('#') + 1)
const isShort = value.length === 3 || value.length === 4
const hasAlpha = value.length === 4 || value.length === 8
const r = isShort ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2)
const g = isShort ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4)
const b = isShort ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6)
let a = hasAlpha ? (isShort ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF'
a = parseFloat((parseInt(a, 16) / 255).toFixed(2))
return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), a]
}HSL模型
前端在顏色的處理上,除了支持 RGB 模型外,另外支持的就只有 HSL 模型,所以我們需要了下解該模型。
HSL 顏色值表示,紅色:
hsl(0, 100%, 50%) hsla(0, 100%, 50%, 1) // 帶透明度
HSL 是對(duì)色相H(hue)、飽和度S(saturation)、亮度L(lightness)的處理得到顏色的一種模型。
色相(H):色相、色調(diào),代表人眼所能看到的不同的顏色,本質(zhì)就是一種顏色。與 HSV(B) 模型中的 H 概念相同。 色相的定義中,許多的顏色分布在一個(gè)圓環(huán)上,取值范圍則是 0-360度,每個(gè)角度代表著一種顏色。
在HSL和HSV的模型中,色相是以六大主色為基礎(chǔ),他們分別按 60 度的間隔排列在圓環(huán)上。這六大主色分別是:360°/0°紅、60°黃、120°綠、180°青、240°藍(lán)、300°洋紅。
而在前端進(jìn)行處理時(shí),常常把圓環(huán)處理成長(zhǎng)方形的色塊,通過(guò)顏色的線性漸變方式進(jìn)行分段處理,角度換算成一定的比例,如下所示:

linear-gradient(90deg, #f00, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00);
飽和度(S):飽和度是指顏色的強(qiáng)度或純度,使用 0 ~ 100% 的百分比來(lái)度量。
表示色相中顏色成分所占的比例,數(shù)值越大,顏色中的灰色越少,顏色越鮮艷,呈現(xiàn)的是一種從灰色到色相顏色的變化。
亮度(L):表現(xiàn)顏色的明暗程度,使用 0 ~ 100% 的百分比來(lái)度量。
反映色彩中混入的黑白兩色,50% 處只有純色,小于 50% 時(shí),數(shù)值越小混入的黑色越多,越接近于黑色;大于 50% 時(shí),數(shù)值越大混入的白色越多,越接近于白色。
L最大時(shí)必為白色,L最小時(shí)必為黑色。
體現(xiàn)的是從黑色到色相(H)選擇顏色再到白色的過(guò)渡。
HSV(B)模型
HSV 顏色值表示,紅色:
// 前端不支持 hsv(0, 100%, 100%) hsva(0, 100%, 100%, 1) // 帶透明度
HSV 采用色相H(hue)、飽和度S(saturation)、明度V(Value)3個(gè)參數(shù)來(lái)表示顏色的一種方式。
HSV 和 HSL 兩個(gè)模型都是更偏向于視覺(jué)上直觀的感覺(jué)。
而HSV 與 HSB 的內(nèi)容基本是一樣的,可以理解為兩種不同寫(xiě)法而已,其中 B( brightness )。
色相(H):同 HSL 模型中的 H 色相。
飽和度(S):飽和度是指顏色的強(qiáng)度或純度,使用 0 ~ 100% 的百分比來(lái)度量。
在 HSV 中更多的是反映色相的顏色中混入白色的值,值越大白色越少色相顏色越純,值越小白色越多色相顏色越淡。
明度(V):表現(xiàn)顏色的明暗程度,使用 0 ~ 100% 的百分比來(lái)度量。
反映色相的顏色中混入的黑色的值,值越小黑色越多顏色更暗(黑),值越大黑色越少顏色更純(亮)。
體現(xiàn)的是從黑色到色相(H)選擇顏色的過(guò)渡。
RGB 與 HSL 的轉(zhuǎn)換
下面是常用的 rgb 顏色值與 hsl 之間互相轉(zhuǎn)換的代碼。
注意:這兩個(gè)過(guò)程中,由于取整去除了小數(shù)位,并不是完全可逆的,可能存在個(gè)別個(gè)位數(shù)的差值。
雖有些微差別,但在頁(yè)面顏色顯示上基本沒(méi)分別,因?yàn)槿搜鄯直娌怀鰜?lái)。
rgb 轉(zhuǎn) hsl
function rgbToHsl (red, green, blue) {
red = red / 255
green = green / 255
blue = blue / 255
let hue = saturation = lightness = 0
const max = Math.max(red, green, blue)
const min = Math.min(red, green, blue)
const diff = max - min
const sum = max + min
lightness = sum / 2
if (diff) {
saturation = lightness > 0.5 ? diff / (2 - sum) : diff / sum
switch (max) {
case red:
hue = (green - blue) / diff + (green < blue ? 6 : 0)
break
case green:
hue = (blue - red) / diff + 2
break
case blue:
hue = (red - green) / diff + 4
break
}
hue = hue / 6
}
hue = Math.round(hue * 360)
saturation = Math.round(saturation * 100)
lightness = Math.round(lightness * 100)
return [hue, saturation, lightness]
}hsl 轉(zhuǎn) rgb
function hslToRgb(hue, saturation, lightness) {
hue = hue / 360
saturation = saturation / 100
lightness = lightness / 100
let red, green, blue
const hue2rgb = (val1, val2, vH) => {
vH = vH < 0 ? (vH + 1) : vH > 1 ? (vH - 1) : vH
if (vH < 1 / 6) {
return val1 + (val2 - val1) * 6 * vH
}
if (vH < 1 / 2) {
return val2
}
if (vH < 2 / 3) {
return val1 + (val2 - val1) * (2 / 3 - vH) * 6
}
return val1
}
if (saturation === 0) {
red = green = blue = lightness;
} else {
const val2 = lightness <= 0.5 ? lightness * (saturation + 1) : (lightness + saturation) - (lightness * saturation)
const val1 = lightness * 2 - val2
red = hue2rgb(val1, val2, hue + 1 / 3)
green = hue2rgb(val1, val2, hue)
blue = hue2rgb(val1, val2, hue - 1 / 3)
}
red = Math.round(red * 255)
green = Math.round(green * 255)
blue = Math.round(blue * 255)
return [red, green, blue]
}到此這篇關(guān)于JavaScript中顏色模型的基礎(chǔ)知識(shí)與應(yīng)用詳解的文章就介紹到這了,更多相關(guān)JavaScript顏色模型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)循環(huán)嵌套數(shù)據(jù)選擇
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)循環(huán)嵌套數(shù)據(jù)選擇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
javascript中錯(cuò)誤使用var造成undefined
這篇文章主要介紹了javascript中錯(cuò)誤使用var造成undefined的原因,實(shí)例分析了錯(cuò)誤使用var造成undefined的過(guò)程,感興趣的小伙伴們可以參考一下2016-03-03
DeviceOne 讓你一見(jiàn)鐘情的App快速開(kāi)發(fā)平臺(tái)
DeviceOne是一個(gè)非常先進(jìn)的App開(kāi)發(fā)平臺(tái),使用Javascript 構(gòu)建原生體驗(yàn)的移動(dòng)應(yīng)用程序,DeviceOne主要關(guān)注外觀和體驗(yàn),以及和你的應(yīng)用程序的 UI 交互2016-02-02
JavaScript錯(cuò)誤處理try..catch...finally+涵蓋throw+TypeError+RangeEr
這篇文章主要介紹了JavaScript錯(cuò)誤處理:try..catch...finally+涵蓋throw+TypeError+RangeError,文章內(nèi)容具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2021-12-12
前端排查內(nèi)存泄漏的方法及實(shí)戰(zhàn)案例
內(nèi)存泄漏是指在程序運(yùn)行時(shí),分配的內(nèi)存沒(méi)有被正確釋放,導(dǎo)致內(nèi)存空間的浪費(fèi),最終可能會(huì)導(dǎo)致程序崩潰或運(yùn)行緩慢,這篇文章主要介紹了前端排查內(nèi)存泄漏的相關(guān)資料,需要的朋友可以參考下2025-03-03
javascript實(shí)現(xiàn)div浮動(dòng)在網(wǎng)頁(yè)最頂上并帶關(guān)閉按鈕效果實(shí)例
我們有時(shí)會(huì)看到有些網(wǎng)站最頂部一直會(huì)跟著我們滾動(dòng)而滾動(dòng)了,這種方法其實(shí)很簡(jiǎn)單,下面我來(lái)給大推薦一個(gè)javascript實(shí)現(xiàn)div浮動(dòng)在網(wǎng)頁(yè)最頂上并帶關(guān)閉按鈕效果2013-08-08
Javascript中prototype與__proto__的關(guān)系詳解
這篇文章主要給大家介紹了關(guān)于Javascript中prototype與__proto__的關(guān)系的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
微信小程序?qū)崿F(xiàn)計(jì)時(shí)器開(kāi)始和結(jié)束功能
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)計(jì)時(shí)器開(kāi)始和結(jié)束功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07

