
電脳麻将 のスマートフォン表示では、画面サイズに関わらず画面いっぱいに卓を表示していますが、それを実現しているのが関数 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 の意味になりました。
以下で実際の表示を確認できます(スマートフォンで確認してください)。