Home

電脳麻将UI 〜 scale

スマートフォン用表示

電脳麻将 のスマートフォン表示では、画面サイズに関わらず画面いっぱいに卓を表示していますが、それを実現しているのが関数 scale() です。

スマートフォン用の表示では、卓は 800x450px の固定サイズで描画し、スマートフォン画面の縮尺をそれに合わせています。 まず、卓を画面の横幅いっぱいに表示するために、meta 要素の viewport で画面幅を指定します。


<meta name="viewport" content="width=800">

これでスマートフォンの場合、画面の幅いっぱいに卓を表示するようになります。 iPhone SE の画面サイズの場合、これで高さも画面いっぱいに表示されますが、現在のスマートフォンはこれより横長の画面のことが多いため、卓の高さが画面からはみ出すケースがほとんどでしょう。 その場合、CSSの transform の関数 scale() を使って卓の表示を縮小します。

例えば、ある要素に

  transform: scale(0.8);

と指定すれば、その要素を 80% に縮小します。 ただし、要素の中心を基準位置に縮小を行うため、上方に隙間が空いてしまいます。 これを transform の関数 translate() で補正します。 例えば高さ 450px の要素を80%の 360px に縮小した場合は、(450 - 360) / 2 = 45 px だけ上方に補正する必要があります。

  transform: translate(0px, -45px) scale(0.8);

これを実装しているのが、@kobalab/majiang-ui のクラス Majiang.UI.Util の関数 scale() です。

/*
 *  scale.js
 */
"use strict";

const $ = require('jquery');

function scale(board, space) {

    let dh = $('body').height();
    let bh = board.height();
    if (bh > dh) {
        let scale  = dh / bh;
        let margin = (dh - bh) / 2;
        board.css('transform', `translate(0px, ${margin}px) scale(${scale})`);
        $(window).scrollTop(space.height());
    }
    else {
        board.css('transform', '');
    }
}

module.exports = { scale: scale };

board は縮小する卓のDOMノードです。 画面の高さ dh と卓の高さ bh を比較し、bh > dh ならば縮小のためのCSSを卓のDOMノードに追加します。 space は卓の上方に配置する「スクロールのための余白」です。 初期状態では余白を隠すようにスクロールを試みますが、Chromeでは期待通りにスクロールされないようです。 実際にスマートフォンで操作してみるとわかりますが、この余白があるとサイズ調整がしやすくなります。

body 要素の高さを画面の高さとみなしていますが、それを可能にするためにはCSSに以下のような指定が必要です。

  @media screen and (max-height: 450px) {
    body {
      margin: 0;
      height: 100dvh;
    }
  }

画面の高さが卓の高さ(450px)以下のときに body 要素の height プロパティに 100dvh を指定しています。 dvh はアドレスバーを含むかあいまいだった従来の単位 vh を置き換える 新単位 です。 svh はアドレスバーが表示されているときの高さ、lvh はアドレスバーが表示されていないときの高さ、dvh はアドレスバーの表示/非表示を反映した現在の高さのようです。 従来の vh は lvh の意味になりました。

以下で実際の表示を確認できます(スマートフォンで確認してください)。