กรณีศึกษา - MathBoard ของ HTML5

บทนำ

แอปพลิเคชัน MathBoard

MathBoard ใน iPad ซึ่งเป็นแอปพลิเคชันของ PalaSoftware เป็นแอปพลิเคชันที่ผ่านการขัดเกลามาอย่างดี โดยมีภาพเคลื่อนไหวที่ละเอียดแต่ดูเป็นธรรมชาติ รวมถึงรูปลักษณ์และความรู้สึกที่สมจริงไม่เหมือนใคร โดยมีเป้าหมายเพื่อพอร์ตแอปพลิเคชัน iPad ไปยัง HTML5 ที่ตรงที่สุด

N2N-Apps เป็นบริษัทพัฒนาซอฟต์แวร์ที่มุ่งเน้นการสร้างเว็บแอปพลิเคชันและแอปพลิเคชันบนอุปกรณ์เคลื่อนที่รุ่นถัดไปด้วยเทคโนโลยี HTML5 บริษัทได้รับเงินทุนในปี 2010 จาก Jeremy Chone ซึ่งหลังจากมีประสบการณ์ด้านวิศวกรรมและการจัดการ 11 ปีจาก Netscape, Oracle และ Adobe ก็ได้ตัดสินใจแชร์ความเชี่ยวชาญกับธุรกิจต่างๆ เพื่อสร้างแอปพลิเคชันบนเว็บและอุปกรณ์เคลื่อนที่ที่มีคุณภาพสูง N2N-Apps มุ่งเน้นที่คุณภาพและความเร็วในการนำส่ง

ดาวน์โหลด MathBoard สำหรับ Chrome เว็บสโตร์ ดาวน์โหลด MathBoard สำหรับ Chrome เว็บสโตร์ (เวอร์ชันฟรี)

ข้อกำหนด

ข้อกำหนดหลักสำหรับโปรเจ็กต์การพอร์ต HTML5 นี้ ได้แก่

  1. พอร์ตที่ตรงตามต้นฉบับของรูปลักษณ์และอินเทอร์เฟซผู้ใช้ของแอปพลิเคชัน iPad เวอร์ชันแรก
  2. ปรับให้เข้ากับรูปแบบของอุปกรณ์เป้าหมาย (เช่น PC/Mac ที่มีแป้นพิมพ์/เมาส์เทียบกับหน้าจอสัมผัส)
  3. ใช้ฟีเจอร์ที่เกี่ยวข้อง 100%
  4. กําหนดเป้าหมายเบราว์เซอร์ HTML5 เป็นหลัก
  5. ทําให้แอปพลิเคชัน "ไม่ต้องใช้เซิร์ฟเวอร์" เพื่อให้แอปพลิเคชันทํางานบนไคลเอ็นต์ทั้งหมดและสามารถโฮสต์บนเซิร์ฟเวอร์แบบคงที่หรือแอปพลิเคชันแพ็กเกจของ Google Chrome
  6. สร้างเวอร์ชัน 1.0 ที่มีฟีเจอร์ทั้งหมดยกเว้นเครื่องมือแก้ปัญหาภายในเวลาไม่ถึง 1 เดือน

สถาปัตยกรรม

สถาปัตยกรรม

จากข้อกำหนดดังกล่าว เราจึงตัดสินใจใช้สถาปัตยกรรมต่อไปนี้

  1. HTML5: เนื่องจากเราไม่มีข้อกำหนดในการรองรับ HTML4 เราจึงตัดสินใจใช้ HTML5 เป็นพื้นฐาน
  2. jQuery: แม้ว่า HTML5 จะมีตัวเลือกขั้นสูงมากมายที่ทำให้ jQuery ยอดเยี่ยม แต่เราก็ตัดสินใจที่จะใช้ jQuery ต่อไปเนื่องจากเป็นวิธีที่มีประสิทธิภาพและสมบูรณ์แบบมากในการจัดการ DOM และเหตุการณ์ที่เกี่ยวข้อง นอกจากนี้ jQuery ยังมีข้อดีตรงที่เน้น DOM มากกว่า ซึ่งทำให้การออกแบบและการใช้งานแอปพลิเคชันใกล้เคียงกับ HTML มากขึ้น
  3. SnowUI: jQuery มี API ที่ยอดเยี่ยมและแนวทางปฏิบัติแนะนำสำหรับการใช้งาน DOM แต่สำหรับแอปพลิเคชัน MathBoard ที่ใช้ HTML5 เราต้องใช้เฟรมเวิร์กสไตล์ MVC หรือ MVP เพื่อจัดระเบียบมุมมองต่างๆ ทั้งหมด SnowUI เป็นเฟรมเวิร์ก MVC ที่เรียบง่ายแต่มีประสิทธิภาพซึ่งทำงานร่วมกับ jQuery แพลตฟอร์มนี้มาพร้อมกลไก MVC ที่เน้น DOM และวิธีที่ยืดหยุ่นในการสร้างคอมโพเนนต์ที่กําหนดเอง ขณะเดียวกันก็เปิดโอกาสให้นักพัฒนาแอปพลิเคชันใช้ไลบรารีวิดเจ็ต/ตัวควบคุม หรือโค้ดที่กําหนดเองตามที่เห็นว่าเหมาะสม

ข้อควรพิจารณาในการโอนจาก iPad ไปยัง PC

เมื่อพอร์ตแอปพลิเคชันเป็น HTML5 สำหรับการใช้งานบน PC เราต้องทำการเปลี่ยนแปลงหลายอย่างกับการออกแบบและการโต้ตอบของผู้ใช้กับแอปพลิเคชัน

การวางแนวหน้าจอ

MathBoard ของ iPad เป็นแบบแนวตั้งเท่านั้น ซึ่งไม่เหมาะกับจอแสดงผลของ PC เนื่องจากโดยทั่วไปจะใช้ในแนวนอน ด้วยเหตุนี้ เราจึงจัดระเบียบการออกแบบ UI ใหม่และย้ายแผงการตั้งค่าไปทางด้านขวาในมุมมองแบบเลื่อน (ภาพเคลื่อนไหวโดยการเปลี่ยน CSS3)

การวางแนวหน้าจอ
การวางแนวหน้าจอของ iPad เทียบกับ HTML5

อินพุต: แป้นพิมพ์/เมาส์ เทียบกับการสัมผัส

ความแตกต่างที่สำคัญอีกอย่างหนึ่งระหว่างเวอร์ชัน iPad กับเวอร์ชันเว็บคืออินเทอร์เฟซการป้อนข้อมูล ใน iPad คุณมีเพียงอินเทอร์เฟซแบบสัมผัส ส่วนใน PC คุณต้องใช้ทั้งเมาส์และแป้นพิมพ์

การควบคุมการป้อนข้อมูล MathBoard ใน iPad ได้รับการขัดเกลามาอย่างดี เราต้องการการแสดงผลที่มีคุณภาพสูงแบบเดียวกันในอินเทอร์เฟซเว็บ ทางออกคือการเพิ่มการรองรับแป้นพิมพ์ลัดและการจำลองการควบคุม UI โดยใช้การจัดตำแหน่ง CSS การพอร์ตเป็น HTML5 นั้นสมบูรณ์แบบทุกพิกเซล

การควบคุม UI
การตั้งค่าเวอร์ชัน iPad กับ HTML5

เราอนุญาตให้ผู้ใช้คลิกลูกศรซ้ายและขวาเพื่อเปลี่ยนค่าของการควบคุมได้เช่นเดียวกับในอินเทอร์เฟซ iPad นอกจากนี้ คุณยังลากเส้นแนวตั้งเพื่อเปลี่ยนค่าได้อย่างรวดเร็ว มีการใช้ลักษณะการทำงานซ้ำสำหรับ click และ keydown เพื่อให้ผู้ใช้เร่งการเปลี่ยนแปลงค่าได้เมื่อกดเมาส์หรือแป้นพิมพ์

เพิ่มการรองรับแป้น TAB เพื่อเลื่อนจากช่องป้อนข้อมูลหนึ่งไปยังอีกช่องหนึ่ง และแป้นลูกศร ← และ → จะวนดูค่าต่างๆ

ฟีเจอร์หนึ่งที่ไม่เหมาะกับอินเทอร์เฟซของ PC ในเวอร์ชัน iPad คือกระดานวาดภาพ แม้ว่าการใช้แป้นพิมพ์ลัดจะดูเก๋ไก๋ แต่การวาดตัวเลขด้วยเมาส์นั้นไม่ค่อยสะดวกนัก แต่เราตัดสินใจที่จะใช้เวลาขัดเกลาอินเทอร์เฟซแป้นพิมพ์มากกว่าการใช้กระดานวาดภาพ

ฟีเจอร์ HTML5

ใน MathBoard เวอร์ชันเว็บ เราใช้ฟีเจอร์ HTML5 หลายอย่าง ดังนี้

พื้นที่เก็บข้อมูลในเครื่อง

MathBoard ช่วยให้ผู้ใช้บันทึกแบบทดสอบเพื่อเล่นซ้ำในภายหลังได้ MathBoard ของ HTML5 ใช้ฟีเจอร์นี้โดยใช้ HTML5 localStorage โดยใช้อินเทอร์เฟซ SnowUI DAO

localStorage เป็นตัวเลือกที่เหมาะสมเนื่องจากข้อมูลนั้นเรียบง่ายพอและไม่จําเป็นต้องจัดทําดัชนีขั้นสูง เราจัดเก็บแบบทดสอบทั้งหมดในรูปแบบ JSON รูปแบบเดียวที่เราJSON.stringifyเป็นข้อความ

snowUI DAO เป็น Wrapper อินเทอร์เฟซ CRUD ที่เรียบง่าย ซึ่งช่วยให้ UI ดึงข้อมูลได้โดยไม่ต้องกังวลว่าจะจัดเก็บข้อมูลอย่างไร การติดตั้งใช้งาน DAO จะจัดการรายละเอียดพื้นที่เก็บข้อมูล

ใน MathBoard ข้อกำหนดด้านพื้นที่เก็บข้อมูลนั้นง่ายมาก เราจำเป็นต้องจัดเก็บเฉพาะการตั้งค่าผู้ใช้และข้อมูลแบบทดสอบ โดยจัดเก็บทั้ง 2 รายการเป็นสตริง 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 แล้ว UI จะเรียกใช้การเรียกต่อไปนี้ได้โดยไม่ต้องกังวลเกี่ยวกับตรรกะร้านค้า

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 Font "Chalkduster" ลงในแอปพลิเคชันได้อย่างง่ายดาย

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

และเนื่องจากแบบอักษรนี้เป็นแบบอักษรเริ่มต้นสำหรับข้อความเกือบทั้งหมดในแอปพลิเคชัน เราจึงกำหนดให้แบบอักษรนี้เป็นแบบอักษรเริ่มต้นสำหรับเนื้อหา

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

ไล่ระดับสี เงา มุมโค้งมน CSS3

ไล่ระดับสี เงา ความโปร่งใส และมุมมนทั้งหมดทำด้วย CSS3 วิธีนี้ช่วยประหยัดเวลาได้มากเมื่อเทียบกับการใช้ไฟล์ .png แบบดั้งเดิมในการสร้างอินเทอร์เฟซผู้ใช้

นอกจากนี้ เรายังใช้พร็อพเพอร์ตี้ CSS3 ขั้นสูงเพื่อปรับแต่งรูปลักษณ์ของแถบเลื่อนให้ดูกลมกลืนมากขึ้น (ดูการจัดสไตล์แถบเลื่อนในเบราว์เซอร์ WebKit ได้ที่ http://webkit.org/blog/363/styling-scrollbars/)

การเปลี่ยน CSS3

สำหรับ MathBoard เวอร์ชัน HTML5 เราได้จำลองภาพเคลื่อนไหวทั้งหมดของ iPad และเพิ่มภาพเคลื่อนไหวใหม่สำหรับแผงด้านขวาแบบเลื่อน การเปลี่ยน CSS3 ช่วยให้เราเพิ่มภาพเคลื่อนไหวได้อย่างง่ายดายและมีประสิทธิภาพสูงสุด

เรามีภาพเคลื่อนไหวหลัก 3 รายการในแอปพลิเคชัน

1.) แผงด้านขวาแบบเลื่อน

ภาพเคลื่อนไหวแรกอยู่ในแผงด้านขวา (#rightPane) ซึ่งจะเลื่อนปิดเมื่อผู้ใช้เริ่มแบบทดสอบใหม่ และเลื่อนเปิดเมื่อผู้ใช้จบแบบทดสอบ ในการสร้างเอฟเฟกต์นี้ เราใช้การเปลี่ยน CSS ต่อไปนี้และเรียกใช้ผ่าน JavaScript สไตล์เริ่มต้นของ rightPane เปิดอยู่

#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 มิติได้รับการเร่งด้วยฮาร์ดแวร์
  3. ในกรณีนี้ setTimeout ไม่จำเป็นต้องมีก็ได้เนื่องจากมีการตั้งค่าตำแหน่งเดิมไว้ก่อนการแก้ไข อย่างไรก็ตาม วิธีนี้ช่วยให้เบราว์เซอร์แสดงภาพเคลื่อนไหวได้ราบรื่นขึ้นด้วยการแสดงแบบทดสอบก่อนเลื่อนแผงด้านขวาเข้ามา

2.) ภาพเคลื่อนไหวของกล่องโต้ตอบการตั้งค่า

เมื่อผู้ใช้คลิกการตั้งค่าทางด้านขวา กล่องโต้ตอบการตั้งค่าจะปรากฏขึ้นจากด้านล่างของหน้าจอและเลื่อนลงไปที่ส่วนที่เหมาะสม

เราจึงมีการเปลี่ยนแปลงที่คล้ายกันกับบานหน้าต่างด้านขวา สิ่งเดียวที่ใช้เวลานานคือแก้ปัญหาความกระตุกเมื่อกล่องโต้ตอบปรากฏขึ้นเป็นครั้งแรก ในการสั่งให้เบราว์เซอร์แคช UI ของกล่องโต้ตอบ เราจึงแสดง UI นั้นเพียงครั้งเดียวและเลื่อนไปที่ UI ตอนแรกเราลองใช้ display: none แนวทางนี้ไม่ถูกต้องเนื่องจากเบราว์เซอร์จะถือว่าไม่จำเป็นต้องแสดงกล่องโต้ตอบ ทางออกคือแสดงการตั้งค่าด้วย z-index: -1 ในการเริ่มต้น ทำให้ผู้ใช้มองไม่เห็นการตั้งค่า แต่เบราว์เซอร์มองเห็น

3.) ภาพเคลื่อนไหวของข้อความ "ทำแบบทดสอบสำเร็จ" หรือ "ไม่สำเร็จ" ไม่ถูกต้อง

ภาพเคลื่อนไหวที่ 3 นั้นจริงๆ แล้วเป็นภาพเคลื่อนไหว 2 แบบในภาพเดียว เมื่อข้อความ "สำเร็จ" หรือ "ไม่ถูกต้อง" ปรากฏขึ้น ให้ปรับขนาดเป็นจุดแรก รอสักครู่ และสุดท้ายให้ปรับขนาดให้ใหญ่ขึ้นและหายไป เรามีภาพเคลื่อนไหว CSS3 2 สไตล์สำหรับการดำเนินการนี้ และควบคุมผ่าน 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 ได้อย่างใกล้เคียง