HSP3Dish.jsでフルスクリーン化(3)
目次
解像度を固定して拡大表示
前回は画面サイズいっぱいまで解像度を上げて表示しました。 この方法は、解像度が高い環境とそうでない環境では、表示結果が変わってしまいます。 高さが広いのか、幅が広いのか、両方広いのか、画面の縦横比はどう違うか…実行環境ごとに解像度が異なると動作検証作業が大変です。
そこで今回は解像度を固定して、画面に出来るだけ大きく表示されるようにしてみます。 つまり拡大表示です。開発時の解像度が固定なので、表示結果に悩むことなく開発に集中できますね。
サンプル
まずは実行結果から見てみます。今回のサンプルとhtmlです。 ウィンドウサイズが変更されるとHSP3Dishの描画領域も変化します。ウィンドウの縦横比を変えると、狭い方に合わせて表示領域を変更します。 スクリプトの動作解像度は変化させずに拡大するので、線の太さが太くなっていますね。文字は少しぼやけた感じです。スマホの場合は、画面の黒い部分をつかめばスクロールが可能です。
htmlはリンク先から参照してください。
HSP3Dishの描画先要素
まずはHSP3Dishの描画が何処に対して行われているかを確認してみます。
<div class="emscripten_border">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
</div>
id属性がcanvas
のcanvas要素がHSP3Dishの描画領域です。emscripten_border
クラスは、canvas要素を配置するなどの取り扱いを容易にするためのコンテナ要素です。
今回の修正ではcanvas要素を広げると、HSP3Dishの描画結果はcanvas要素に合わせて拡大して表示されます。
コンテナサイズを調整
今回の計画。コンテナをウィンドウサイズいっぱいまで広げて、canvasはコンテナに収まる最大まで縦横比を維持したまま広げる方法で実装してみます。
まずは、HSP3Dishの描画先要素が格納されているコンテナ(emscripten_borderクラスのdiv要素)をウィンドウサイズいっぱいまで広げます。
div.emscripten_border {
background-color: black;
/* 表示可能領域を全画面にする。 */
height: 100vh;
width: 100%;
/* 子要素を中央寄せ */
display: flex;
justify-content: center;
align-items: center;
}
出来るだけ広げたいので、border
は消しました。
height
は、ウィンドウサイズに合わせてビューポートのサイズを指定します。
width
は、100vw
を指定するとスクロールバーで隠れてしまうので100%
を指定します。
内側の子要素(HSP3Dishの描画先要素)は、中央に表示されるようにしています。
HSP3Dishの描画先要素のサイズを調整
canvas要素(HSP3Dishの描画先要素)のサイズをコンテナ要素内に収まるように拡大します。ただし、縦横比は維持したままとします。
#canvas {
object-fit: contain;
}
これで解決だな!と思ったんですが、mtinfo
命令での座標取得が正しく動かないようです。仕方がないので別の方法を考えてみます。
canvas.sm-width { /* コンテナが横に長い場合 */
height: 100%;
width: auto;
}
canvas.sm-height { /* コンテナが縦に長い場合 */
height: auto;
width: 100%;
}
コンテナ サイズの縦横比に合わせてスタイルを切り替える方法です。
100%
とauto
を使用します。コンテナ要素が縦に長い場合と、横に長い場合とで100%
にする方向を変えます。切替はJavaScriptで行います。
// 追加機能
// ウィンドウサイズが変更になった場合、HSP3Dishの描画領域を変更します。
// #canvasが、親のdiv要素に収まるように縦横比を調整して拡大します。
function resizeCanvas() {
const canvas = document.getElementById('canvas');
const container = canvas.parentElement;
const canvasAspectRatio = canvas.width / canvas.height;
const containerAspectRatio = container.clientWidth / container.clientHeight;
// canvas要素
// object-fit を使うと座標取得に不具合が起きるためここで対応しています。
canvas.classList.remove('sm-height', 'sm-width'); // クラスをリセット
if (containerAspectRatio > canvasAspectRatio) {
// 親要素の方が横に長い場合
canvas.classList.add('sm-width');
} else {
// 親要素の方が縦に長い場合
canvas.classList.add('sm-height');
}
}
resizeCanvas();
window.addEventListener('load', resizeCanvas);
window.addEventListener('resize', resizeCanvas);
イベントリスナーを置いて、ウィンドウサイズが変わったらcanvas要素のスタイルを変更をする関数が実行されます。
メリットとデメリット
この方法なら、作成した画面を出来るだけ大きく表示することができます。 解像度は固定で開発するので、環境が変わってもボタンや文字の配置は開発時と全く同じになります。 Windows向けに開発する場合と同じ感覚で作ればいいので、PC向けとしては一番作りやすい方法ではないかと思います。
一方で、小さいディスプレイだと全てが小さく表示されるので、文字が読みにくくなったり、ボタンが押しにくくなる等の問題があります。