HTML5版のDxLibでアプリをブラウザに合わせたい時の処理


ブラウザ側の処理

ブラウザ側ではキャンバスの幅は”~vw”使えば勝手にやってくれる。

index.html

/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
      @media screen and (orientation: landscape) {
     /* 横向きの場合のスタイル */
     canvas.emscripten { height:66vh;border: 0px none; background-color: black; }
      }
      @media screen and (orientation: portrait) {
        /* 縦向きの場合のスタイル */
        canvas.emscripten { width:100vw;border: 0px none; background-color: black; }
      }

縦向きの場合は『width:100vw;』に好きな幅を書き込む。
間違っても3:2の比率にしたいからといって『height:66vw;』などと書き込まないように。
GetMousePoint関数の取得座Y座標がずれますorz
横向きの場合はデスクトップの場合が多いので、上下にバナーを出すために高さを中心に合わせた方が良い。よって。『height:66vh;』

<canvas class="emscripten" id="canvas" width="640px" height="480px" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>

ここのwidthとheightはDXライブラリのSetGraphMode()関数の引数で渡したサイズを書き込むこと。ここで幅と高さを指定しているお陰でcanvas.emscriptenのstyleが高さと幅のどちらかだけで済むようになっている。

C++側の処理

EM_JS関数を使用する。
これは、この範囲はJavaScriptで書き込むというマクロであり、当たり前だがこの範囲内ではC++の変数などの操作は出来ない。

// ウィンドウ幅を取得する関数(正確なマウス座標を取得するのに使用)
EM_JS(int, canvas_get_width, (), {
  return document.getElementById('canvas').clientWidth;
});

// キャンバスの高さを取得する関数(正確なマウス座標を取得するのに使用)
EM_JS(int, canvas_get_height, (), {
  return document.getElementById('canvas').clientHeight;
});

// 横向きかどうかを返す関数
EM_JS(int, landscape_flag, (), {
  if(document.body.clientWidth<document.body.clientHeight){return 0;}
  return 1;
});

たとえば、以下の記述はエラーになる。

int a=5;
EM_JS(int, canvas_get_width, (), {
  a=6;
  return a;
});

変数aはJavaScriptではないし、EM_JS内にCの変数を持ち込むことは出来ない。

正確なマウス座標を取得する

付け焼刃ではあるが以下のようなメソッドで問題ない。

        GetMousePoint(&MouseX, &MouseY);
        #ifdef EMSCRIPTEN
        float Rate = 640.0f / ((float)canvas_get_width());
        if(landscape_flag()==1)
        {
            Rate = 480.0f / ((float)canvas_get_height());
        }
        MouseX = (int)(((float)MouseX)*Rate);
        MouseY = (int)(((float)MouseY)*Rate);

        #endif
        DrawCircle(MouseX, MouseY, 64, CircleColor);


赤丸の中心にマウスポインタが来ていれば成功。
(これ見てる人はこんな付け焼刃のプログラムじゃなくて、GetMousePoint関数をoverride、しよう!)

最後に

WebアプリをC++で作れるのは最高!
次はFirebaseとの連携を試してみるつもりです。
Android版ではAndroidStudioを使ってFirestoreまで連携出来たので興味ある方がいればここに記事書きます。お気軽にコメントどうぞ。

更新履歴

2020.12/29。縦横比の変更に対応しました。

多謝

DxLibのHTML5版作成して下さったかめ様。
https://qiita.com/nokotan