来做一个色码转换器吧!

前言

今天来做一个色码转换器~

我们先认识色码之间的关系,拆解步骤後再一步步完成吧!

颜色表示的方法

  • 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 进位原理,快速搭配所需颜色
维基百科


<<:  简报版-第八章-近年勒索软件加密威胁无人不知!注意基本观念「备份」一式三份

>>:  用React刻自己的投资Dashboard Day24 - styled components

Day06 - Parsing Ptt(补充)

接续Day04,在确认连上Ptt後,会将页面跳转至Login页,原本Day04应该要把这些都写进去的...

【Day 26】JavaScript AJAX - XMLHttpRequest

说明 : 藉由 XMLHttpRequest(XHR)物件的方式来存取服务器端的资料,可以直接经由指...

[Day3] 安全签章 - XOR加密(HashID)

API流程 I have A Nonce, I have A key, Uh It's time t...

Day 14:凯撒密码之Shifting Letters

在开始今天题目之前,先来认识一下凯撒密码 (Caesar cipher) 凯撒密码是一种替换加密技术...

Day07:07 - User服务(2) - 前端 - 注册、登入、JS正则表达式

Hi,Привет,我是Charlie! 在Day06当中,我们完成了後端的基本注册、登入,在今天我...