Kemas kini (23/07/2019): Saya telah membetulkan beberapa kesalahan tatabahasa dan sedikit mengubah kod app.js dengan menghapus fungsi checkBG.
Dalam artikel ini, kami akan membuat aplikasi web yang menukar kod warna antara bentuk Heksadesimal dan bentuk RGB.
Anda boleh mendapatkan demo di sini dan kod sumber di sini.
Struktur Projek:
Struktur projeknya cukup sederhana.
index.html
: Mengandungi struktur aplikasi.style.css
: Menggayakan halaman.app.js
: Mengandungi semua kod ajaib.
Idea:
Inilah senarai perkara yang saya mahukan aplikasi ini dilaksanakan:
- Setiap kali sesuatu ditaip di medan teks untuk hex, aplikasi harus memeriksa apakah warnanya sah. Sekiranya ada, ubah menjadi RGB, tetapkan sebagai latar belakang dan kemudian masukkan nilai RGB di medan teks RGB dan sebaliknya.
- Sekiranya kod warna hex pendek ditaip ke dalam medan teks, kembangkan apabila medan teks hilang fokus (pengguna mengklik di luar kawasan teks).
- Tambah simbol '#' secara automatik ke input hex.
Mari kita mulakan!
indeks.html
Hex to RGB Converter HEX <--> RGB ![]()
![]()
Kami membuat dua medan teks dengan id 'hex' dan 'rgb' masing-masing. Di sebelah setiap input terdapat ikon SVG untuk ralat, yang mempunyai kelas tersembunyi, secara lalai.
gaya.css
:root { --color: rgba(255,255,255,0.9); --tweet: white; } * { margin: 0; padding: 0; box-sizing: border-box; } ::placeholder { color: var(--color)!important; } body { padding: 50px; width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center; background-color: #28a745; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; } .head { position: absolute; top: 30px; text-align: center; color: var(--tweet); font-size: 3rem; border-bottom: 2px solid var(--tweet); } #content { display: block; } input { color: var(--color)!important; margin: 1rem 0; width: 400px; border: none; border-bottom: 1px solid var(--color); font-size: 2.5rem; background-color: transparent; } input:focus { outline: none; } img { width: 24px; } .hidden { visibility: hidden; opacity: 0.8; } .dark { --color: rgba(0,0,0,0.75); --tweet: rgba(0,0,0,0.95); } @media only screen and (max-width: 560px){ #content input { margin: 0.75rem 0; width: 90%; font-size: 1.875rem; } #content img { width: 16px; } .head { font-size: 2rem; } }
Inilah susun atur asas untuk menjadikan markup kelihatan lebih baik. Kami telah menentukan dua kelas di sini, .hidden
dan .dark
..hidden
digunakan untuk menyembunyikan / menunjukkan ikon kesalahan SVG dan .dark
untuk mengubah warna teks berdasarkan warna latar belakang. Secara lalai, saya telah menetapkan teks ke warna gelap (untuk latar belakang yang terang).
app.js
Inilah bahagian ajaibnya. Saya akan memecahkan kodnya menjadi beberapa bahagian:

Pertama, kami telah menentukan pemboleh ubah yang mensasarkan input dengan id 'hex' dan 'rgb'. Selanjutnya, kami mempunyai fungsi untuk memeriksa apakah input Hex / RGB sah atau tidak. Mereka menggunakan penyediaan regex asas dan mengembalikan boolean. Sekiranya anda diintimidasi oleh mereka, saya cadangkan anda untuk mencuba RegexTutorial ini.

Di sini, Kami menulis fungsi parse yang disebut modifyHex
yang memeriksa apakah hex input panjangnya 4 aksara; iaitu, mengandungi '#' dan pendek (misalnya, # 333) dan menggantikan '#' dengan watak kosong. Kemudian memeriksa apakah panjangnya sekarang adalah 3 dan memperluasnya menjadi 6 aksara (misalnya, # 123 = # 112233).

Kami telah menentukan dua fungsi yang menukar hex menjadi rgb dan sebaliknya. Berikut adalah langkah demi langkah untuk hexToRgb
(Proses ini ditulis dalam bentuk yang diperluas untuk pemahaman yang lebih baik):
- Tentukan array kosong untuk menyimpan hasilnya.
- Ganti simbol '#', jika ada, dan jika panjangnya tidak sama dengan 6 (iaitu versi pendek), panggil
modifyHex
fungsi di atas dan kembangkan. - Dengan cara yang sangat asas, hex ke rgb berfungsi dengan menukar kod hex (di pangkalan 16) ke kod rgb (di pangkalan 10). Setiap dua watak dalam kod hex mewakili nilai dalam kod warna rgb. Sebagai contoh dalam #aabbcc, merah adalah (aa ke pangkalan 10), hijau adalah (bb ke pangkalan 10) dan biru (cc ke pangkalan 10). Oleh itu, dalam fungsi tersebut, kita memotong nilai heksa, mengubahnya menjadi asas 10 menggunakan
parseInt
, dan kemudian menyimpannya dalam susunan yang ditentukan. - Akhirnya, kami mengembalikan rentetan output dengan bergabung dengan array di atas.
Untuk rgbToHex
fungsi (ini ditulis dengan logik yang lebih pendek):
- Kami secara langsung menggunakan regex untuk mengekstrak nilai nombor sahaja - iaitu, rgb (123,21,24) akan mengembalikan 123,21,24.
- Seterusnya, kami menggunakan fungsi peta untuk mengembalikan array baru, yang menukar nombor menjadi asas 16, kemudian menambah nilai.
Regex yang kami gunakan di atas mengembalikan data jenis 'string'. Untuk menukarnya ke Base 16, kita harus menggunakan toString()
kaedah tersebut, dengan parameter '16'.
Sekarang, toString()
metode hanya berlaku untuk jenis data angka, jadi kami gunakan parseInt
untuk mengubah setiap elemen array menjadi angka, kemudian menggunakannya toString(16)
untuk mengubahnya menjadi bentuk heksadesimal dan akhirnya menambahkan padding untuk membuatnya panjangnya 2 karakter. Padding diperlukan, jika anda mempunyai sesuatu seperti '14', yang ingin anda ubah menjadi heksadesimal, ia akan mengembalikan 'e'. Tetapi kod warna hex memerlukan 2 aksara untuk setiap bahagian, jadi padding diperlukan, yang menjadikannya '0e'.
Catatan: padStart
adalah ciri ES8, yang mungkin tidak disokong di setiap penyemak imbas. Untuk memastikan tutorial ini mudah, saya belum menyebarkannya ke ES5.
3. Akhirnya, kami mengembalikan susunan yang dihasilkan dengan menggabungkannya dan menukarnya menjadi huruf besar.

errorMark()
fungsi digunakan untuk menunjukkan atau menyembunyikan ikon kesalahan SVG. Ia hanya menyampaikan isi input ( hex.value
dan rgb.value
) melalui fungsi pemeriksaan masing-masing dan menggunakan boolean yang dikembalikan untuk menambah / membuang .hidden
kelas.

Sekarang kita menentukan fungsi yang mengambil warna latar belakang dan kemudian menentukan apakah itu gelap atau terang (saya mendapat kod ini dari StackOverflow). Ia mengalikan nilai warna individu dengan beberapa nombor yang dikira dan mengembalikan 'hitam' atau 'putih'. Saya kemudian menggunakan fungsi lain untuk menukar warna teks dengan menambahkan / membuang .dark
kelas.
Menambah Pendengar Acara:

Akhirnya, kami menghubungkan semua fungsi dengan menambahkan Event Pendengar.
Pertama, kami menambahkan keyup
acara ke hex
input. Acara ini dicetuskan setiap kali kunci dilepaskan. Inilah pecahan proses:
- Periksa sama ada kod input itu sah dan kembangkan jika kod pendek
- Tetapkan warna latar badan ke nilai input.
- Periksa kontras warna dan ubah warna teks dengan sewajarnya.
- Panggil fungsi tukar dan letakkan warna yang ditukar ke medan input RGB.
Pendengar acara lain yang kami gunakan adalah blur
. Ia dipicu setiap kali input kehilangan 'fokus', atau dalam istilah awam, setiap kali anda mengklik / mengetuk di luar elemen input, blur
dipicu. Jadi eloklah ubah hex input!
Oleh itu, kami memeriksa sama ada warna hex itu sah atau tidak, maka kami memperluasnya jika pendek, dan akhirnya kami menambahkan '#' jika tidak ada. Perhatikan bahawa kami sedang memeriksa apakah indeks 0 dan 1 mengandungi '#'. Ini dilakukan supaya fungsi tidak menambahkan '#' dua kali.

keyup
Pendengar acara yang sama ditambahkan ke input RGB dan ia juga mengikuti siri langkah yang sama dengan pendengar peristiwa hex.
Terakhir, kami telah menambahkan pendengar acara keyup
ke seluruh dokumen, iaitu, ia akan dipicu untuk salah satu daripada dua elemen input. Di dalamnya, kami memanggil errorMark
fungsi, yang menambahkan ikon ralat, sekiranya ada kesalahan, atau menghapusnya jika semuanya berlaku.
Inilah kod terakhir untuk app.js
:
const hex = document.getElementById("hex"); const rgb = document.getElementById("rgb"); // Check Functions function checkHex(hex) { const hexRegex = /^[#]*([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i if (hexRegex.test(hex)) { return true; } } function checkRgb(rgb) { const rgbRegex = /([R][G][B][A]?[(]\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])(\s*,\s*((0\.[0-9]{1})|(1\.0)|(1)))?[)])/i if (rgbRegex.test(rgb)) { return true } } // Parse Function function modifyHex(hex) { if (hex.length == 4) { hex = hex.replace('#', ''); } if (hex.length == 3) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; } return hex; } // Converting Functions function hexToRgb(hex) { let x = []; hex = hex.replace('#', '') if (hex.length != 6) { hex = modifyHex(hex) } x.push(parseInt(hex.slice(0, 2), 16)) x.push(parseInt(hex.slice(2, 4), 16)) x.push(parseInt(hex.slice(4, 6), 16)) return "rgb(" + x.toString() + ")" } function rgbToHex(rgb) { let y = rgb.match(/\d+/g).map(function(x) { return parseInt(x).toString(16).padStart(2, '0') }); return y.join('').toUpperCase() } // Helper Functions function addPound(x) { return '#' + x; } // Function to add cross mark on error values function errorMark() { if (checkHex(hex.value)) { document.getElementById('hexError').classList.add('hidden'); } else { document.getElementById('hexError').classList.remove('hidden'); } if (checkRgb(rgb.value)) { document.getElementById('rgbError').classList.add('hidden'); } else { document.getElementById('rgbError').classList.remove('hidden'); } } // Finding Contrast Ratio to change text color. Thanks //stackoverflow.com/a/11868398/10796932 function getContrastYIQ(hexcolor) { if (checkHex(hexcolor)) { hexcolor = hexcolor.replace("#", '') } else { hexcolor = rgbToHex(hexcolor) } var r = parseInt(hexcolor.substr(0, 2), 16); var g = parseInt(hexcolor.substr(2, 2), 16); var b = parseInt(hexcolor.substr(4, 2), 16); var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000; return (yiq >= 128) ? document.body.classList.add('dark') : document.body.classList.remove('dark') } // Adding Event Listeners hex.addEventListener('keyup', function() { let color = hex.value if (checkHex(color)) { color = modifyHex(color); document.body.style.backgroundColor = addPound(color); getContrastYIQ(color) rgb.value = hexToRgb(color); } }) hex.addEventListener('blur', function() { if (checkHex(hex.value)) { hex.value = modifyHex(hex.value) if (hex.value[1] != '#') { if (hex.value[0] != '#') { hex.value = addPound(hex.value); } } } }) rgb.addEventListener('keyup', function() { let color = rgb.value if (checkRgb(color)) { hex.value = color = addPound(rgbToHex(color)) document.body.style.backgroundColor = color; getContrastYIQ(color) } }) document.addEventListener('keyup', function() { errorMark(); })
Kesimpulannya
There you have it! I know the code is not perfect and can be refactored, but hey, this is just the beginning. If you want to improve this code, you can go ahead and open a PR on my github repo.
Happy Coding!