【30分鐘學完】canvas動畫|遊戲基礎(extra1):顏色那些事

前言

本篇主要講解關於計算機顏色系統的概念,後續結合一些canvas的應用。由於是「你不知道也不要緊」的邊緣知識,因此做爲本系列教程的擴展,沒有興趣的同窗能夠跳過。
開始咱們萬紫千紅的故事吧!
本人能力有限,歡迎牛人共同討論,批評指正。javascript

先從老朋友CSS講起

咱們熟悉的CSS風格顏色表示方式,大致有下面幾種,canvas大致是直接沿用這些寫法的,但最後包含透明度的寫法有些許不一樣。前端

  • #RRGGBB:十六進制格式,紅綠藍分別用兩位十六進制數表示。
  • #RGB:簡寫的十六進制格式,轉換成6位格式時會重複三原色,例如#fb0->#ffbb00
  • rgb(R,G,B):函數表達式,三原色分別由0~255的整數值表示。
  • rgba(R,G,B,A):包含透明度的函數表達式,其中alpha參數爲0~1,須要指定透明度的顏色必須使用該格式。

做爲前端人員平時用得不少,但你可能會一臉懵逼以前本身寫的顏色字符串竟然是十六進制?
待我細細道來。這裏的R便是紅色(red),G便是綠色(green),B便是藍色(blue),這三個是顯示器廣泛使用的三基色,屬於疊加型原色,百科摘錄以下。java

【科普】原色是指不能透過其餘顏色的混合調配而得出的「基本色」。
以不一樣比例將原色混合,能夠產生出其餘的新顏色。以數學的向量空間來解釋色彩系統,則原色在空間內可做爲一組基底向量,而且能組合出一個「色彩空間」。因爲人類肉眼有三種不一樣顏色的感光體,所以所見的色彩空間一般能夠由三種基本色所表達,這三種顏色被稱爲「三原色」。通常來講疊加型的三原色是紅色、綠色、藍色(又稱三基色,用於電視機、投影儀等顯示設備);而消減型的三原色是品紅色、黃色、青色(用於書本、雜誌等的印刷)。

解密顏色值

每個顏色都是由三基色疊加合成,因此咱們須要告訴計算機這各個基色的比例(濃度),將這個比例量化就是一個0~255的整數,也可說是256個級別,越大即表示各類原色更多(更濃)。git

【PS】至於爲何是256個級別?
是由於計算機中每一個原色用8位二進制(0或1)表示,也就是2的8次方共256。

每一個顏色都是256個級別,那它的組合的可能就有256*256*256=16777216,換句話說,一個顏色用24位二進制表示,換算成十進制就是0~16777215。
這裏你應該能夠看懂上面CSS顏色表示方式前三個的含義了吧,至於rgba(R,G,B,A)多加入了A,表示透明度,這個是擴展版的32位顏色系統,多了一個額外的8位二進制表示透明度的級別,CSS將它簡化成0~1表示。github

    • *

舉個例子吧!
#FF55F3這個顏色爲例進行講解。(0x開頭表示十六進制數,js中不區分大小寫,至於不知道什麼是十六進制的,請自行百度)
紅色是0xFF,綠色是0x55,藍色0xF3
轉換成十進制:紅色是255,綠色是85,藍色是243。也就是說這個數值和rgb(255,85,243)寫法是等價的。canvas

【PS】簡便的轉換方法,直接在控制檯打印便可,好比 console.log(0xF3);,js默認輸出十進制表示的字符串。

顏色合成

顏色理論學得差很少了,如今來看看合成,已知三原色的值,要如何用代碼合成一個顏色呢?
以上面說的#FF55F3爲例,如今已知的是各個顏色值,下面提供兩種作法:函數

一、獲得rgb(R,G,B)格式

直接利用js數字轉換爲字符串時默認是十進制的特性。工具

let r = 0xFF;
let g = 0x55;
let b = 0xF3;
let color = `rgb(${r},${g},${b})`;

二、獲得#RRGGBB格式

一個24位的顏色值,二進制即:RRRRRRRRGGGGGGGGBBBBBBBB
紅色值左移16位,綠色左移8位,將三者作「或」就能獲得合成的24位顏色值,再轉成16進制字符串便可。code

0xFF << 16 = 111111110000000000000000
0x55 << 08 = 000000000101010100000000
0xF3       = 000000000000000011110011
OR         = 111111110101010111110011
//省略跟前面同樣的...
let color = `#${(r << 16 | g << 8 | b).toString(16)}`;

顏色分解

合成學完了,如今考慮一下如何用代碼分解顏色,也就是把一個顏色分離出紅、綠、藍。
rgb(R,G,B)格式就說了,切字符串就能獲得。
重點討論#RRGGBB格式,其實就是第二種合成方法的逆過程,右移後「與「操做,簡單來講就是把想要的顏色值所在的位置移動到末尾,再用「與」0xFF剔除其餘顏色。
仍是以#FF55F3爲例,現已知這個字符串,要求分解出三基色的值。教程

  1. 切除「#」號獲得16進制字符串;
  2. 紅色:右移16位,與0xFF作「與」操做;
  3. 綠色:右移8位,與0xFF作「與」操做;
  4. 藍色:直接與0xFF作「與」操做。
let color = parseInt('#FF55F3'.slice(1), 16);
let r = color >> 16 & 0xFF
let g = color >> 8 & 0xFF
let b = color & 0xFF

以綠色提取過程爲例:

0xFF55F3      = 111111110101010111110011
0xFF55F3 >> 8 = 000000001111111101010101
0xFF          = 000000000000000011111111
AND           = 000000000000000001010101

封裝顏色工具

固然,上面的合成、分解代碼都是基本理論的應用,實際項目中使用會爲了健壯性封裝成更加合理的工具,能夠參考咱們工具類utils.js中的colorToRGB()和parseColor()兩個函數。

  • colorToRGB()用於將#RRGGBB格式或任意數字,轉換成rgb(R,G,B)rgba(R,G,B,A)
  • parseColor()用於將#RRGGBB格式轉成數字,將數字轉成#RRGGBB格式。
相關文章
相關標籤/搜索