私はこれがうまくいくと思います:
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 数学ライブラリを使用している場合は、射影行列と関数 (通常はperspective
fieidOfView、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 100vw
andの使用から切り替えました。100vw
前のソリューションではキャンバスをドキュメントのサイズにしてから、ドキュメントをウィンドウのサイズに強制しようとしました。ドキュメントのコンテンツがウィンドウよりも大きくなる可能性があるため、これは間違いなく間違ったソリューションでした。