الغوص في JavaScript: كيفية إنشاء محول ألوان Hex2RGB

تحديث (23/07/2019): لقد قمت بتصحيح بعض الأخطاء النحوية وقمت بتغيير رمز app.js قليلاً عن طريق إزالة وظيفة checkBG.

في هذه المقالة ، سننشئ تطبيق ويب يحول رموز الألوان بين شكل سداسي عشري وشكل RGB.

يمكنك العثور على عرض هنا وكود المصدر هنا.

هيكل المشروع:

هيكل المشروع بسيط للغاية.

  1. index.html : يحتوي على هيكل التطبيق.
  2. style.css : أنماط الصفحة.
  3. app.js : يحتوي على كل الكود السحري.

فكرة:

فيما يلي قائمة بالأشياء التي أردت أن يؤديها هذا التطبيق:

  1. عندما يتم كتابة شيء ما في حقل نصي للعرافة ، يجب على التطبيق التحقق مما إذا كان اللون صالحًا. إذا كان الأمر كذلك ، فقم بتحويله إلى RGB ، واضبطه كخلفية ثم ضع قيمة RGB في حقل نص RGB والعكس صحيح.
  2. إذا تمت كتابة رمز لون سداسي عشري قصير في حقل النص ، فقم بتوسيعه عندما يفقد حقل النص التركيز (ينقر المستخدم خارج منطقة النص).
  3. إضافة رمز "#" تلقائيًا قبل الإدخال السداسي.

هيا نبدأ!

index.html

      Hex to RGB Converter HEX <--> RGB 

أنشأنا حقلين نصيين بمعرّف "hex" و "rgb" على التوالي. بجانب كل إدخال يوجد رمز SVG للخطأ ، والذي يحتوي على فئة مخفية افتراضيًا.

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

إليك مخطط أساسي لجعل العلامات تبدو أفضل قليلاً. لقد حددنا فئتين هنا ، .hiddenو .dark..hiddenيستخدم لإخفاء / إظهار رمز SVG الخطأ .darkوهو لتغيير لون النص بناءً على لون الخلفية. بشكل افتراضي ، قمت بتعيين النص على لون غامق (للخلفيات الساطعة).

app.js

ها هو الجزء السحري. سوف أقوم بتقسيم الكود إلى أجزاء:

أولاً ، حددنا المتغيرات التي تستهدف المدخلات بالمعرف "hex" و "rgb". بعد ذلك ، لدينا وظائف للتحقق مما إذا كان الإدخال Hex / RGB صالحًا أم لا. يستخدمون إعداد regex أساسي ويعيدون قيمة منطقية. إذا شعرت بالخوف من قبلهم ، فإنني أوصيك بتجربة هذا البرنامج التعليمي Regex.

هنا ، كتبنا دالة تحليل تسمى modifyHexوالتي تتحقق مما إذا كان طول سداسي عشرية 4 أحرف ؛ أي يحتوي على "#" وهو اختصار (على سبيل المثال ، # 333) ويستبدل "#" بحرف فارغ. ثم يتحقق مما إذا كان الطول الآن 3 ويوسعه إلى 6 أحرف (على سبيل المثال ، # 123 = # 112233).

لقد حددنا وظيفتين تقومان بتحويل hex إلى rgb والعكس صحيح. إليك تفصيل خطوة بخطوة لـ hexToRgb(هذه العملية مكتوبة بصيغة موسعة لفهم أفضل):

  1. حدد مصفوفة فارغة لتخزين النتيجة.
  2. استبدل الرمز "#" ، إذا كان موجودًا ، وإذا كان الطول لا يساوي 6 (أي ، النسخة المختصرة) ، فاتصل modifyHexبالوظيفة أعلاه وقم بتوسيعها.
  3. بطريقة أساسية للغاية ، يعمل hex إلى rgb عن طريق تحويل الكود السداسي (في الأساس 16) إلى كود RGB (في الأساس 10). يمثل كل حرفين في الكود السداسي العشري قيمة في رمز لون rgb. على سبيل المثال في #aabbcc ، الأحمر هو (aa إلى الأساس 10) ، والأخضر (bb إلى الأساس 10) والأزرق (cc إلى الأساس 10). لذلك في الدالة ، نقوم بتقطيع القيمة السداسية ، وتحويلها إلى الأساس 10 باستخدام parseInt، ثم تخزينها في المصفوفة المحددة.
  4. أخيرًا ، نعيد سلسلة الإخراج من خلال الانضمام إلى المصفوفة أعلاه.

ل rgbToHexوظيفة (وهذا هو مكتوب مع منطق أقصر):

  1. نحن نستخدم regex مباشرة لاستخراج قيم الأرقام فقط - أي أن rgb (123،21،24) سيعيد 123،21،24.
  2. بعد ذلك ، نستخدم دالة map لإرجاع مصفوفة جديدة ، والتي تحول الرقم إلى الأساس 16 ، ثم تبطن القيمة.

يُرجع التعبير المعتاد الذي استخدمناه أعلاه بيانات من النوع "سلسلة". لتحويلها إلى Base 16 ، يتعين علينا استخدام toString()  الطريقة ، بمعامل "16".

الآن ، toString()الطريقة قابلة للتطبيق على أنواع البيانات الرقمية فقط ، لذلك نستخدم parseIntأولاً تحويل كل عنصر من المصفوفة إلى رقم ، ثم نستخدمه toString(16)لتحويله إلى شكل سداسي عشري ، ثم نضيف حشوًا لجعله بطول حرفين بالضبط. الحشو ضروري ، إذا كان لديك شيء مثل "14" ، والذي تريد تحويله إلى نظام سداسي عشري ، فسيعيد "e". لكن رمز اللون السداسي يحتاج إلى حرفين لكل جزء ، لذا فإن الحشو مطلوب ، مما يجعله "0e".

ملاحظة: padStartهي ميزة ES8 ، والتي قد لا تكون مدعومة في كل متصفح. لإبقاء هذا البرنامج التعليمي بسيطًا ، لم أنقله إلى ES5.

3. أخيرًا ، نعيد المصفوفة الناتجة عن طريق ضمها وتحويلها إلى أحرف كبيرة.

errorMark()تُستخدم الوظيفة لإظهار أو إخفاء رمز SVG الخطأ. إنه ببساطة يمرر محتويات الإدخال ( hex.valueو rgb.value) من خلال وظائف التحقق الخاصة بكل منها ويستخدم المنطقي المرتجع لإضافة / إزالة .hiddenالفئة.

نحن الآن نحدد وظيفة تأخذ لون الخلفية ثم تحدد ما إذا كانت داكنة أو ساطعة (حصلت على هذا الرمز من StackOverflow). يضاعف قيم اللون الفردية ببعض الأرقام المحسوبة ويعيد "الأسود" أو "الأبيض". ثم أستخدم وظيفة أخرى لتغيير لون النص عن طريق إضافة / إزالة .darkالفصل.

إضافة مستمعي الأحداث:

أخيرًا ، نقوم بتوصيل جميع الوظائف من خلال إضافة مستمعي الأحداث.

أولاً ، نضيف keyupحدثًا إلى hexالمدخلات. يتم تشغيل هذا الحدث في كل مرة يتم فيها تحرير مفتاح. إليك تفاصيل العملية:

  1. تحقق مما إذا كان كود الإدخال صالحًا وقم بتوسيعه إذا كان اختصارًا.
  2. اضبط لون خلفية الجسم على قيمة الإدخال.
  3. تحقق من تباين الألوان وقم بتغيير لون النص وفقًا لذلك.
  4. قم باستدعاء وظيفة التحويل ووضع اللون المحول في حقل إدخال RGB.

مستمع الحدث الآخر الذي استخدمناه هو blur. يتم تشغيله في كل مرة يفقد فيها الإدخال "التركيز" ، أو يتم تشغيله في كل مرة تنقر فيها / تنقر خارج عنصر الإدخال blur. لذلك من الجيد تعديل الإدخال السداسي!

لذلك ، نتحقق مما إذا كان اللون السداسي صالحًا أم لا ، ثم نقوم بتوسيعه إذا كان قصيرًا ، وأخيرًا نضيف "#" إذا لم يكن موجودًا. لاحظ أننا نتحقق مما إذا كان الفهرس 0 و 1 يحتويان على "#". يتم ذلك حتى لا تسبق الوظيفة "#" مرتين.

keyupتتم إضافة مستمع الحدث نفسه إلى إدخال RGB ويتبع أيضًا نفس سلسلة الخطوات مثل مستمع الحدث السداسي.

أخيرًا ، أضفنا مستمع حدث keyupإلى المستند بأكمله ، أي أنه سيتم تشغيله لأي من عنصري الإدخال. في ذلك ، نقوم باستدعاء errorMarkالوظيفة ، والتي تضيف رمز الخطأ ، في حالة وجود خطأ ، أو إزالته إذا كان كل شيء صالحًا.

إليك الكود النهائي لـ 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(); })

استنتاج

ها أنت ذا! أعلم أن الكود ليس مثاليًا ويمكن إعادة بنائه ، لكن هذه مجرد البداية. إذا كنت ترغب في تحسين هذا الرمز ، يمكنك المضي قدمًا وفتح العلاقات العامة على github repo.

ترميز سعيد!