【ドット絵エディタ制作】17回目:スマホ用レイアウト

イシュー「スマホ向けのレイアウト対応 」への対応。

作ったもの

スマホは表示領域が限られているので、
基本機能以外は必要に応じて表示するようにした。

個人的には、タブにお絵かきのプレビューを載せているところが一番気に入っている。

確認用ページ

ソースコード

クラス図

またレイアウトをリセットしてしまったので、改めて並びを整理した。

今回は、追加・改修したクラスが多岐に渡ったので、
それらを列挙するのはやめておく。

つまづきポイント

HTMLソースをPC用とスマホ用に分けた

PCもスマホも同一HTMLを利用するレスポンシブで作るのが理想だったが、
スマホ用ではUIを大幅に変えたかったので、
HTMLを分けることにした。

分け方としては、一つのPHPファイルにPC用のHTMLとスマホ用のHTMLを書いておき、
アクセスしたデバイスのユーザーエージェントによって、
出力するHTMLを変更するようにした。

一方、Typescript側はPCとスマホのソースを完全に分けてしまうと
二重管理となってしまい、後々つらくなりそうなので分けないことにした。
PCとスマホで実装を変える必要がある場合は
Typescript内で処理を分岐させている。

なお、Typescript側でPCとスマホの判定基準は持たず、
PHPによって出力されているHTMLソースの内容によって
処理を分岐している。

アプリっぽくするための工夫

スマホ用レイアウトを作成するにあたり、
アプリっぽくしたかったので、
アプリっぽくないブラウザの処理やUIを排除してみた。

ページを拡大させない

iPhoneのSafariに対応させるにはJavascriptで設定するしかないらしい。

ピンチイン対策
document.documentElement.addEventListener('touchstart', (e:TouchEvent)=>{
  if (e.touches.length >= 2){
    e.preventDefault();
  }
}, {
  passive: false
});
ダブルタップによる拡大対策

let t:number = 0;
document.documentElement.addEventListener('touchend',(e:TouchEvent)=>{
  let now:number = new Date().getTime();
  if ((now - t) < 350){
    e.preventDefault();
  }
  t = now;
}, false);

参考:iPhoneのSafariでページを拡大縮小させない方法

ブラウザのアドレスバーを非表示にする

以下のタグをHTMLのheadタグ内に書き込んでおく。

<!-- iOS用 -->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- Android用 -->
<meta name="mobile-web-app-capable" content="yes">

その上で、このページへのショートカットをホーム画面に追加し、
そのショートカットを利用して対象ページを表示すると
アドレスバーが表示されない。

参考:【Android/iOS】Webブラウザのアドレスバーを非表示にする方法

iPhoneでポートレートモードに固定するのは無理

ランドスケープモード(横向き)のレイアウトを考えるのが面倒だったので、
ポートレートモード(縦向き)のみにしたかったが、
iPhoneではこれができないらしい。

苦肉の策として、
ランドスケープモードになったときに、
画面を縦向きに促すイラストのみを表示し
お絵かきに関する操作が一切できないようにした。

favicon

ファビコンはfavicon generatorを利用した。
必要なデータやサイトに設置するためのHTMLソースコードまで出力してくれるので便利。

参考:様々なファビコンを一括生成。favicon generator

CSSアニメーションでdisplay:noneが効かない

要素を徐々に透明していき、完全に透明になったらdisplay:none;にする
CSSアニメーションを作りたかったが無理らしい。

そこで、
以下のようなCSSアニメーションを実施し、
durationに指定した0.3s後にJavascriptでdisplay:none;にした。

@keyframes fadeout {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
.hide{
  animation-name: fadeout;
  animation-duration: 0.3s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}

かなり気持ち悪いが、現状ではこれしかなさそう。

ひとこと

スマホ用に独自のUIを用意した箇所以外は
ほとんどPCの実装のままで済んだので
Typescriptで行う作業はそれほど多くなかったように思う。

一方で、スマホレイアウト用のCSSはほぼ0から書いたようなもんなので
そちらに時間がかかってしまった。