Actualizare (23/07/2019): Am corectat câteva erori gramaticale și am schimbat puțin codul app.js eliminând funcția checkBG.

În acest articol, vom crea o aplicație web care convertește codurile de culoare între forma hexazecimală și forma RGB.

Puteți găsi un demonstrație aici si codul sursă aici.

Structura proiectului:

Structura proiectului este destul de simplă.

  1. index.html : Conține structura aplicației.
  2. style.css : Stilizează pagina.
  3. app.js : Conține tot codul magic.

Idee:

Iată lista lucrurilor pe care am vrut să le efectueze această aplicație:

  1. Ori de câte ori se introduce ceva într-un câmp de text pentru hex, aplicația ar trebui să verifice dacă culoarea este validă. Dacă este, convertiți-l în RGB, setați-l ca fundal și apoi puneți valoarea RGB în câmpul de text RGB și invers.
  2. Dacă este introdus un scurt cod hexagonal de culoare în câmpul de text, extindeți-l atunci când câmpul de text pierde focalizarea (utilizatorul face clic în afara zonei de text).
  3. Introduceți automat simbolul „#” la intrarea hexagonală.

Sa incepem!

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Hex to RGB Converter</title>
  <link rel="stylesheet" href="https://www.freecodecamp.org/news/how-to-create-a-hex2rgb-color-converter-ce32d32afd1f/style.css">
</head>

<body>
  <div class="head">
    HEX &lt;--&gt; RGB
  </div>
  <div id="content">
    <input type="text" id="hex" placeholder="hex">
    <img id="hexError" class="hidden" src="data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIj48cGF0aCBkPSJNNTY5LjUxNyA0NDAuMDEzQzU4Ny45NzUgNDcyLjAwNyA1NjQuODA2IDUxMiA1MjcuOTQgNTEySDQ4LjA1NGMtMzYuOTM3IDAtNTkuOTk5LTQwLjA1NS00MS41NzctNzEuOTg3TDI0Ni40MjMgMjMuOTg1YzE4LjQ2Ny0zMi4wMDkgNjQuNzItMzEuOTUxIDgzLjE1NCAwbDIzOS45NCA0MTYuMDI4ek0yODggMzU0Yy0yNS40MDUgMC00NiAyMC41OTUtNDYgNDZzMjAuNTk1IDQ2IDQ2IDQ2IDQ2LTIwLjU5NSA0Ni00Ni0yMC41OTUtNDYtNDYtNDZ6bS00My42NzMtMTY1LjM0Nmw3LjQxOCAxMzZjLjM0NyA2LjM2NCA1LjYwOSAxMS4zNDYgroutechuOTgyIDExLjM0Nmg0OC41NDZjNi4zNzMgMCAxMS42MzUtNC45ODIgroutechuOTgyLTExLjM0Nmw3LjQxOC0xMzZjLjM3NS02Ljg3NC01LjA5OC0xMi42NTQtroutechuOTgyLTEyLjY1NGgtNjMuMzgzYy02Ljg4NCAwLTEyLjM1NiA1Ljc4LTExLjk4MSAxMi42NTR6Ii8+PC9zdmc+" />
    </br>
    <input type="text" id="rgb" placeholder="rgb">
    <img id="rgbError" class="hidden" src="data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIj48cGF0aCBkPSJNNTY5LjUxNyA0NDAuMDEzQzU4Ny45NzUgNDcyLjAwNyA1NjQuODA2IDUxMiA1MjcuOTQgNTEySDQ4LjA1NGMtMzYuOTM3IDAtNTkuOTk5LTQwLjA1NS00MS41NzctNzEuOTg3TDI0Ni40MjMgMjMuOTg1YzE4LjQ2Ny0zMi4wMDkgNjQuNzItMzEuOTUxIDgzLjE1NCAwbDIzOS45NCA0MTYuMDI4ek0yODggMzU0Yy0yNS40MDUgMC00NiAyMC41OTUtNDYgNDZzMjAuNTk1IDQ2IDQ2IDQ2IDQ2LTIwLjU5NSA0Ni00Ni0yMC41OTUtNDYtNDYtNDZ6bS00My42NzMtMTY1LjM0Nmw3LjQxOCAxMzZjLjM0NyA2LjM2NCA1LjYwOSAxMS4zNDYgroutechuOTgyIDExLjM0Nmg0OC41NDZjNi4zNzMgMCAxMS42MzUtNC45ODIgroutechuOTgyLTExLjM0Nmw3LjQxOC0xMzZjLjM3NS02Ljg3NC01LjA5OC0xMi42NTQtroutechuOTgyLTEyLjY1NGgtNjMuMzgzYy02Ljg4NCAwLTEyLjM1NiA1Ljc4LTExLjk4MSAxMi42NTR6Ii8+PC9zdmc+" />
  </div>
  <script src="app.js"></script>
</body>

</html>

Am creat două câmpuri de text cu ID-ul „hex” și respectiv „rgb”. Lângă fiecare intrare este o pictogramă SVG pentru eroare, care are în mod implicit o clasă de ascuns.

stil.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;
    }
}

Iată un aspect de bază pentru a face ca marcajul să arate puțin mai bine. Aici am definit două clase, .hidden și .dark. .hidden este folosit pentru a ascunde / afișa pictograma SVG de eroare și .dark este de a schimba culoarea textului pe baza culorii de fundal. În mod implicit, am setat textul la o culoare închisă (pentru fundaluri luminoase).

app.js

Iată partea magică. Voi descompune codul în bucăți:

Scufundarea in JavaScript Cum sa creati un convertor de culoare

În primul rând, am definit variabile care vizează intrările cu id-ul „hex” și „rgb”. În continuare, avem funcții pentru a verifica dacă intrarea Hex / RGB este validă sau nu. Folosesc o configurare regex de bază și returnează un boolean. Dacă te lasă intimidat de ei, îți recomand să încerci acest lucru RegexTutorial.

1611937988 245 Scufundarea in JavaScript Cum sa creati un convertor de culoare

Aici, am scris o funcție de analiză numită modifyHex care verifică dacă hexagonul de intrare are 4 caractere; adică conține „#” și este prescurtat (de exemplu, # 333) și înlocuiește „#” cu un caracter gol. Apoi verifică dacă lungimea este acum de 3 și o extinde la 6 caractere (de exemplu, # 123 = # 112233).

1611937988 810 Scufundarea in JavaScript Cum sa creati un convertor de culoare

Am definit două funcții care convertesc hex în rgb și invers. Iată o defalcare pas cu pas pentru hexToRgb(Acest proces este scris în formă extinsă pentru o mai bună înțelegere):

  1. Definiți o matrice goală pentru a stoca rezultatul.
  2. Înlocuiți simbolul „#”, dacă există, și dacă lungimea nu este egală cu 6 (adică versiunea pe scurt), apelați la cele de mai sus modifyHex funcționează și extinde-l.
  3. Într-un mod foarte de bază, hex în rgb funcționează prin conversia codului hex (în baza 16) în cod rgb (în baza 10). La fiecare două caractere din codul hexagonal reprezintă o valoare în codul de culoare rgb. De exemplu în #aabbcc, roșu este (aa la baza 10), verde este (bb la baza 10) și albastru este (cc la baza 10). Deci, în funcție, tranșăm valoarea hexagonală, transformând-o în baza 10 folosind parseInt, și apoi stocarea acestuia în matricea definită.
  4. În cele din urmă, returnăm șirul de ieșire prin alăturarea matricei de mai sus.

Pentru rgbToHex funcție (aceasta este scrisă cu o logică mai scurtă):

  1. Folosim direct o regex pentru a extrage numai valorile numărului – adică rgb (123,21,24) va returna 123,21,24.
  2. Apoi, folosim o funcție de hartă pentru a returna o nouă matrice, care convertește numărul în baza 16, apoi tamponează valoarea.

Expresia pe care am folosit-o mai sus returnează date de tipul „șir”. Pentru a-l converti în baza 16, trebuie să folosim toString() metoda, cu un parametru de ’16’.

Acum, toString() metoda este aplicabilă numai tipurilor de date numerice, așa că folosim parseInt pentru a converti mai întâi fiecare element al matricei într-un număr, apoi utilizați toString(16) pentru a-l converti în formă hexazecimală și apoi adăugați în final umplutura pentru a avea exact 2 caractere. Căptușirea este necesară, dacă aveți ceva de genul „14”, pe care doriți să îl convertiți în hexazecimal, acesta va întoarce „e”. Dar codul hexagonal de culoare are nevoie de 2 caractere pentru fiecare parte, deci este necesară umplerea, ceea ce îl face să fie „0e”.

Notă: padStart este o caracteristică ES8, care ar putea să nu fie acceptată în fiecare browser. Pentru a păstra acest tutorial simplu, nu l-am transpus în ES5.

3. În cele din urmă, returnăm matricea rezultată prin unirea acesteia și convertirea acesteia în majuscule.

1611937988 77 Scufundarea in JavaScript Cum sa creati un convertor de culoare

errorMark() funcția este utilizată pentru a afișa sau ascunde pictograma SVG de eroare. Trece pur și simplu conținutul intrării ( hex.value și rgb.value ) prin funcțiile lor de verificare respective și folosește booleanul returnat pentru a adăuga / elimina .hidden clasă.

1611937990 624 Scufundarea in JavaScript Cum sa creati un convertor de culoare

Acum definim o funcție care ia culoarea de fundal și apoi determină dacă este întunecată sau strălucitoare (am primit acest cod de la StackOverflow). Înmulțește valorile individuale ale culorilor cu unele numere calculate și returnează „negru” sau „alb”. Apoi folosesc o altă funcție pentru a schimba culoarea textului adăugând / eliminând .dark clasă.

Adăugarea de ascultători de evenimente:

1611937990 53 Scufundarea in JavaScript Cum sa creati un convertor de culoare

În cele din urmă, conectăm toate funcțiile prin adăugarea de ascultători de evenimente.

În primul rând, adăugăm un keyup eveniment la hex intrare. Acest eveniment este declanșat de fiecare dată când este eliberată o cheie. Iată defalcarea procesului:

  1. Verificați dacă codul de intrare este valid și extindeți-l dacă este scurt.
  2. Setați culoarea de fundal a corpului la valoarea de intrare.
  3. Verificați contrastul culorilor și modificați culoarea textului în consecință.
  4. Apelați funcția de conversie și plasați culoarea convertită în câmpul de intrare RGB.

Celălalt ascultător de evenimente pe care l-am folosit este blur . Este declanșat de fiecare dată când intrarea pierde „focalizarea” sau, în termeni simpli, de fiecare dată când faceți clic / atingeți în afara elementului de intrare, blur este declanșat. Deci, este bine să modificați hex-ul de intrare!

Deci, verificăm dacă culoarea hexagonală este validă sau nu, apoi o extindem dacă este scurtă și, în cele din urmă, adăugăm un „#” dacă nu există. Rețineți că verificăm dacă indexul 0 și 1 conțin „#”. Acest lucru este realizat astfel încât funcția să nu prevină „#” de două ori.

1611937991 394 Scufundarea in JavaScript Cum sa creati un convertor de culoare

La fel keyup ascultătorul de evenimente este adăugat la intrarea RGB și, de asemenea, urmează aceeași serie de pași ca și ascultătorul de evenimente hex.

În cele din urmă, am adăugat un ascultător de evenimente keyup la întregul document, adică va fi declanșat pentru oricare dintre cele două elemente de intrare. În el, apelăm la errorMark funcție, care adaugă pictograma eroare, în cazul în care apare o eroare, sau o elimină dacă totul este valid.

Iată codul final pentru 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 https://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();
})

Concluzie

Iată-l! Știu că codul nu este perfect și poate fi refactorizat, dar hei, acesta este doar începutul. Dacă doriți să îmbunătățiți acest cod, puteți continua și deschide un PR pe my github repo.

Codificare fericită!