11

WebGL アプリのビューポートとキャンバスをブラウザー ウィンドウのサイズ変更 (F11 ボタンを含む) に反応させたい。つまり、キャンバスの幅と高さを常に 100% にし、ビューポートのサイズと縦横比を適切にする必要があります。前者は簡単に達成できます:

<canvas style="width: 100%; height:100%;">

それが正しいかどうかはわかりませんが。後者は、ここで見つけた情報を使用して達成しようとしていました: Webgl gl.viewport changeですが、明らかに何か間違っています。私は気づいています:

canvas.onresize = resizeViewport;

キャンバスのサイズはあまり頻繁に変更されないため (常に 100% の幅と高さです)、間違っていますが、どうすればよいかわかりません。

アプリのオンライン バージョンは次のとおりです: http://nps.netarteria.pl/gallery .

4

1 に答える 1

13

私はこれがうまくいくと思います:

var canvas;
var gl;

function render() {
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
    
  // Draw a 1 pixel border around the edge using 
  // the scissor test since it's easier than setting up
  // a lot of stuff
  gl.clearColor(1, 0, 0, 1);  // red
  gl.disable(gl.SCISSOR_TEST);
  gl.clear(gl.COLOR_BUFFER_BIT);
    
  gl.enable(gl.SCISSOR_TEST);
  gl.scissor(1, 1, gl.canvas.width - 2, gl.canvas.height - 2);
  gl.clearColor(0, 0, 1, 1);  // blue
  gl.clear(gl.COLOR_BUFFER_BIT);
};

function resizeCanvas() {
  var width = canvas.clientWidth;
  var height = canvas.clientHeight;
  if (canvas.width != width ||
      canvas.height != height) {
    canvas.width = width;
    canvas.height = height;
          
    // in this case just render when the window is resized.
    render();
  }
}

function main() {
  canvas = document.getElementById("c");
  gl = canvas.getContext("webgl");
  resizeCanvas();
}

window.addEventListener('resize', resizeCanvas);
main();
body { 
  margin: 0;
}
#c {
  width: 100vw;
  height: 100vh;
  display: block;
}
<canvas id="c"></canvas>

私の知る限り、サイズ変更はウィンドウでのみ機能します。残念ながら、HTML5 仕様では、他の要素にサイズ変更イベントが追加されていません。

注: 常にレンダリングしている場合 (たとえばゲームなど)、サイズ変更イベントをリッスンする必要はありません。レンダリング ループの先頭で resizeCanvas を呼び出すだけです。ブラウザーがキャンバスのサイズを変更した場合、そのコンテナーに関係なく、コードはサイズが一致しなくなったことを確認し、キャンバスの描画バッファーのサイズを更新します。

キャンバスをレンダリングするための適切なビューポート サイズは、ほとんどの場合次のとおりです。

// Set the viewport to be the size of the canvas's drawingBuffer.

gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

一方、一般的な 3D 数学ライブラリを使用している場合は、射影行列と関数 (通常はperspectivefieidOfView、aspect、zNear、および zFar パラメーターを受け取る) も使用されます。ほぼすべての WebGL プログラムの正しい側面は次​​のとおりです。

// Set the aspect of our perspective matrix to match the size
// the canvas is displayed at.

var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight
???.perspective(fieldOfView, aspect, zNear, zFar);

アップデート

clientWidth と clientHeight をキャッシュする必要があるようです。その理由は、設定canvas.widthによって変更可能な CSS レイアウトが変更されるためです。clientHeight

上記のコードを更新しました。

Update2

これらは間違いなくより正しいため、100%to 100vwandの使用から切り替えました。100vw前のソリューションではキャンバスをドキュメントのサイズにしてから、ドキュメントをウィンドウのサイズに強制しようとしました。ドキュメントのコンテンツがウィンドウよりも大きくなる可能性があるため、これは間違いなく間違ったソリューションでした。

于 2012-12-14T07:02:03.080 に答える