Merülés a JavaScript-be: Hogyan készítsünk Hex2RGB színátalakítót

Frissítés (2019.07.23.): Javítottam néhány nyelvtani hibát és kissé megváltoztattam az app.js kódot azáltal, hogy eltávolítottam a checkBG funkciót.

Ebben a cikkben létrehozunk egy webalkalmazást, amely átalakítja a színkódokat a hexadecimális és az RGB formák között.

Itt talál egy bemutatót, a forráskódot pedig itt.

Projekt felépítése:

A projekt felépítése meglehetősen egyszerű.

  1. index.html : Az alkalmazás felépítését tartalmazza.
  2. style.css : Stílusozza az oldalt.
  3. app.js : Minden mágikus kódot tartalmaz.

Ötlet:

Itt van a lista azokról a dolgokról, amelyeket szerettem volna, hogy ez az alkalmazás:

  1. Amikor valamit beírunk egy szövegmezőbe a hexa számára, az alkalmazásnak ellenőriznie kell, hogy a szín érvényes-e. Ha igen, konvertálja RGB -vé, állítsa be háttérként, majd tegye az RGB értéket az RGB szövegmezőbe és fordítva.
  2. Ha egy rövid hexadecimális színkódot ír be a szövegmezőbe, akkor bontsa ki, ha a szövegmező elveszíti a fókuszt (a felhasználó a szövegterületen kívül kattint).
  3. A „#” szimbólum automatikus megadása a hexadecimális bemenethez

Kezdjük!

index.html

      Hex to RGB Converter HEX <--> RGB 

Két olyan szövegmezőt hoztunk létre, amelyek azonosítója 'hex', illetve 'rgb'. Minden bemenet mellett található egy SVG hiba ikon, amelynek alapértelmezés szerint rejtett osztálya van.

stílus.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; } } 

Itt van egy alapvető elrendezés, hogy a jelölés egy kicsit jobban nézzen ki. Itt két osztályt definiáltunk, .hiddenés .dark..hiddenaz SVG hiba elrejtésére / megjelenítésére szolgál, és .darka szöveg színének megváltoztatására a háttérszín alapján. Alapértelmezés szerint sötét színűre állítottam a szöveget (világos háttérhez).

app.js

Itt van a varázslat. A kódot darabokra bontom:

Először meghatároztunk olyan változókat, amelyek a bemeneteket „hex” és „rgb” azonosítóval célozzák meg. Ezután funkciókkal ellenőrizhetjük, hogy a Hex / RGB bemenet érvényes-e vagy sem. Alapvető regex beállítást használnak, és logikai értéket adnak vissza. Ha megfélemlíti őket, akkor ajánlom, hogy próbálja ki ezt a RegexTutorial-t.

Itt írtunk egy elemző függvényt, modifyHexamelynek neve: a bemeneti hexa 4 karakter hosszú; vagyis a „#” szót tartalmazza, és rövidítés (például # 333), és a „#” karaktert üres karakterrel helyettesíti. Ezután ellenőrzi, hogy a hossz most 3-e, és kibővíti-e 6 karakter hosszúságúra (például # 123 = # 112233).

Két olyan funkciót definiáltunk, amelyek a hexát rgb-vé alakítják, és fordítva. Itt van egy lépésenkénti bontás hexToRgb(Ez a folyamat kibővített formában van megírva a jobb megértés érdekében):

  1. Adjon meg egy üres tömböt az eredmény tárolásához.
  2. Cserélje ki a „#” szimbólumot, ha létezik, és ha a hossza nem egyenlő 6-val (vagyis a gyorsírásos verzióval), hívja meg a fenti modifyHexfüggvényt, és bővítse ki.
  3. Nagyon egyszerű módon a hexáról rgb-re úgy működik, hogy a hex kódot (a 16. alapban) rgb kódokká alakítja (a 10. alapban). A hexakódban minden két karakter egy értéket képvisel az rgb színkódban. Például az #aabbcc-ban a piros (aa-tól 10-ig), a zöld (bb-től 10-ig), kék pedig (cc-től 10-ig). Tehát a függvényben feldaraboljuk a hexa értéket, felhasználásával átalakítjuk a 10 alapra parseInt, majd eltároljuk a meghatározott tömbben.
  4. Végül a fenti tömb csatlakozásával visszaküldjük a kimeneti karakterláncot.

A rgbToHexfüggvényhez (ezt rövidebb logikával írjuk):

  1. Közvetlenül egy regexet használunk, hogy csak a számértékeket nyerjük ki, vagyis az rgb (123,21,24) 123,21,24-et ad vissza.
  2. Ezután egy térképfüggvény segítségével adunk vissza egy új tömböt, amely a számot 16 alapra konvertálja, majd kitölti az értéket.

A fent használt regex a 'string' típusú adatokat adja vissza. A Bázis 16-ba konvertálásához toString()  a "16" paraméterű metódust kell használnunk .

Most a toString()módszer csak numerikus adattípusokra alkalmazható, ezért parseIntelőször a tömb minden elemét toString(16)számokká alakítjuk, majd hexadecimális alakúra konvertáljuk, majd végül kitöltést adunk hozzá, hogy pontosan 2 karakter hosszú legyen. A kitöltésre szükség van, ha van valami, mint '14', amelyet hexadecimálissá kíván konvertálni, akkor az 'e' -t adja vissza. De a hexadecimális színkódhoz 2 karakterre van szükség minden résznél, ezért kitöltésre van szükség, ami '0e' értéket ad.

Megjegyzés: padStartegy ES8 szolgáltatás, amelyet nem minden böngésző támogat. Annak érdekében, hogy ez az oktatóanyag egyszerű legyen, még nem fordítottam át az ES5-re.

3. Végül visszaküldjük a kapott tömböt, összekapcsolva és nagybetűvé alakítva.

errorMark()funkció az SVG hiba megjelenítésére vagy elrejtésére szolgál. Egyszerűen átadja a bemenet ( hex.valueés rgb.value) tartalmát a megfelelő ellenőrzési funkcióikon keresztül, és a visszatérő logikai értéket használja az .hiddenosztály hozzáadásához / eltávolításához .

Most meghatározunk egy olyan funkciót, amely felveszi a háttér színét, majd meghatározza, hogy sötét vagy világos-e (ezt a kódot a StackOverflow-tól kaptam). Megszorozza az egyes színértékeket néhány számított számmal, és „fekete” vagy „fehér” értéket ad vissza. Ezután egy másik funkcióval megváltoztatom a szöveg színét az .darkosztály hozzáadásával / eltávolításával .

Eseményhallgatók hozzáadása:

Végül összekapcsoljuk az összes funkciót az Eseményhallgatók hozzáadásával.

Először egy keyupeseményt adunk a hexbemenethez. Ez az esemény minden egyes kulcs felszabadításakor elindul. Itt van a folyamat lebontása:

  1. Ellenőrizze, hogy a beviteli kód érvényes-e, és bontsa ki, ha rövidítésű.
  2. Állítsa be a törzs háttérszínét a bemeneti értékre.
  3. Ellenőrizze a színkontrasztot, és ennek megfelelően változtassa meg a szöveg színét.
  4. Hívja meg a konvertálás funkciót, és helyezze az átalakított színt az RGB beviteli mezőbe.

A másik eseményhallgató, akit használtunk, az blur. Ez akkor aktiválódik, amikor a bemenet elveszíti a „fókuszt”, vagy laikus értelemben, minden egyes alkalommal, amikor a bemeneti elemen kívül kattint / megérinti, bluraktiválódik. Tehát jó módosítani a bemeneti hexát!

Tehát ellenőrizzük, hogy a hexa szín érvényes-e vagy sem, majd kibővítjük, ha rövid, és végül hozzáadunk egy „#” -t, ha nem létezik. Ne feledje, hogy ellenőrizzük, hogy a 0. és 1. index tartalmaz-e '#' jelet. Ez úgy történik, hogy a függvény ne írja be kétszer a „#” karaktert.

Ugyanazt az keyupeseményfigyelőt adják az RGB bemenethez, és ez is ugyanazokat a lépéseket követi, mint a hex eseményfigyelő.

Végül hozzáadtunk egy eseményhallgatót keyupa teljes dokumentumhoz, vagyis a két beviteli elem bármelyikéhez beindul. Ebben a errorMarkfüggvényt hívjuk meg , amely hozzáadja a hiba ikont, ha hiba van, vagy eltávolítja, ha minden érvényes.

Itt van a végső kód 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(); })

Következtetés

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!