Eintauchen in JavaScript: So erstellen Sie einen Hex2RGB-Farbkonverter

Update (23/07/2019): Ich habe einige Grammatikfehler korrigiert und den app.js-Code ein wenig geändert, indem ich die checkBG-Funktion entfernt habe.

In diesem Artikel erstellen wir eine Web-App, die Farbcodes zwischen Hexadezimalform und RGB-Form konvertiert.

Eine Demo finden Sie hier und den Quellcode hier.

Projektstruktur:

Die Projektstruktur ist ziemlich einfach.

  1. index.html : Enthält die Struktur der App.
  2. style.css : Stylen Sie die Seite.
  3. app.js : Enthält den gesamten magischen Code.

Idee:

Hier ist die Liste der Dinge, die diese App ausführen soll:

  1. Immer wenn etwas in ein Textfeld für Hex eingegeben wird, sollte die App prüfen, ob die Farbe gültig ist. Wenn dies der Fall ist, konvertieren Sie es in RGB, legen Sie es als Hintergrund fest und geben Sie den RGB-Wert in das RGB-Textfeld ein und umgekehrt.
  2. Wenn ein kurzer hexadezimaler Farbcode in das Textfeld eingegeben wird, erweitern Sie ihn, wenn das Textfeld den Fokus verliert (Benutzer klickt außerhalb des Textbereichs).
  3. Stellen Sie dem Hex-Eingang automatisch das Symbol '#' voran.

Lass uns anfangen!

index.html

      Hex to RGB Converter HEX <--> RGB 

Wir haben zwei Textfelder mit der ID 'hex' bzw. 'rgb' erstellt. Neben jeder Eingabe befindet sich standardmäßig ein SVG-Symbol für Fehler, das eine Klasse von ausgeblendeten hat.

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

Hier ist ein grundlegendes Layout, damit das Markup ein bisschen besser aussieht. Wir haben hier zwei Klassen definiert, .hiddenund .dark..hiddenwird verwendet, um das Fehler-SVG-Symbol auszublenden / anzuzeigen und .darkum die Textfarbe basierend auf der Hintergrundfarbe zu ändern. Standardmäßig habe ich den Text auf eine dunkle Farbe eingestellt (für helle Hintergründe).

app.js.

Hier ist der magische Teil. Ich werde den Code in Stücke zerlegen:

Zunächst haben wir Variablen definiert, die auf die Eingaben mit den IDs 'hex' und 'rgb' abzielen. Als nächstes haben wir Funktionen, um zu überprüfen, ob die Eingabe Hex / RGB gültig ist oder nicht. Sie verwenden ein grundlegendes Regex-Setup und geben einen Booleschen Wert zurück. Wenn Sie sich von ihnen einschüchtern lassen, empfehle ich Ihnen, dieses RegexTutorial auszuprobieren.

Hier haben wir eine Analysefunktion namens aufgerufen, modifyHexdie prüft, ob das eingegebene Hex 4 Zeichen lang ist. Das heißt, enthält '#' und ist eine Kurzform (z. B. # 333) und ersetzt das '#' durch ein leeres Zeichen. Dann wird geprüft, ob die Länge jetzt 3 beträgt, und auf 6 Zeichen erweitert (z. B. # 123 = # 112233).

Wir haben zwei Funktionen definiert, die hex in rgb konvertieren und umgekehrt. Hier ist eine schrittweise Aufschlüsselung für hexToRgb(Dieser Prozess ist zum besseren Verständnis in erweiterter Form geschrieben):

  1. Definieren Sie ein leeres Array, um das Ergebnis zu speichern.
  2. Ersetzen Sie das Symbol '#', falls vorhanden, und wenn die Länge nicht gleich 6 ist (dh die Kurzfassung), rufen Sie die obige modifyHexFunktion auf und erweitern Sie sie.
  3. In einer sehr einfachen Weise funktioniert hex zu rgb, indem der hexadezimale Code (in Basis 16) in rgb-Code (in Basis 10) konvertiert wird. Alle zwei Zeichen im Hex-Code stehen für einen Wert im RGB-Farbcode. Zum Beispiel in #aabbcc ist Rot (aa zu Basis 10), Grün ist (bb zu Basis 10) und Blau ist (cc zu Basis 10). In der Funktion schneiden wir den Hex-Wert auf, konvertieren ihn mit zur Basis 10 parseIntund speichern ihn dann im definierten Array.
  4. Schließlich geben wir die Ausgabezeichenfolge zurück, indem wir das obige Array verbinden.

Für die rgbToHexFunktion (dies wird mit kürzerer Logik geschrieben):

  1. Wir verwenden direkt einen regulären Ausdruck, um nur die Zahlenwerte zu extrahieren - das heißt, rgb (123,21,24) gibt 123,21,24 zurück.
  2. Als nächstes verwenden wir eine Map-Funktion, um ein neues Array zurückzugeben, das die Zahl in Basis 16 konvertiert und dann den Wert auffüllt.

Der oben verwendete reguläre Ausdruck gibt Daten vom Typ 'string' zurück. Um es in Base 16 zu konvertieren, müssen wir die toString()  Methode mit dem Parameter '16' verwenden.

Jetzt ist die toString()Methode nur auf numerische Datentypen anwendbar. Daher parseIntkonvertieren wir zuerst jedes Element des Arrays in eine Zahl, toString(16)konvertieren es dann in eine hexadezimale Form und fügen schließlich einen Abstand hinzu, um es genau 2 Zeichen lang zu machen. Das Auffüllen ist erforderlich. Wenn Sie etwas wie '14' haben, das Sie in hexadezimal konvertieren möchten, wird 'e' zurückgegeben. Der hexadezimale Farbcode benötigt jedoch 2 Zeichen für jedes Teil, sodass eine Auffüllung erforderlich ist, wodurch es zu '0e' wird.

Hinweis: padStartDies ist eine ES8-Funktion, die möglicherweise nicht in jedem Browser unterstützt wird. Um dieses Tutorial einfach zu halten, habe ich es nicht auf ES5 übertragen.

3. Schließlich geben wir das resultierende Array zurück, indem wir es verbinden und in Großbuchstaben konvertieren.

errorMark()Mit dieser Funktion wird das SVG-Fehlersymbol ein- oder ausgeblendet. Es übergibt einfach den Inhalt der Eingabe ( hex.valueund rgb.value) durch ihre jeweiligen Prüffunktionen und verwendet den zurückgegebenen Booleschen Wert, um die .hiddenKlasse hinzuzufügen / zu entfernen .

Jetzt definieren wir eine Funktion, die die Hintergrundfarbe verwendet und dann feststellt, ob es dunkel oder hell ist (ich habe diesen Code von StackOverflow erhalten). Es multipliziert die einzelnen Farbwerte mit einigen berechneten Zahlen und gibt 'schwarz' oder 'weiß' zurück. Ich benutze dann eine andere Funktion, um die Textfarbe durch Hinzufügen / Entfernen der .darkKlasse zu ändern .

Hinzufügen von Ereignis-Listenern:

Schließlich verbinden wir alle Funktionen durch Hinzufügen von Ereignis-Listenern.

Zuerst fügen wir keyupder hexEingabe ein Ereignis hinzu . Dieses Ereignis wird jedes Mal ausgelöst, wenn eine Taste losgelassen wird. Hier ist die Prozessaufschlüsselung:

  1. Überprüfen Sie, ob der Eingabecode gültig ist, und erweitern Sie ihn, wenn er kurz ist.
  2. Stellen Sie die Hintergrundfarbe des Körpers auf den Eingabewert ein.
  3. Überprüfen Sie den Farbkontrast und ändern Sie die Textfarbe entsprechend.
  4. Rufen Sie die Konvertierungsfunktion auf und platzieren Sie die konvertierte Farbe in das RGB-Eingabefeld.

Der andere Ereignis-Listener, den wir verwendet haben, ist blur. Es wird jedes Mal ausgelöst, wenn die Eingabe den Fokus verliert, oder in Laienbegriffen jedes Mal, wenn Sie außerhalb des Eingabeelements klicken / tippen blur. Es ist also gut, das Eingabefeld zu ändern!

Wir prüfen also, ob die Hex-Farbe gültig ist oder nicht, erweitern sie, wenn sie kurz ist, und fügen schließlich ein '#' hinzu, wenn sie nicht vorhanden ist. Beachten Sie, dass wir prüfen, ob Index 0 und 1 '#' enthalten. Dies geschieht, damit die Funktion '#' nicht zweimal voranstellt.

Dem keyupRGB-Eingang wird derselbe Ereignis-Listener hinzugefügt, und er folgt ebenfalls der gleichen Reihe von Schritten wie der Hex-Ereignis-Listener.

Zuletzt haben wir keyupdem gesamten Dokument einen Ereignis-Listener hinzugefügt , der für jedes der beiden Eingabeelemente ausgelöst wird. Darin rufen wir die errorMarkFunktion auf, die im Fehlerfall das Fehlersymbol hinzufügt oder es entfernt, wenn alles gültig ist.

Hier ist der endgültige Code für 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(); })

Fazit

Hier hast du es! Ich weiß, dass der Code nicht perfekt ist und überarbeitet werden kann, aber hey, das ist erst der Anfang. Wenn Sie diesen Code verbessern möchten, können Sie eine PR auf meinem Github-Repo öffnen.

Viel Spaß beim Codieren!