كل المقالات

واجهة ⁨HTML-in-Canvas⁩: ⁨Chrome⁩ يرسم ⁨DOM⁩ حقيقيًا داخل ⁨canvas⁩ و⁨WebGL⁩

منصة الويب · 4 دقيقة قراءة ·

إن بنيت يومًا تطبيقًا على ⁨canvas⁩ فأنت تعرف تلك اللحظة: الرسوميات سريعة، ثم يسأل أحدهم لماذا لا يستطيع تحديد النص، أو البحث فيه بـ⁨Ctrl+F⁩، أو سماعه عبر قارئ الشاشة. واجهة ⁨HTML-in-Canvas⁩ في ⁨Chrome⁩، المتاحة الآن كتجربة أولية (⁨origin trial⁩)، جواب عن هذا السؤال. فهي ترسم محتوى ⁨DOM⁩ حقيقيًا داخل ⁨canvas⁩ ثنائي الأبعاد أو خامة ⁨WebGL⁩ أو ⁨WebGPU⁩، ويبقى المحتوى تفاعليًا ومتاحًا لتقنيات الوصول.

الاختيار الذي تلغيه

يصف ⁨Thomas Nattestad⁩ و⁨Natalia Markoborodova⁩ الأمر بأنه مفاضلة قديمة. يمنحك ⁨DOM⁩ تخطيط النص وعناصر النماذج وكل ميزات المتصفح المبنية فوقه: أدوات الوصول، والترجمة، والبحث في الصفحة، ووضع القراءة، والإضافات، والتكبير، والملء التلقائي. أما ⁨canvas⁩ و⁨WebGL⁩ و⁨WebGPU⁩ فتمنحك شبكة من البكسلات وسرعة منخفضة المستوى، ولهذا تستخدمها الألعاب وتطبيقات مثل ⁨Google Docs⁩ و⁨Figma⁩. والثمن أن النص داخل شبكة البكسلات يفقد كل تلك الميزات، وإعادة بناء حتى النص المتجاوب يدويًا تكبّر حجم الحزمة.

⁨DOM⁩ نص ونماذج قارئ الشاشة والبحث ⁨canvas⁩ بكسلات وثلاثي الأبعاد سرعة منخفضة المستوى ⁨HTML-in-Canvas⁩ يُرسم ⁨DOM⁩ داخل ⁨canvas⁩ ويبقى ⁨DOM⁩
كنت تختار جانبًا واحدًا. الواجهة ترسم جانب ⁨DOM⁩ داخل جانب ⁨canvas⁩.

ما الذي تحصل عليه

بحسب مقال ⁨Chrome⁩، يحتفظ المحتوى المرسوم بهذه الطريقة بما يلي:

  • تخطيط النص، بما فيه النص متعدد الأسطر وثنائي الاتجاه مع تطبيق ⁨CSS⁩،
  • عناصر نماذج حقيقية،
  • تحديد النص والنسخ واللصق وقائمة النقر الأيمن،
  • شجرة الوصول، فتقرؤه قارئات الشاشة كأي ⁨HTML⁩ عادي،
  • البحث في الصفحة، مع إبراز النتيجة داخل خامة ⁨WebGL⁩،
  • الإضافات وأدوات المطور: غيّر قيمة ⁨CSS⁩ في المفتش فتتحدث الخامة ثلاثية الأبعاد.

سطر النص ثنائي الاتجاه يهمني تحديدًا. فالنص العربي الذي تتخلله كلمة إنجليزية من الأشياء التي تخطئ فيها تطبيقات ⁨canvas⁩ عادة، وهنا يتولى محرك النص في المتصفح نفسه هذا العمل.

كيف تعمل، في ثلاث خطوات

أولًا، ضع ⁨HTML⁩ داخل عنصر ⁨<canvas>⁩ وأضف السمة ⁨layoutsubtree⁩، التي تطلب من المتصفح تخطيط هذا المحتوى وكشفه لشجرة الوصول. ثانيًا، ارسمه داخل حدث ⁨paint⁩ الخاص بالـ⁨canvas⁩، وهو يُطلق كلما احتاج العنصر إلى إعادة رسم، كما عند تحديد النص أو الكتابة. ثالثًا، طبّق التحويل الذي يعيده استدعاء الرسم على ⁨style.transform⁩ للعنصر، لتقع النقرات ومرور المؤشر حيث رُسم العنصر فعلًا. هذا هو مثال المقال ثنائي الأبعاد:

<canvas id="canvas" style="width: 200px; height: 200px;" layoutsubtree>
  <div id="form_element">
    <label for="name">Name:</label> <input id="name" type="text">
  </div>
</canvas>
const ctx = document.getElementById('canvas').getContext('2d');
const form_element = document.getElementById('form_element');
const canvas = document.getElementById('canvas');

canvas.onpaint = () => {
  ctx.reset();
  // Draw the form element at x:0, y:0
  let transform = ctx.drawElementImage(form_element, 0, 0);

  // Sync the DOM location with the drawn location
  form_element.style.transform = transform.toString();
};
1. التهيئة ⁨layoutsubtree⁩ 2. الرسم حدث ⁨paint⁩ 3. المزامنة ⁨style.transform⁩ تتكرر مع كل رسم
تجاهل الخطوة الثالثة، فيُرسم العنصر في مكان وتذهب النقرات إلى مكان آخر.

في ⁨WebGL⁩ الاستدعاء هو ⁨texElementImage2D⁩، ويعمل مثل ⁨texImage2D⁩ لكنه يأخذ عنصر ⁨DOM⁩. وفي ⁨WebGPU⁩ هو ⁨copyElementImageToTexture⁩ على طابور الجهاز. وفي المشاهد ثلاثية الأبعاد لا يستطيع المتصفح أن يعرف أين يضع الـ⁨shader⁩ الخامة، فتبني المصفوفة بنفسك وتمررها إلى ⁨getElementTransform()⁩. لدى ⁨Three.js⁩ دعم تجريبي بالفعل عبر ⁨THREE.HTMLTexture⁩، ولدى ⁨PlayCanvas⁩ دعم عبر واجهة الخامات الخاصة به، وهذا يوفر عليك حساب المصفوفات.

كيف تجربها، وما حدودها

يقول المقال إن الواجهة في تجربة أولية في ⁨Chrome⁩ من الإصدار 148 حتى 150، وإنها في مرحلة مبكرة وقد تتغير تفاصيلها. للتجربة محليًا استخدم ⁨Chrome Canary⁩ بإصدار 149 أو أحدث مع تفعيل العلم ⁨chrome://flags/#canvas-draw-element⁩. ولتفعيلها لزوار موقعك، سجّل موقعك في التجربة الأولية.

يذكر الكاتبان قيدين. الأول أنها لا تعمل مع محتوى ⁨iframe⁩ من أصل مختلف، لأسباب أمنية وأسباب تتعلق بالخصوصية. والثاني أن المحتوى يُرسم بـ⁨JavaScript⁩، فلا يمكن للتمرير والحركة داخل ⁨canvas⁩ أن يعملا بمعزل عن الخيط الرئيسي كما في الصفحة العادية، فتأنَّ قبل وضع قائمة طويلة قابلة للتمرير داخلها.

نصيحة عامة: هذه الواجهة للتطبيقات التي تعيش أصلًا داخل ⁨canvas⁩. أما الصفحة العادية المبنية بـ⁨HTML⁩ و⁨CSS⁩ فلديها كل هذه الميزات أصلًا، ولا تكسب شيئًا من الانتقال إليها.

إن كان تطبيقك يرسم واجهته داخل ⁨canvas⁩ بالفعل، فهذه أول طريقة لاستعادة النص الحقيقي والنماذج وإمكانية الوصول دون إعادة بنائها. جرّبها خلف فحص للميزة، فهي تجربة أولية وليست معيارًا.

الخطوة التالية: ثبّت ⁨Chrome Canary⁩، وفعّل العلم، وجرّب المثال ثنائي الأبعاد أعلاه بحقل من نماذجك. إن صمد، فسجّل في التجربة واحتفظ ببديل لكل المتصفحات الأخرى. المصدر: مدونة ⁨Chrome for Developers⁩: تقديم التجربة الأولية لواجهة ⁨HTML-in-Canvas⁩.

ملاحظات القراء

  1. مفيش تعليقات لسه. الأول دايمًا الأجرأ.
بتبني حاجة زي كده؟ أقدر أساعدك. راسلني على واتساب