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