Dykning i JavaScript: Sådan oprettes en Hex2RGB farvekonverter

Opdatering (23/07/2019): Jeg har rettet et par grammatiske fejl og ændret app.js-koden lidt ved at fjerne checkBG-funktionen.

I denne artikel opretter vi en webapp, der konverterer farvekoder mellem hexadecimal form og RGB-form.

Du kan finde en demo her og kildekoden her.

Projektstruktur:

Projektstrukturen er ret enkel.

  1. index.html : Indeholder appens struktur.
  2. style.css : Formaterer siden.
  3. app.js : Indeholder al den magiske kode.

Ide:

Her er listen over ting, jeg ville have denne app til at udføre:

  1. Når der er skrevet noget i et tekstfelt til hex, skal appen kontrollere, om farven er gyldig. Hvis det er tilfældet, skal du konvertere det til RGB, indstille det som baggrund og derefter sætte RGB-værdien i RGB-tekstfeltet og omvendt.
  2. Hvis der indtastes en kort hex-farvekode i tekstfeltet, skal du udvide den, når tekstfeltet mister fokus (brugeren klikker uden for tekstområdet).
  3. Forhæng automatisk '#' symbolet til hex input.

Lad os begynde!

index.html

      Hex to RGB Converter HEX <--> RGB 

Vi oprettede to tekstfelter med henholdsvis 'hex' og 'rgb'. Ved siden af ​​hver indgang er der et SVG-ikon for fejl, som som standard har en klasse skjult.

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

Her er et grundlæggende layout for at få markeringen til at se lidt bedre ud. Vi har defineret to klasser her, .hiddenog .dark..hiddenbruges til at skjule / vise fejl SVG-ikonet og .darker til at ændre tekstfarven baseret på baggrundsfarven. Som standard har jeg indstillet teksten til en mørk farve (for lyse baggrunde).

app.js

Her er den magiske del. Jeg vil nedbryde koden i klumper:

For det første har vi defineret variabler, der er målrettet mod input med id 'hex' og 'rgb'. Dernæst har vi funktioner til at kontrollere, om input Hex / RGB er gyldig eller ej. De bruger en grundlæggende regex-opsætning og returnerer en boolsk. Hvis du bliver skræmt af dem, anbefaler jeg dig at prøve denne RegexTutorial.

Her skrev vi en parsefunktion kaldet modifyHexsom kontrollerer om input hex er 4 tegn lang; indeholder '#' og er stenografi (for eksempel # 333) og erstatter '#' med et tomt tegn. Derefter kontrolleres det, om længden nu er 3 og udvider den til 6 tegn (f.eks. # 123 = # 112233).

Vi har defineret to funktioner, der konverterer hex til rgb og omvendt. Her er en trinvis opdeling af hexToRgb(Denne proces er skrevet i udvidet form for bedre forståelse):

  1. Definer et tomt array for at gemme resultatet.
  2. Udskift '#' symbolet, hvis det findes, og hvis længden ikke er lig med 6 (det vil sige kortversionen), skal du ringe til ovenstående modifyHexfunktion og udvide den.
  3. På en meget grundlæggende måde fungerer hex til rgb ved at konvertere hex-koden (i base 16) til rgb-kode (i base 10). Hvert andet tegn i hexkoden repræsenterer en værdi i rgb-farvekoden. For eksempel i #aabbcc er rød (aa til base 10), grøn er (bb til base 10) og blå er (cc til base 10). Så i funktionen udskærer vi hex-værdien, konverterer den til base 10 ved hjælp af parseIntog lagrer den derefter i det definerede array.
  4. Endelig returnerer vi outputstrengen ved at slutte os til ovenstående array.

For rgbToHexfunktionen (dette er skrevet med kortere logik):

  1. Vi bruger direkte en regex til kun at udtrække antallet af værdier - det vil sige rgb (123,21,24) returnerer 123,21,24.
  2. Dernæst bruger vi en kortfunktion til at returnere et nyt array, der konverterer tallet til base 16 og derefter padser værdien.

Den regex, vi brugte ovenfor, returnerer data af typen 'streng'. For at konvertere den til Base 16 skal vi bruge toString()  metoden med parameteren '16'.

Nu er toString()metoden anvendelig til kun numeriske datatyper, så vi bruger parseInttil først at konvertere hvert element i arrayet til et tal, derefter bruge toString(16)til at konvertere det til hexadecimal form og derefter til sidst tilføje polstring for at gøre det nøjagtigt 2 tegn langt. Polstring er nødvendig, hvis du har noget som '14', som du vil konvertere til hexadecimal, returnerer det 'e'. Men hex-farvekode har brug for 2 tegn til hver del, så polstring er påkrævet, hvilket gør den til '0e'.

Bemærk: padStarter en ES8-funktion, som muligvis ikke understøttes i enhver browser. For at holde denne tutorial enkel, har jeg ikke sendt den til ES5.

3. Endelig returnerer vi det resulterende array ved at forbinde det og konvertere det til store bogstaver.

errorMark()funktionen bruges til at vise eller skjule SVG-fejlikonet. Det sender simpelthen indholdet af input ( hex.valueog rgb.value) gennem deres respektive kontrolfunktioner og bruger den returnerede boolske til at tilføje / fjerne .hiddenklassen.

Nu definerer vi en funktion, der tager baggrundsfarven og derefter bestemmer, om den er mørk eller lys (jeg har denne kode fra StackOverflow). Det multiplicerer de individuelle farveværdier med nogle beregnede tal og returnerer 'sort' eller 'hvid'. Jeg bruger derefter en anden funktion til at ændre tekstfarven ved at tilføje / fjerne .darkklassen.

Tilføjelse af lyttere til begivenheder:

Endelig forbinder vi alle funktioner gennem tilføjelse af lyttere til begivenheder.

Først tilføjer vi en keyupbegivenhed til hexinput. Denne begivenhed udløses hver gang en nøgle frigives. Her er procesopdelingen:

  1. Kontroller, om inputkoden er gyldig, og udvid den, hvis den er stenografi.
  2. Sæt kroppens baggrundsfarve til inputværdien.
  3. Kontroller farvekontrasten, og skift tekstfarven i overensstemmelse hermed.
  4. Ring til konverteringsfunktionen, og placer den konverterede farve i RGB-indtastningsfeltet.

Den anden begivenhedslytter, vi brugte, er blur. Det udløses hver gang input mister 'fokus', eller i lægmandssprog blurudløses hver gang du klikker / trykker uden for inputelementet. Så det er godt at ændre input hex!

Så vi kontrollerer, om hex-farven er gyldig eller ej, så udvider vi den, hvis den er kort, og til sidst tilføjer vi et '#', hvis det ikke findes. Bemærk, at vi kontrollerer, om indeks 0 og 1 indeholder '#'. Dette gøres, så funktionen ikke afhænger af '#' to gange.

Den samme keyupbegivenhedslytter føjes til RGB-indgangen, og den følger også den samme række trin som den hex-begivenhedslytter.

Endelig har vi tilføjet en begivenhedslytter keyuptil hele dokumentet, det vil sige, det udløses for et af de to inputelementer. I den kalder vi errorMarkfunktionen, som tilføjer fejlikonet, hvis der er en fejl eller fjerner den, hvis alt er gyldigt.

Her er den sidste kode for 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(); })

Konklusion

Der har du det! Jeg ved, at koden ikke er perfekt og kan omarbejdes, men hej, det er kun begyndelsen. Hvis du vil forbedre denne kode, kan du gå videre og åbne en PR på min github repo.

Glad kodning!