دراسة حالة: تطبيق MathBoard المستند إلى HTML5

مقدمة

تطبيق MathBoard

MathBoard على جهاز iPad، هو تطبيق من PalaSoftware، ويمتاز بتصميم مُحسَّن للغاية يتضمّن العديد من الصور المتحركة الهادئة والطبيعية ومظهرًا وأسلوبًا واقعيَين فريدَين. كان الهدف هو نقل تطبيق iPad إلى HTML5 بدقة عالية.

‫N2N-Apps هي شركة تطوير برامج تركّز على إنشاء التطبيقات المتوافقة مع الجيل التالي من الويب والأجهزة الجوّالة باستخدام تكنولوجيا HTML5. تم تمويل الشركة في عام 2010 من قِبل "جيريمي تشون" الذي قرّر مشاركة خبرته مع الأنشطة التجارية لإنشاء تطبيقات عالية الجودة للويب والأجهزة الجوّالة بعد 11 عامًا من العمل في مجال الهندسة والإدارة في Netscape وOracle وAdobe. تركّز N2N-Apps على الجودة وسرعة التسليم.

تنزيل MathBoard من "سوق Chrome الإلكتروني" تنزيل MathBoard من "سوق Chrome الإلكتروني" (الإصدار المجاني)

المتطلبات

في ما يلي المتطلبات الرئيسية لمشروع نقل البيانات إلى HTML5:

  1. نسخة عالية الدقة من شكل تطبيق iPad الأصلي وأسلوبه وواجهة المستخدم
  2. التكيّف مع شكل الجهاز المستهدَف (مثل الكمبيوتر الشخصي/Mac المزوّد بلوحة مفاتيح/ماوس مقابل الشاشة التي تعمل باللمس)
  3. تنفيذ كل الميزات السارية
  4. استهدِف بشكل أساسي متصفّحات HTML5.
  5. اجعل التطبيق "غير مزوّد بخادم" حتى يتم تشغيله بالكامل على العميل ويمكن استضافته على خادم ثابت أو تطبيق مُحزم في Google Chrome.
  6. أنشئ إصدارًا 1.0 يتضمّن جميع الميزات باستثناء ميزة حلّ المشاكل في أقل من شهر.

الهندسة المعمارية

الهندسة المعمارية

استنادًا إلى المتطلبات، قرّرنا استخدام البنية التالية:

  1. HTML5: بما أنّنا لا نفرض أي متطلبات متوافقة مع HTML4، قرّرنا استخدام HTML5 كقاعدة.
  2. ‫jQuery: على الرغم من أنّ HTML5 تتضمّن العديد من المحدّدات المتقدّمة التي تجعل jQuery رائعًا، قرّرنا الاستمرار في استخدام jQuery على أي حال لأنّه يوفّر لنا طريقة قوية جدًا ومتقدّمة للتعامل مع DOM والأحداث ذات الصلة. يستفيد jQuery أيضًا من التركيز بشكل أكبر على DOM، ما يؤدي إلى جعل تصميم التطبيق وتنفيذه أقرب إلى HTML.
  3. SnowUI: يوفّر jQuery واجهة برمجة تطبيقات رائعة وأفضل الممارسات للعمل مع نموذج DOM، ومع ذلك، بالنسبة إلى تطبيق MathBoard المستنِد إلى HTML5، احتجنا إلى إطار عمل بأسلوب MVC أو MVP لتنسيق جميع طرق العرض المختلفة. ‫SnowUI هو إطار عمل MVC بسيط وفعّال يستند إلى jQuery. وتوفّر هذه البنية آلية MVC متمركزة حول نموذج DOM وطريقة مرنة لإنشاء مكوّنات مخصّصة مع منح مطوّر التطبيقات فرصة استخدام أي مكتبة تطبيقات مصغّرة/عناصر تحكّم أو رمز مخصّص يراه مناسبًا.

اعتبارات حول نقل البيانات من جهاز iPad إلى جهاز كمبيوتر شخصي

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

اتجاه الشاشة

لوحة MathBoard لأجهزة iPad مخصّصة للاستخدام في الوضع العمودي فقط، ما لم يكن مثاليًا لشاشات الكمبيوتر الشخصي لأنّها تُستخدَم بشكل عام في الوضع الأفقي. نتيجةً لذلك، أعدنا تنظيم تصميم واجهة المستخدم ونقلّنا لوحة الإعدادات إلى الجانب الأيمن، في عرض قابل للانزلاق (يتم تشغيله من خلال انتقالات CSS3).

اتجاه الشاشة
اتجاه شاشة iPad مقارنةً باتجاه شاشة HTML5

الإدخال: لوحة المفاتيح/الماوس مقابل اللمس

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

عناصر التحكّم في الإدخال في MathBoard على جهاز iPad مصقولة للغاية. أردنا أن نوفّر تمثيلاً مماثلاً عالي الدقة في واجهة الويب. كان الحلّ هو إضافة إمكانية استخدام اختصارات لوحة المفاتيح وتكرار عناصر التحكّم في واجهة المستخدم باستخدام موضع CSS. كان النقل إلى HTML5 دقيقًا على مستوى البكسل:

عناصر التحكّم في واجهة المستخدم
إعدادات إصدار HTML5 على أجهزة iPad مقارنةً بأجهزة Android

كما هو الحال في واجهة iPad، نسمح للمستخدم بالنقر على السهمين المتّجهَين لليسار واليمين لتغيير قيمة عنصر التحكّم. يمكن أيضًا سحب الخط العمودي ل تغيير القيم بسرعة. تم تنفيذ سلوك تكرار لكل من click وkeydown حتى يتمكّن المستخدمون من تسريع تغيير القيمة عند الضغط على الماوس أو لوحة المفاتيح.

تمت إضافة علامة التبويب للانتقال من حقل إدخال إلى آخر، وسهمَي الالتفاف ← و→ للتنقّل بين القيم.

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

ميزات HTML5

في إصدار الويب من MathBoard، نستخدم العديد من ميزات HTML5:

التخزين المحلي

تتيح MathBoard للمستخدمين حفظ اختباراتهم لإعادة تشغيلها لاحقًا. تنفِّذ HTML5 MathBoard هذه الميزة باستخدام HTML5 localStorage باستخدام واجهة SnowUI DAO.

كان localStorage خيارًا مناسبًا لأنّ البيانات كانت بسيطة بالقدر الكافي ولم تتطلّب فهرسة متقدّمة. نخزّن جميع الاختبارات بتنسيق JSON واحد JSON.stringify كنص.

‫snowUI DAO هو حزمة بسيطة لواجهة CRUD تسمح لواجهة المستخدم بجمع البيانات بدون القلق بشأن كيفية تخزينها. يهتم تنفيذ DAO بتفاصيل التخزين.

في MathBoard، كانت متطلبات التخزين بسيطة جدًا. كان علينا تخزين إعدادات المستخدم وبيانات الاختبار فقط. تم تخزين كليهما كسلسلتَي JSON في localStorage.

على سبيل المثال، كان DAO لقيمة الإعداد على النحو التالي:

snow.dm.registerDao('settingValue', (function() {

  var _settingValues = null;

  function SettingValueDao() {};

  // ------ DAO CRUD Interface ------ //
  // get
  SettingValueDao.prototype.get = function(objectType, id) {
    return $.extend({},getSettingValues()[id]);
  };

  // find, remove

  // save
  SettingValueDao.prototype.save = function(objectType, data) {
    var storeValue = getSettingValues('settingValue')[data.id];
    if (!storeValue) {
      storeValue = {};
      getSettingValues()[data.id] = storeValue;
    }

    $.extend(storeValue, data);
    saveSettingValues();
  };
  // ------ /DAO CRUD Interface ------ //

  function getSettingValues() {
    if (_settingValues == null) {
      var settingValuesString = localStorage.getItem('settingValues');
      if (settingValuesString) {
        _settingValues = JSON.parse(settingValuesString);
      } else{
        _settingValues = {};
      }
    }

    return _settingValues;
  }

  function saveSettingValues(){
    var settingValues = getSettingValues();
    if (settingValues != null) {
      localStorage.removeItem('settingValues');
      localStorage.setItem('settingValues', JSON.stringify(settingValues)); 
    }
  }

  return new SettingValueDao();
})());

بعد تسجيل DAO هذا في settingValue، يمكن لواجهة المستخدم إجراء الطلب التالي بدون القلق بشأن منطق المتجر:

var addition = snow.dm.get('settingValue', 'operator_addition');
addition.value = true; // to check the addition checkbox
snow.dm.save('settingValue', addition);

خطوط CSS3

يستخدم تطبيق MathBoard خطوطًا مخصّصة. بفضل إتاحة استخدام الخطوط في CSS3، كان من السهل تضمين خط True Type‏ "Chalkduster" في تطبيقنا:

@font-face {
  font-family: Chalkduster;
  src: url(Chalkduster.ttf);
}

وبما أنّ هذا الخط كان الخط التلقائي لكل النص تقريبًا في التطبيق، جعلناه الخط التلقائي للنص الرئيسي.

body {
  background: #333333;
  font-family: Chalkduster;
  color: #ffffff;
}

التدرّج والظل والزوايا المستديرة في CSS3

يتم إنشاء جميع أشكال التدرّج والظل والشفافية والزوايا المستديرة باستخدام CSS3. وقد ساعدنا ذلك كثيرًا مقارنةً بالطريقة التقليدية لإنشاء واجهات المستخدم باستخدام ملفات png.

استخدمنا أيضًا سمات CSS3 المتقدّمة لتخصيص مظهر شريط التمرير ومضمونه لجعله أكثر دقة (اطّلِع على http://webkit.org/blog/363/styling-scrollbars/ للاطّلاع على كيفية تصميم أشرطة التمرير في متصفّحات WebKit).

انتقالات CSS3

بالنسبة إلى تطبيق HTML5 MathBoard، كرّرنا جميع الصور المتحركة على جهاز iPad وأضافنا صورة جديدة للوحة اليمنى المنزلقة. بفضل عمليات النقل في CSS3، كان من السهل إضافة صور متحركة وتحقيق أفضل أداء.

لقد أدرجنا ثلاث صور متحركة رئيسية في التطبيقات.

1.) اللوحة اليمنى المنزلقة

يظهر التأثير المتحرك الأول في اللوحة اليمنى (#rightPane)، ويتم إغلاقه عندما يبدأ المستخدم اختبارًا جديدًا ويتم فتحه عندما ينهيه. لإنشاء هذا التأثير، استخدمنا انتقال CSS التالي وشغّلناه من خلال JavaScript. النمط التلقائي للوحة اليمنى مفتوح:

#rightPane {
  /* look and feel, and layout property */
  position: absolute;
  width: 370px;
  height: 598px;
  top: 28px;
  left: 720px; /* open */
  -webkit-transition: all .6s ease-in-out;
}

عندما يبدأ المستخدم اختبارًا، ينقل منطق JavaScript اللوحة:

var $rightPane = $('#rightPane');
var left = $rightPane.position().left - 400;
setTimeout(function() {
  $rightPane.css('left', left + 'px');
}, 0);

في ما يلي بعض الملاحظات حول عملية التنفيذ هذه:

  1. بما أنّ أحجام التطبيقات ثابتة، كان بإمكاننا استخدام فئة CSS ‎.close وتحديد موضع الإغلاق بشكل ثابت بالطريقة نفسها التي نحدّد بها موضع الفتح بشكل ثابت.
  2. كان بإمكاننا أيضًا استخدام CSS "translate"، الذي كان سيؤدي إلى تحسين الأداء أكثر من إضافة رسوم متحركة إلى سمة "left" للوحة. وينطبق ذلك بشكل خاص على الأجهزة الجوّالة (مثل أجهزة iOS) التي يتم فيها تسريع عمليات التحويل الثلاثية الأبعاد باستخدام الأجهزة.
  3. ليس من الضروري استخدام setTimeout في هذه الحالة لأنّه سبق ضبط القيمة الأصلية لملفه الشخصي. ومع ذلك، يسمح ذلك للمتصفح بجعل الرسوم المتحركة أكثر سلاسة من خلال عرض الاختبار قبل تحريك اللوحة اليمنى.

2- الصورة المتحركة لمربّع حوار الإعدادات

عندما ينقر المستخدم على أحد الإعدادات على يسار الشاشة، يظهر مربّع حوار الإعدادات من أسفل الشاشة وينتقل للأسفل إلى القسم المناسب.

ولإجراء ذلك، أجرينا عملية انتقال مماثلة إلى اللوحة اليمنى. إنّ الأمر الوحيد الذي استغرق بعض الوقت هو حلّ مشكلة الارتباك عند ظهور مربّع الحوار لأول مرة. لتوجيه المتصفّح إلى تخزين واجهة مستخدم مربّع الحوار في ذاكرة التخزين المؤقت، انتهينا من عرضه مرة واحدة والانتقال إليه. في البداية، حاولنا استخدام display: none. كان هذا النهج خاطئًا لأنّ المتصفّح افترض أنّه ليس من الضروري عرض مربّع الحوار. كان الحلّ هو عرض الإعدادات باستخدام z-index: -1 عند الإعداد، ما يجعلها غير مرئية للمستخدم ولكن مرئية للمتصفّح.

3- رسالة متحركة غير صحيحة أو نجاح الاختبار

الصورة المتحركة الثالثة هي في الواقع صورتان في صورة واحدة. عندما تظهر رسالة "نجاح" أو "غير صحيح"، يظهر الرمز أولاً بحجم صغير، ثم يكبر تدريجيًا، وأخيرًا يختفي. لهذا الغرض، لدينا نمطان للرسوم المتحركة في CSS3، وننسّقهما من خلال JavaScript في حدث webkitTransitionEnd.

.quiz-result > div.anim1 {
  opacity: 0.8;
  -webkit-transform: scale(6,6);
}
.quiz-result > div.anim2{
  opacity: 0;
  -webkit-transform: scale(9,9);
}
setTimeout(function() {
  $msg.addClass("anim1");
  $msg.bind("webkitTransitionEnd", function(){
    if ($msg.hasClass("anim1")) {
      setTimeout(function() {
        $msg.removeClass("anim1");
        $msg.addClass("anim2");
      }, 300);
    } else {
      $msg.remove();
      displayNextItem();
      freezeInput = false;
    }
  });
}, 0);

علامة صوتية

عندما يجيب المستخدمون عن سؤال في الاختبار، يصدر التطبيق صوتًا يشير إلى نجاح الإجابة أو فشلها. كان الخيار البسيط هو استخدام علامة الصوت والاتصال play() بها. تتم إضافة هذه المقاطع الصوتية إلى الصفحة الرئيسية للتطبيق:

<audio id="audioCorrect" src="correct.mp3" preload="auto" autobuffer></audio>
<audio id="audioWrong" src="wrong.mp3" preload="auto" autobuffer></audio>

الخاتمة

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