كيفية استخدام حركة الوجه للتفاعل مع الطباعة
نشرت: 2022-03-10يبحث مصممو الويب دائمًا عن طرق جديدة لتحسين عرض محتوى الصفحة. في بعض الأحيان ، يمكن أن يؤدي ذلك إلى حلول بارعة أو التفاعل مع التقنيات التي غالبًا ما تكون بعيدة عن مجال التصميم. في هذه المقالة سنجعل الطباعة على اتصال مع الذكاء الاصطناعي ، باستخدام التعلم الآلي لاكتشاف أشياء مثل قرب وجه المستخدم من أجل تحسين وضوح النص.
سنقوم بتجربة كيفية استخدام التعرف على الوجوه مع Tensorflow من أجل استخراج بعض المعلومات من الكاميرا ، مثل المسافة بين الشاشة ووجه المستخدم أو عدد الأشخاص الذين يقرؤون الصفحة. بعد ذلك ، سنقوم بتمرير هذه البيانات إلى CSS من أجل تكييف الطباعة وتعديل تخطيط الصفحة.
ما هو Tensorflow؟
Tensorflow هو نظام أساسي مفتوح المصدر من Google للتعلم الآلي. التعلم الآلي هو أحد مجالات علوم الكمبيوتر التي تدرس الخوارزميات التي تتعلم التعرف على العلاقات المعقدة والأنماط المتكررة من الصور والمسارات الصوتية والسلاسل الزمنية والنص الطبيعي والبيانات بشكل عام. تولد هذه الخوارزميات نماذج رياضية (تسمى أيضًا النماذج المدربة) ، والتي تعد نوعًا من المخطط الذي يمكن استخدامه لاتخاذ القرارات بناءً على بيانات الإدخال. إذا كنت ترغب في تناول الموضوع ، كتب تشارلي جيرارد عن ML لمطوري الواجهة الأمامية هنا على Smashing Mag.
يوفر Tensorflow الكثير من الأدوات لمطوري الذكاء الاصطناعي وعلماء البيانات وعلماء الرياضيات ، ولكن لا داعي للذعر إذا لم يكن تحليل البيانات هو خبزك اليومي! الخبر السار هو أنه لا يجب أن تكون خبيرًا لاستخدامه ، طالما أنك تستخدم نماذج مسبقة الصنع ، تمامًا كما سنقوم بذلك.
نماذج Tensorflow متاحة للاستخدام على الويب مع JavaScript SDK.
اقامة
لبدء استخدام خوارزميات التعرف على الوجوه ، نحتاج إلى اتباع بعض الخطوات:
- تحميل Tensorflow SDK.
- قم بتحميل مكتبة Facemesh التي تحتوي على النموذج الرياضي.
- الوصول إلى كاميرا المستخدم ودفقها إلى عنصر فيديو HTML. سوف يقوم Facemesh بتحليل الإطارات من علامة الفيديو لاكتشاف وجود الوجوه.
في هذه المشاريع ، سنستخدم Tensorflow عبر CDN ، ولكنه متاح أيضًا على NPM إذا كنت تفضل طريقة التجميع:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl"></script>
لا تقوم Tensorflow بالخدعة نفسها ، لذلك نحتاج إلى إضافة Facemesh ، وهي مكتبة مبنية على الجزء العلوي من إطار عمل ML وتوفر نموذجًا مدربًا بالفعل للتعرف على الوجوه:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
الخطوة التالية هي إعداد مكتبة Facemesh من أجل تحميل النموذج المدرَّب ولتحديد الوظيفة التي ستقيم بيانات الوجه من دفق فيديو:
// create and place the video const video = document.createElement('video'); document.body.appendChild(video); // setup facemesh const model = await facemesh.load({ backend: 'wasm', maxFaces: 1, }); async function detectFaces() { const faces = await model.estimateFaces(video); console.log(faces); // recursively detect faces requestAnimationFrame(detectFaces); }
نحن الآن جاهزون لنطلب من المستخدم الإذن بالوصول إلى دفق الكاميرا الخاص به باستخدام علامة فيديو:
// enable autoplay video.setAttribute('autoplay', ''); video.setAttribute('muted', ''); video.setAttribute('playsinline', ''); // start face detection when ready video.addEventListener('canplaythrough', detectFaces); // stream the camera video.srcObject = await navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode: 'user', }, }); // let's go! video.play();
ستطلب طريقة navigator.mediaDevices.getUserMedia الإذن وستبدأ في دفق الكاميرا إلى عنصر الفيديو. بمجرد القبول ، ستبدأ الكاميرا في التدفق إلى علامة الفيديو ، بينما ستسجل وحدة تحكم المتصفح معلومات الوجه التي اكتشفها Facemesh.
يرجى ملاحظة أن أذونات الكاميرا تتطلب اتصال https آمنًا أو مضيف محلي: لا يمكنك ببساطة فتح ملف index.html. إذا لم تكن متأكدًا من كيفية إعداد خادم محلي ، فراجع http-server لـ Node أو اتبع هذا الدليل لـ Python أو هذا الدليل لـ PHP.
الحالة 1. ضبط الطباعة باستخدام كاميرا الهاتف الذكي
نحن نتصفح الويب في كل مكان باستخدام هاتفنا الذكي. كان هناك وقت ، ليس منذ فترة طويلة ، حيث اعتدنا ركوب القطارات أو الحافلات المزدحمة وأبقينا الهاتف الذكي قريبًا جدًا من أعيننا لأنه لم يكن هناك مكان. في العديد من اللحظات والأماكن في يومنا هذا ، غالبًا ما نغير موضع وميل الهاتف الذكي ، حتى لو كنا نشاهد نفس الموقع. تؤثر المسافة بين العينين والهاتف الذكي على قدرات القراءة لدينا. بتقييم تلك المسافة ، يمكننا ضبط الطباعة الدقيقة من أجل تحسين الصور الرمزية لقراءة أقرب أو أبعد.
يعني اكتشاف الوجه ، بالطبع ، اكتشاف موضع العين أيضًا. يمكننا استخدام البيانات المقدمة من Facemesh لحساب حجم وجهنا فيما يتعلق بالصورة الكاملة التي التقطتها الكاميرا. يمكننا أن نفترض أنه كلما زاد حجم وجهنا ، كلما اقتربنا من الشاشة. يمكننا إعداد مقياس من 0 (ذراع واحد بعيدًا - يشغل الوجه نصف الكاميرا تقريبًا) إلى 1 (ملتصق بالشاشة) واكتشاف القيمة الحالية بتقسيم المقاطع:
async function detectFaces() { const faces = await model.estimateFaces(video); if (faces.length === 0) { // is somebody out there? return requestAnimationFrame(detectFaces); } const [face] = faces; // extract face surface corners let { bottomRight, topLeft} = face.boundingBox; // calculate face surface size let width = bottomRight[0] - topLeft[0]; let height = bottomRight[1] - topLeft[1]; let videoWidth = video.videoWidth; let videoHeight = video.videoHeight; let adjustWidth = videoWidth / 2; let adjustHeight = videoHeight / 2; // detect the ratio between face and full camera picture let widthRatio = Math.max(Math.min((width - adjustWidth) / (videoWidth - adjustWidth), 1), 0); let heightRatio = Math.max(Math.min((height - adjustHeight) / (videoHeight - adjustHeight), 1), 0); let ratio = Math.max(widthRatio, heightRatio); // recursively detect faces requestAnimationFrame(detectFaces); }
الآن وقد قمنا بحساب ratio
، حان الوقت لتحقيق بعض السحر ، وتمرير القيمة إلى ورقة الأنماط:
document.documentElement.style.setProperty('--user-distance', ratio);
باستخدام هذه القيمة وقليلًا من الحساب ، يمكننا بسهولة تطبيق تغييرات طفيفة على وزن الخط وحجمه وربما النمط أيضًا ، ولكن يمكننا القيام بشيء أفضل. باستخدام خط متغير ، وهو خط يحتوي على أشكال ذات معلمات ومسافات من الحروف الرسومية ، يمكننا ضبط إدراك كل حرف رسومي عن طريق تحديث تباين الحجم البصري.
نظرًا لأن كل خط متغير يستخدم مقياسه الخاص لقيم الحجم البصري ، فنحن بحاجة إلى ربط قيمة النسبة الخاصة بنا بهذا المقياس. علاوة على ذلك ، قد نرغب في الانتقال فقط بين مجموعة فرعية من الحجم البصري المتاح ، من أجل توفير القليل من التحسينات.
.main-text { --min-opsz: 10; --max-opsz: 15; --opsz: calc(var(--min-opsz) + (var(--user-distance) * (var(--max-opsz) - var(--min-opsz)))); ... font-family: 'Amstelvar', serif; font-variation-settings: 'opsz' var(--opsz); }
يمكنك رؤيتها تعيش هنا. يرجى ملاحظة أن هذا المثال هو مجرد عرض توضيحي لكيفية عمل التكنولوجيا. يجب أن تكون التغييرات المطبعية غير محسوسة تقريبًا لعيون المستخدم من أجل توفير تجربة أفضل للقارئ حقًا. استفدنا هنا من أشكال الحروف الرسومية ، ولكن استخدام الألوان لزيادة أو تقليل التباينات هو مجرد حل جيد آخر للتجربة. كانت تجربة أخرى هي اكتشاف زاوية الوجه من أجل حساب منظور القراءة ، وتعديل الصاعدة ، والمنحدرات ، وارتفاع الحروف:
الحالة رقم 2: تعديل التخطيط عندما يتغير عدد الأشخاص الذين يبحثون
في هذه الحالة الثانية ، سنقوم بتغيير التخطيط على أساس عدد الأشخاص الذين يشاهدون الشاشة. يمكننا تخيل مقال معروض على السبورة التفاعلية في سياق فصل دراسي بالمدرسة الثانوية. يختلف هذا السيناريو بهدوء عن السيناريو الذي تم اكتشافه بواسطة استعلام وسائط الإسقاط المهمل نظرًا لأننا نريد تعديل تخطيط الصفحة إذا كان عدد الطلاب الذين يشاهدون أصغر أو أكبر من 10. عندما يكون عدد قليل من الطلاب في الفصل الدراسي ، فإنهم يمكن أن يقترب بأمان من السبورة ، ولكن إذا كان الفصل الدراسي بأكمله موجودًا ، فربما لا تكون المساحة كافية ونحتاج إلى تغيير التخطيط لإظهار أشياء أقل (وأكبر).
نحتاج فقط إلى بعض التغييرات على النص السابق من أجل الكشف بشكل صحيح عن عدد الوجوه التي تشاهد على السبورة البيضاء. أولاً ، نحتاج إلى توجيه Facemesh لاكتشاف وجوه متعددة:
const model = await facemesh.load({ backend: 'wasm', maxFaces: 30, });
وبعد ذلك ، يتعين علينا تمرير هذا الرقم إلى ورقة الأنماط:
async function detectFaces() { const faces = await model.estimateFaces(video); document.documentElement.style.setProperty('--watching', faces.length); // recursively detect faces requestAnimationFrame(detectFace); }
مرة أخرى ، يمكننا استخدام هذه القيمة لزيادة حجم الخط ببساطة ، لكن هدفنا هو توفير تنسيق مختلف تمامًا. قد تساعدنا تخطيطات شبكة CSS في هذه المهمة. هذا المستند المسقط هو نموذج طويل به جانب يحتوي على صور ذات صلة:
<section> <article> <h1>...</h1> <h2>...</h2> <p>...</p> </article> <aside> <img src="..." alt="..." /> </aside> </section>
وهذا تخطيطه الافتراضي:
section { display: grid; grid-template-columns: repeat(12, 1fr); grid-column-gap: 1em; width: 120ch; max-width: 100%; padding: 1em; } section article { grid-column: 1 / -5; } section aside { grid-column: 7 / -1; }
عندما يشاهد عدد كبير من الأشخاص ، نحتاج إلى منح امتياز لسياق القراءة الطويلة ، وإعطاء مساحة أكبر للعمود الرئيسي ، وزيادة حجم الخط ، وإزالة العناصر المزعجة. للقيام بذلك ، نقوم بزيادة عدد الأعمدة الممتدة ، مع تحريك الجانب الجانبي أسفل النص الرئيسي.
:root { --watching: 10; } section { /** The maximum number of people watching for the default layout */ --switch: 10; /** The default number of columns for the text */ --text: 8; /** The default number of columns for the aside */ --aside: 4; grid-template-columns: repeat(calc(var(--text) + var(--aside)), 1fr); } section article { /** * Kinda magic calculation. * When the number of people watching is lower than --switch, it returns -2 * When the number of people watching is greater than --switch, it returns -1 * We are going to use this number for negative span calculation */ --layout: calc(min(2, (max(var(--switch), var(--watching)) - var(--switch) + 1)) - 3); /** * Calculate the position of the end column. * When --layout is -1, the calculation just returns -1 * When --layout is -2, the calculation is lower than -1 */ --layout-span: calc((var(--aside) * var(--layout)) + var(--aside) - 1); /** * Calculate the maximum index of the last column (the one "before" the aside) */ --max-span: calc(-1 * var(--aside) - 1); /** * get the max between --layout-span and the latest column index. * -1 means full width * --max-span means default layout */ --span: max(var(--max-span), var(--span)); grid-column-start: 1; grid-column-end: var(--span); }
- يمكنك رؤيتها تعيش هنا →
Viceversa ، عندما تواجه مجموعة صغيرة من الطلاب النص بالقرب من اللوحة ، يمكننا تقديم المزيد من التفاصيل ، مثل ملفات الوسائط ومشغلات الإجراءات التفاعلية.
ما وراء التعرف على الوجوه
الحالات التي واجهناها () هي مجرد مثالين لكيفية استخدام تقنية التعرف على الوجوه للنطاقات التخطيطية أو المطبعية. يوفر Tensorflow نماذج ومكتبات أخرى يمكنها تحويل تدفق الكاميرا إلى متغيرات لصفحاتنا. علاوة على ذلك ، يجب ألا ننسى أنه يوجد في هواتفنا الذكية الكثير من أجهزة الاستشعار الأخرى التي يمكننا استغلالها باستخدام واجهات برمجة تطبيقات الاستشعار: نظام تحديد المواقع العالمي (GPS) ، ومقياس التسارع ، والضوء المحيط ، وما إلى ذلك.
نظرًا لأن الحالة المزاجية تؤثر على الطريقة التي نقرأ بها وندرسها ونبحث عنها ، فمن خلال التعلم الآلي يمكننا أيضًا تحليل تعبيرات المستخدم للتبديل من التخطيطات البسيطة إلى التخطيطات التفصيلية وفقًا لأرواح المستخدم.
لسنوات عديدة اعتدنا على استخدام استعلامات CSS Media لتصميم الويب سريع الاستجابة. ومع ذلك ، فإن حجم منفذ العرض ليس سوى واحد من متغيرات تجربة المستخدم. في الآونة الأخيرة ، نوع جديد من استعلام الوسائط المصمم لاحترام تفضيلات المستخدم قد وصل إلى المستعرضات ، مثل نظام prefers-color-scheme
المفضل prefers-reduced-motion
. يمنح هذا المصممين والمطورين طريقة للمضي قدمًا في ممارسات تصميم الويب ، مما يسمح لصفحة الويب بالتكيف مع البيئة بأكملها بدلاً من جهاز المستخدم فقط. في عصر البيانات الضخمة ، لدينا الفرصة لتجاوز التصميم سريع الاستجابة والتكيف. يمكن لصفحات الويب الخاصة بنا أخيرًا "مغادرة الشاشة" وتصبح جزءًا من تجربة المستخدم العالمية. سيشمل التصميم التفاعلي كل هذه الاحتمالات ، لذا فإن الاستمرار في تجربة التركيبات المحتملة بين التكنولوجيا وتصميم الويب سيكون أمرًا بالغ الأهمية في السنوات التالية.