دروس نصية SVG: تعليق توضيحي نصي على الويب

نشرت: 2022-03-11

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

دروس نصية SVG - شرح نصي

وجد المطورون العديد من الحلول للحد من مستعرض الويب. تتضمن العديد من هذه الحلول استخدام CSS بطرق أقل سهولة ، حيث يستخدم البعض الصور في العناصر الزائفة ":: after". يعمل هذا ، ولكن غالبًا ما يكون الحفاظ على العديد من الصور لكل زوج من الألوان ذات النمط أمرًا صعبًا. تلقي هذه المقالة نظرة على تشريح مكتبة JavaScript التي تحاول حل هذه المشكلة بأناقة.

المكتبة مفتوحة المصدر ومتاحة على GitHub: Text Annotator

ملخص

أثناء تطوير هذه المكتبة ، تم إيلاء اهتمام خاص لضمان التوافق مع متصفحات الويب الأكثر شيوعًا (بما في ذلك IE 9+). ومع ذلك ، على عكس كيفية حل هذه المشكلة ، لا تعتمد المكتبة على حيل CSS غامضة على وجه التحديد ؛ أو ما هو أسوأ ، رموز Unicode الخاصة. بدلاً من ذلك ، يستخدم SVG لتحقيق زخارف نصية أفضل وأنظف.

بشكل أساسي ، تنفذ المكتبة "فئة" التعليقات التوضيحية التي يمكن استخدامها لإنشاء عناصر DIV تلقائيًا ، ووضعها تحت نصوص للتعليق عليها ، وملء خلفياتهم بصور SVG. يمكن دمج DIVs المتعددة لتخصيص الزخارف بشكل أكبر. النهج متوافق مع المستعرضات ، ويوفر المرونة في تحديد موضع العناصر الزخرفية ، ويسمح بتوسيع أسهل باستخدام القوالب المخصصة.

تم تطوير المكتبة باستخدام Google Closure Tools لأنها معيارية ومتعددة المستعرضات ، مما يساعد على إنتاج كود JavaScript مدمج وسريع دون أي تبعية إضافية.

بنيان

تم تصميم المكتبة كمجموعة من "فئات" JavaScript ، وتعرض جميع الوظائف الضرورية للمستخدم من خلال "class" Annotator:

مكتبة النص التوضيحي

فيما يلي عرض موجز للوظائف المتاحة:

  • annotateDocument - يعلق على العناصر ، والتي يتم تمييزها بسمة "تعليق توضيحي للبيانات".

  • تسطير - تسطير العنصر

  • تسليط الضوء - يبرز العنصر

  • الإضراب - عنصر الضربات

  • - تسطير محدد - تسطير النص المحدد

  • التحديد - يبرز النص المحدد

  • الإضراب المحدد - ضربات النص المحدد

  • unannotateElement - يزيل التعليق التوضيحي من العنصر

  • getTemplates - يعرض قاموس قوالب التعليقات التوضيحية

  • setUnderlineOptions - لتعيين إعدادات مضيف التعليقات على التسطير

  • setHighlightOptions - لضبط الإعدادات لتمييز التعليق التوضيحي

  • setStrikeOptions - يضبط إعدادات مضرب التعليق التوضيحي

تحتوي فئة التعليقات التوضيحية على ثلاث مثيلات لفئة AnnotatorImpl لكل وظيفة تعليق توضيحي: تسطير وتمييز وخط.

 tvs.Annotator = function() { this.underliner_ = new tvs.AnnotatorImpl( 'underliner', tvs.Annotator.getTemplates(), tvs.AnnotatorCore.underlinePositioner); this.highlighter_ = new tvs.AnnotatorImpl( 'highlighter', tvs.Annotator.getTemplates(), tvs.AnnotatorCore.highlightPositioner, {opacity: 0.45}); this.striker_ = new tvs.AnnotatorImpl( 'striker', tvs.Annotator.getTemplates(), tvs.AnnotatorCore.strikePositioner); };

يتم إنشاء مثيلات AnnotatorImpl بمعرفات مختلفة وكائنات مساعد تحديد الموضع. تُستخدم المعرفات التي تم تمريرها لاحقًا في أسماء فئات CSS وأسماء الحقول الداخلية ، مما يتطلب أن تكون المعرفات فريدة. أيضًا ، يتم تمرير مرجع إلى قائمة القوالب المعروفة (يمكن تغييرها لاحقًا).

كل كائن محدد موضع هو تنفيذ لواجهة IPositioner التي لها طريقة "getPosition" فقط وتبدو كما يلي:

 /** * Underline positioner * @implements {tvs.IPositioner} */ tvs.AnnotatorCore.underlinePositioner = /** @type {!tvs.IPositioner} */ ({ /** * @param {Object} elementRect * @param {number} annotationHeight * @return {{left: number, top: number, width: number, height: number}} */ getPosition: function(elementRect, annotationHeight) { return { width: elementRect.width, height: annotationHeight, left: elementRect.left, top: elementRect.bottom - (elementRect.height * 0.1) }; } });

يسمح ذلك باستخدام كل قالب مع وضع خط تحت ، أو تمييز ، أو كتابة تعليق توضيحي. عند تطبيق تعليق توضيحي على عنصر ، يتم الحصول على المربع المحيط للعنصر من خلال استدعاء "getElementRects" كما هو موضح أدناه:

 var rects = elemOrEv.getClientRects();

تقوم هذه الطريقة بإرجاع مجموعة من المستطيلات التي تشير إلى المستطيلات المحيطة لكل مربع في العميل. بعد تمرير كل مستقيم إلى جهاز تحديد المواقع الخرساني ، سنحصل على حدود الوجهة.

قوالب التعليقات التوضيحية النصية بتنسيق SVG

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

محتوى

المحتوى عبارة عن مجموعة من عناصر SVG ممثلة كسلسلة. نظرًا لأن هذا المحتوى لا يحتوي على عقدة SVG جذر حيث يتم تعيين عرض إطار العرض وارتفاعه (بالبكسل) ، فإن مُنشئ جزء القالب يقبلهم كمعلمات. على سبيل المثال ، يمكنك تحديد حجم منفذ العرض على أنه 100 بكسل × 100 بكسل ورسم خط على (50 ، 50) و (25 ، 25). بعد تطبيق التعليق التوضيحي ، سيتم تغيير حجم جميع عناصر svg إلى الحجم المطلوب بشكل صحيح. يمكن أن تستخدم قيمة المحتوى السلسلة "{0}" والتي سيتم استبدالها باللون الذي حدده المستخدم.

يعرض SVG التالي خطًا قطريًا. سنستخدم هذا كأحد الأجزاء في مثال على نمط التعليق التوضيحي التالي بعد قليل:

 <line x1="0" y1="0" x2="5" y2="5" stroke-width="2" stroke="red" />

عرض

عرض النموذج عبارة عن سلسلة يمكن أن تكون "*" أو "ارتفاع" أو أي شيء آخر:

  • يحدد "*" عرض جميع العناصر بنجمة متساوية مع بعضها البعض

  • يحدد "الارتفاع" العرض المساوي لارتفاع عنصر التعليق التوضيحي

سيتم تعيين أي شيء آخر هنا مباشرة إلى عرض CSS وخصائص min-width.

خصائص CSS

وضع الرسم

وضع الرسم هو سلسلة يمكن أن تكون إما "تكرار" أو "تمدد". كما تشير القيم ، فإن تعيينه على "تكرار" سيؤدي إلى تكرار المحتوى ، بينما يؤدي تعيينه على "امتداد" إلى تمديد المحتوى.

فيما يلي مثال لما يمكننا تحقيقه من خلال تكوين هذه المعلمات الثلاثة:

شرح نصي

يحتوي التعليق التوضيحي النصي في المثال أعلاه على 4 أجزاء. الجزء الأول هو الخط القطري ، مع ضبط عرض القالب على "الارتفاع" وضبط وضع الرسم على "التكرار". الجزء الثاني تم ضبط عرض القالب الخاص به على "*" وضبط وضع الرسم على "تكرار". تم تعيين الجزء الثالث ليكون عرضه "15 بكسل" ويتم رسمه في وضع "التكرار". أخيرًا ، يتم ضبط عرض الجزء الأخير على "*" ويتم ضبط وضع الرسم على "تمدد".

عند تقييم هذه العروض ، يأخذ الجزء الأول 5 بكسل (يساوي ارتفاع عنصر التعليق التوضيحي) ، بينما يأخذ الجزء الثالث 15 بكسل (كما هو محدد) ، ويتم تقسيم المساحة المتبقية بالتساوي بين الجزأين الثاني والرابع.

عندما يتم تمييز نفس الجزء من النص باستخدام نفس القالب ، فهذا ما نحصل عليه:

وضع الرسم

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

يؤدي تطبيق تأثير شطب على نفس النص بنفس القالب إلى الحصول على نتيجة مشابهة جدًا للنص الأول. الاختلاف الوحيد هو الموقع حيث يتم وضع عناصر التعليق التوضيحي:

وضع رسم anootation النص

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

 var t = new tvs.Template(new tvs.SvgTemplatePart( '<line y2="16.00" x2="20" y1="4.00" ' + 'x1="10" stroke-linecap="round" ' + 'stroke-width="5" stroke="{0}" fill="none"/>' + '<line y2="4.00" x2="10" y1="16.00" ' + 'x1="0" stroke-linecap="round" ' + 'stroke-width="5" stroke="{0}" fill="none"/>', 20, 20, 'repeat' ))

عندما يتم تقييم هذه القوالب ، يتم تغيير حجم المحتوى ويتم استبدال "{0}" باللون المحدد تلقائيًا. علاوة على ذلك ، فإن إضافة قوالب جديدة أمر بسيط مثل إضافتها إلى كائن JavaScript:

 tvs.AnnotatorDictionary.svgTemplates['brush'] = new tvs.Template(new tvs.SvgTemplatePart( svgContent, 50, 50, '*', 'stretch' ));

نتائج

يتم تطبيق كل تعليق توضيحي من خلال إلحاق عنصر div مع تحديد موضع مطلق للصفحة:

 <div class="tvs-annotate-element"> <div class="tvs-wrap-div"> <table> <tr> <td></td> <td></td> <td></td> </tr> </table> </div> </div>

يتم ملء عنصر div بجدول حيث تتوافق كل خلية تمت إضافتها مع أحد الأجزاء الموجودة في القالب. تتم إضافة محتوى كل جزء من أجزاء القالب باعتباره URI للبيانات المشفرة باستخدام Base64 ، مع تطبيق اللون المحدد:

 tvs.SvgTemplatePart.prototype.getBackground = function(color) { var image = tvs.AnnotatorCore.formatString(this.content, [color]); var encodedSVG = goog.crypt.base64.encodeString(image); return 'data:image/svg+xml;base64,' + encodedSVG; };

التضمين

للحصول على تجربة مستخدم أفضل ، خاصة عند محاولة استخدام مكتبة JavaScript هذه مع مناطق محتوى قابلة للتحرير ، من المهم أن يعرف Text Annotator حدود النص المحدد حاليًا بواسطة المستخدم. تم استخدام Rangy ، وهي مكتبة JavaScript أنيقة تتعامل مع النطاق والاختيار ، لتحقيق ذلك بطريقة عبر المستعرضات. يوفر Rangy واجهة برمجة تطبيقات بسيطة قائمة على المعايير لأداء مهام نطاق DOM الشائعة ومهام التحديد في جميع المتصفحات الرئيسية ، مما يؤدي إلى استبعاد التطبيقات المختلفة بشدة لهذه الوظيفة بين Internet Explorer حتى المتصفحات المتوافقة مع DOM. إنها التبعية الوحيدة للمشروع.

بمجرد تضمين Text Annotator ، يعد استخدامه عملاً بسيطًا للغاية:

 var annotator = new tvs.Annotator(); annotator.underlineSelected();

يتم تمييز كل عنصر توضيحي بفئة "tvs-annotated-text" وكل عنصر من عناصر التعليق يحتوي على فئة "tvs-annotate-element". تعد إزالة التعليقات التوضيحية أبسط من ذي قبل ، بحيث تتكون من سطر واحد:

 annotator.unannotateElement(annotatedElement);

المراوغات

عندما يتم تغيير حجم النافذة ، قد تتحرك العناصر ، مما يتطلب "تحديث" العناصر المشروحة. يتم التعامل مع هذا من قبل المكتبة. ومع ذلك؛ لتقليل التأثير على الأداء ، يتم تقييد الدعوة إلى تحديث التعليقات التوضيحية:

 tvs.AnnotatorImpl = function(id, templates, positioner, options) { // ... this.throttle = new goog.Throttle(goog.bind(this.refreshAllAnnotations, this), 50); tvs.AnnotatorCore.registerForWindowResize( this.id,goog.bind(this.throttle.fire, this.throttle)); }; tvs.AnnotatorImpl.prototype.refreshAllAnnotations = function() { var elems = goog.dom.getElementsByClass(this.getCssClassForAnnotated()); var refFunc = goog.bind(this.refreshAnnotation, this); goog.array.forEach(elems, refFunc); };

عند التحديث ، يمكن إضافة عناصر التعليق التوضيحي أو تغيير حجمها أو إزالتها من الصفحة كما هو مطلوب.

راحة

لتسهيل إضافة تعليق توضيحي على نص ثابت على الصفحة ، فإن كل ما تحتاج إليه هو سمة بيانات بسيطة في عنصر الحاوية:

 data-annotate='underline squiggly green'

سيؤدي هذا إلى وضع تعليق توضيحي على محتوى العنصر بتسطير أخضر متعرج.

خاتمة

ما الذي يمكنني قوله أكثر عن هذا البرنامج التعليمي النصي SVG؟ تم تنفيذ أداة ممتعة لكنها قوية بسهولة. لا أعتقد أننا سنستفيد كثيرًا من خلال ضمان دعم Internet Explorer 8 ، حيث قد ينتهي بنا الأمر بتعقيد عملية التنفيذ بأكملها. ومع ذلك ، مع بعض التحسينات والقليل من العمل على جوهرها ، يمكننا توسيع المكتبة لتكون قادرة على إنتاج حدود زخرفية للعناصر غير النصية. علاوة على ذلك ، قد يكون تنفيذ بعض الآليات للحفظ ثم استعادة حالة المحتوى القابل للتحرير للتعليق التوضيحي مهمة مثيرة للاهتمام.

بالنسبة إلى الآن ، فإن الاحتمالات محدودة فقط بخيالك (وقدرات المتصفح). ربما تريد خطوط الطباعة المصغرة ، أو التدرجات اللونية ، أو حتى الرسوم المتحركة. باستخدام Text Annotator ، يمكنك ذلك.