iT邦幫忙

2021 iThome 鐵人賽

DAY 24
2
Modern Web

前端藏寶圖系列 第 24

來做一個色碼轉換器吧!

前言

今天來做一個色碼轉換器~

我們先認識色碼之間的關係,拆解步驟後再一步步完成吧!

顏色表示的方法

  • RGB色碼:rgb(0, 0, 0) --- rgb(255, 255, 255)
  • HEX色碼:#000000 --- #ffffff
    • HEX 色碼是以十六進位值來代表顏色的一種方式。十六進位色碼的格式為#RRGGBB
    • 每個顏色值RR、GG、BB 各包含256個不同的值,範圍從00到FF

十六進制是什麼呢?

16 進制就是逢 16 進 1,但因為阿拉伯數字只有 0~9,所以需要 A~F 這六個字母來分別表示10~15,以下用表格呈現比較好瞭解,粗體是十進位制的數字,下一欄以十六進制表示。

1 2 3 ... 10 11 12 13 14 15 57
1 2 3 ... A B C D E F 39

如果跟我一樣很困惑為什麼 57 會變成 39 的朋友,可以拿起筆用直式除法將 57除以 16,會得到商數3和餘數9,是不是頓時豁然開朗~~JS 的 Number 物件已內建好轉換的方法,來看看吧!

Number.prototype.toString([radix])

  • radix 指的是要轉換的基數,如果沒有指定預設是 10,就是我們習慣用的十進制
  • 如果基數不在2~36之間就會報錯
(42).toString(2)      // 二進制: '101010'
(101).toString(8)     // 八進制: '145'
(255).toString(16)   // 十六進制:'ff' 
(256).toString(16)   // '100'
(123).toString(37)   // RangeError

有了這些概念,就開始來實作吧!照例先準備好HTML

<div class="red-group">
    <span>R</span>
    <input type="range" min="0" max="255" value="0" class="red">
    <span class="range">0</span>
  </div>

  <div class="green-group">
    <span>G</span>
    <input type="range" min="0" max="255" value="0" class="green">
    <span class="range">0</span>
  </div>

  <div class="blue-group">
    <span>B</span>
    <input type="range" min="0" max="255" value="0" class="blue">
    <span class="range">0</span>
  </div>
  
  <div class="hex">
    <p>#00000</p>
  </div>

步驟的部分我大致上拆解成三個

監聽 slider 變化 --> 將數值做轉換 --> 動態產生顏色以及數值

1. 監聽 slider 的滑鼠事件

這裡是先將要監聽的元素選取出來,綁上監聽器,當使用者滑動 slider 時就會觸發兩個 callback function: displayValue以及changeColor

const rangeSliders  = document.querySelectorAll('input');
const red = document.querySelector('.red');
const green = document.querySelector('.green')
const blue = document.querySelector('.blue')

//監聽並改變數值
rangeSliders.forEach(rangeSlider => 
                     rangeSlider.addEventListener('mousemove', displayValue))

//監聽並改變背景顏色
rangeSliders.forEach(rangeSlider => 
                     rangeSlider.addEventListener('mousemove', changeColor))

2. 將數值做轉換

就像先前提到的 RGB 色碼和 HEX 色碼間需要做換算,以下這個函式專門負責處理十進位轉十六進位

// 傳入三個參數,將數值改成十六進制表示
function rgbToHex(R,G,B) {
  const hexDigit = [R, G, B].map( item => {
    return Number(item).toString(16).padStart(2, '0')
  }).join('')
  
  return '#'+ hexDigit;
}

rgb的值轉成16進制後,有可能會只有一位數,所以需要使用字串方法補字元

(12).toString(16)  // 'c'  --> 使用str.padStart() 補成 '0c'

string.padStart(targetLength [, padString])

  • 第一個參數是字串被填充後的長度
  • 第二個參數是當字串長度小於第一個參數指定的數值時,會補上的字串

詳盡的介紹和使用可以參考這篇~好文推推! JavaScript 之旅 (5):String method - padStart & padEnd

3. 動態產生相對應的顏色以及數值

// 依據input當下的值改變背景色
function changeColor() {
  document.body.style.backgroundColor = `rgb(${red.value},${green.value},${blue.value})`;
}

// 顯示數值:這裡包含了 hex 和 rgb 的數值 
function displayValue(e) {
  const currentValue = e.target.value
  e.target.nextElementSibling.innerHTML = currentValue
  
  const hexValue = (rgbToHex(red.value, green.value, blue.value)).toUpperCase();
  
  const hex = document.querySelector('.hex p')
  hex.innerHTML = hexValue;
}

/images/emoticon/emoticon42.gif
這樣就完成了~~~實作 codepen連結

小結:

今天終於完成了曾經怎麼樣都寫不出來的色碼轉換器(連看了別人的程式碼也寫不出來QQ),重新挑戰成功的感覺真好~~~

參考資料:
MDN
stackoverflow
秒懂16 進位原理,快速搭配所需顏色
維基百科


上一篇
來做一個鐵人賽倒數計時器吧!
下一篇
來做一個簡單的 To-do List 吧! (上)
系列文
前端藏寶圖30

1 則留言

0
Hooo
iT邦新手 5 級 ‧ 2021-10-09 18:26:58

太酷了吧 色碼轉換器!/images/emoticon/emoticon24.gif

Chiahsuan iT邦新手 4 級 ‧ 2021-10-09 20:26:29 檢舉

你之後也可以試試看~~~很神奇喔XD

Chris iT邦新手 4 級 ‧ 2021-10-10 19:50:39 檢舉

可以 RGBA 嗎?

Chiahsuan iT邦新手 4 級 ‧ 2021-10-10 19:58:04 檢舉

那就要再增加一個透明度的slider,然後再轉換,有錯在麻煩糾正~~/images/emoticon/emoticon33.gif
感謝 Chris 出考題~~~/images/emoticon/emoticon41.gif

我要留言

立即登入留言