사례 연구 - HTML5 MathBoard

Jeremy Chone
Jeremy Chone

소개

MathBoard 애플리케이션

PalaSoftware 애플리케이션인 iPad용 MathBoard는 미묘하지만 자연스러운 애니메이션과 독특한 사실적인 디자인을 갖춘 매우 세련된 애플리케이션입니다. 목표는 iPad 애플리케이션을 HTML5로 가장 정확하게 포팅하는 것이었습니다.

N2N-Apps는 HTML5 기술로 차세대 웹 및 모바일 애플리케이션을 구축하는 데 중점을 둔 소프트웨어 개발 회사입니다. 이 회사는 Netscape, Oracle, Adobe에서 11년간 엔지니어링 및 관리 경험을 쌓은 후 양질의 웹 및 모바일 애플리케이션을 빌드하기 위해 비즈니스와 전문 지식을 공유하기로 결정한 제레미 촌에 의해 2010년에 설립되었습니다. N2N-Apps는 전송의 품질과 속도에 중점을 둡니다.

Chrome 웹 스토어용 MathBoard 다운로드 Chrome 웹 스토어용 MathBoard 다운로드 (무료 버전)

요구사항

이 HTML5 포팅 프로젝트의 주요 요구사항은 다음과 같습니다.

  1. 원래 iPad 애플리케이션의 디자인과 느낌, 사용자 인터페이스를 고화질로 포팅합니다.
  2. 타겟 폼 팩터 (예: 키보드/마우스가 있는 PC/Mac과 터치 스크린)에 맞게 조정합니다.
  3. 관련 기능을 100% 구현합니다.
  4. 주로 HTML5 브라우저를 타겟팅합니다.
  5. 애플리케이션이 클라이언트에서 완전히 실행되고 정적 서버 또는 Google Chrome 패키징된 애플리케이션에서 호스팅될 수 있도록 애플리케이션을 '서버리스'로 만듭니다.
  6. 한 달 이내에 문제 해결 도구를 제외한 모든 기능이 포함된 1.0 버전을 만듭니다.

아키텍처

아키텍처

요구사항에 따라 다음과 같은 아키텍처를 사용하기로 결정했습니다.

  1. HTML5: HTML4 지원 요구사항이 없으므로 HTML5를 기반으로 하기로 결정했습니다.
  2. jQuery: HTML5에는 jQuery를 훌륭하게 만드는 많은 고급 선택기가 있지만, jQuery는 DOM 및 관련 이벤트를 조작하는 매우 강력하고 성숙한 방법을 제공하므로 jQuery를 계속 사용하기로 결정했습니다. jQuery는 DOM 중심적이라는 이점도 있어 애플리케이션의 설계와 구현을 HTML에 더 가깝게 할 수 있습니다.
  3. SnowUI: jQuery는 DOM을 사용하는 데 유용한 API와 권장사항을 제공하지만, HTML5 MathBoard 애플리케이션의 경우 모든 다양한 뷰를 조정하는 MVC 또는 MVP 스타일 프레임워크가 필요했습니다. SnowUI는 jQuery를 기반으로 하는 간단하지만 강력한 MVC 프레임워크입니다. DOM 중심의 MVC 메커니즘과 맞춤 구성요소를 빌드하는 유연한 방법을 제공하면서 애플리케이션 개발자가 최적이라고 생각하는 위젯/컨트롤 라이브러리 또는 맞춤 코드를 사용할 수 있는 기회를 남겨 둡니다.

iPad에서 PC로의 전송 고려사항

PC용으로 애플리케이션을 HTML5로 포팅할 때 애플리케이션의 디자인과 사용자 상호작용을 여러 번 수정해야 했습니다.

화면 방향

iPad MathBoard는 세로 모드로만 사용할 수 있으며, PC 디스플레이는 일반적으로 가로 모드로 사용되므로 최적화되지 않았습니다. 이에 따라 UI 디자인을 재구성하고 설정 패널을 오른쪽의 슬라이딩 뷰 (CSS3 전환으로 애니메이션 처리됨)로 이동했습니다.

화면 방향
iPad 화면 방향과 HTML5 화면 방향 비교

입력: 키보드/마우스와 터치 비교

iPad 버전과 웹 버전의 또 다른 주요 차이점은 입력 인터페이스입니다. iPad에서는 터치 인터페이스만 사용할 수 있지만 PC에서는 마우스와 키보드 모두 고려해야 합니다.

iPad의 MathBoard 입력 컨트롤은 매우 세련되었습니다. 웹 인터페이스에서도 동일한 고화질 표현을 원했습니다. 해결 방법은 키보드 단축키 지원을 추가하고 CSS 위치 지정을 사용하여 UI 컨트롤을 복제하는 것이었습니다. HTML5로의 포팅은 픽셀이 정확했습니다.

UI 컨트롤
iPad 버전 설정과 HTML5 버전 설정 비교

iPad 인터페이스에서와 같이 사용자가 왼쪽 및 오른쪽 화살표를 클릭하여 컨트롤의 값을 변경할 수 있습니다. 세로선을 드래그하여 값을 빠르게 변경할 수도 있습니다. 사용자가 마우스나 키보드를 누르면 값 변경을 가속화할 수 있도록 clickkeydown에 반복 동작이 구현되었습니다.

한 입력란에서 다른 입력란으로 이동하는 TAB 지원이 추가되었으며 ← 및 → 화살표는 값을 순환합니다.

iPad 버전의 한 가지 기능은 PC 인터페이스에 적합하지 않은 그리기 보드였습니다. 구현하기는 좋았지만 마우스로 숫자를 그리기는 실용적이지 않습니다. 대신 그리기 보드를 구현하는 것보다 키보드 인터페이스를 다듬는 데 더 많은 시간을 할애하기로 결정했습니다.

HTML5 기능

MathBoard의 웹 버전에서는 다음과 같은 여러 HTML5 기능을 사용합니다.

로컬 저장소

MathBoard를 사용하면 사용자가 퀴즈를 저장하여 나중에 다시 재생할 수 있습니다. HTML5 MathBoard는 SnowUI DAO 인터페이스를 사용하여 HTML5 localStorage를 사용하여 이 기능을 구현합니다.

데이터가 충분히 간단하고 고급 색인이 필요하지 않았으므로 localStorage가 자연스러운 선택이었습니다. 모든 퀴즈는 텍스트로 JSON.stringify하는 하나의 JSON 형식으로 저장됩니다.

snowUI DAO는 UI가 데이터가 실제로 저장되는 방식에 관해 걱정하지 않고 데이터를 가져올 수 있는 간단한 CRUD 인터페이스 래퍼입니다. DAO 구현은 저장소 세부정보를 처리합니다.

MathBoard의 저장용량 요구사항은 매우 간단했습니다. 사용자 설정과 퀴즈 데이터만 저장하면 됩니다. 둘 다 localStorage에 JSON 문자열로 저장되었습니다.

예를 들어 설정 값의 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 글꼴 지원 덕분에 'Chalkduster' TrueType 글꼴을 애플리케이션에 포함하는 것은 간단했습니다.

@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 전환

HTML5 MathBoard의 경우 iPad의 모든 애니메이션을 복제하고 오른쪽 슬라이딩 패널용 애니메이션도 새로 추가했습니다. CSS3 전환 덕분에 애니메이션을 추가하는 것이 간단해졌으며 최고의 성능을 얻을 수 있었습니다.

애플리케이션에는 세 가지 주요 애니메이션이 있습니다.

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' 속성을 애니메이션 처리하는 것보다 성능이 우수합니다. 이는 특히 3D 변환이 하드웨어 가속되는 휴대기기 (예: iOS)에서 그렇습니다.
  3. 이 경우 원래 위치가 수정 전에 설정되었으므로 setTimeout는 엄격히 필요하지 않습니다. 하지만 이렇게 하면 브라우저가 rightPane을 밀어 넣기 직전에 퀴즈를 표시하여 애니메이션을 더 부드럽게 만들 수 있습니다.

2.) 설정 대화상자 애니메이션

사용자가 오른쪽의 설정을 클릭하면 설정 대화상자가 화면 하단에서 표시되고 적절한 섹션으로 아래로 스크롤됩니다.

이를 위해 오른쪽 창과 유사한 전환을 적용했습니다. 대화상자가 처음 표시될 때의 끊김 현상을 해결하는 데만 시간이 걸렸습니다. 브라우저에 대화상자 UI를 캐시하도록 안내하기 위해 대화상자를 한 번 표시하고 스크롤했습니다. 처음에는 display: none를 사용해 보았습니다. 브라우저가 대화상자를 표시할 필요가 없다고 가정했기 때문에 이 접근 방식은 잘못되었습니다. 해결 방법은 초기화 시 z-index: -1로 설정을 표시하여 사용자에게는 보이지 않지만 브라우저에는 표시되도록 하는 것이었습니다.

3.) 퀴즈 성공 또는 잘못된 메시지 애니메이션

세 번째 애니메이션은 실제로 두 가지로 구성되어 있습니다. '성공' 또는 '잘못됨' 메시지가 표시되면 먼저 한 지점으로 크기를 조정하고 잠시 기다린 후 마지막으로 더 크게 조정하고 사라집니다. 이를 위해 두 가지 CSS3 애니메이션 스타일을 사용하고 webkitTransitionEnd 이벤트에서 JavaScript를 통해 조정합니다.

.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는 iPad용 MathBoard의 고급 기능에 밀접하게 일치하도록 애플리케이션의 디자인과 느낌을 맞춤설정하는 데 중요한 역할을 했으며, HTML5 저장소는 데이터 지속성에 적합했으며, HTML5 오디오의 단순성 덕분에 iPad 앱을 거의 그대로 재현할 수 있었습니다.