ビューポートの幅と高さの100%を占めるキャンバス要素を作成しようとしています。
私の例では、これが発生していることがわかりますが、 ChromeとFireFoxの両方にスクロールバーが追加されています。余分なスクロールバーを防ぎ、ウィンドウの幅と高さをキャンバスのサイズに正確に指定するにはどうすればよいですか?
window.innerHeight
キャンバスを常にフルスクリーンの幅と高さにするには、ブラウザのサイズが変更された場合でも、キャンバスのサイズをおよびに変更する関数内で描画ループを実行する必要がありますwindow.innerWidth
。
例: http://jsfiddle.net/jaredwilli/qFuDr/
<canvas id="canvas"></canvas>
(function() {
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
// resize the canvas to fill browser window dynamically
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
/**
* Your drawings need to be inside this function otherwise they will be reset when
* you resize the browser window and the canvas goes will be cleared.
*/
drawStuff();
}
resizeCanvas();
function drawStuff() {
// do your drawing stuff here
}
})();
* { margin:0; padding:0; } /* to remove the top and left whitespace */
html, body { width:100%; height:100%; } /* just to be sure these are full screen*/
canvas { display:block; } /* To remove the scrollbars */
これが、キャンバスをブラウザーの幅と高さ全体に適切に作成する方法です。関数内のキャンバスに描画するためのすべてのコードを配置するだけですdrawStuff()
。
ウィンドウのサイズ変更時にキャンバスのサイズを動的に調整する方法について、より一般的な質問に答えます。受け入れられた回答は、幅と高さが両方とも 100% であると想定されている場合を適切に処理します。これは要求されたものですが、キャンバスのアスペクト比も変更されます。多くのユーザーは、ウィンドウのサイズ変更時にキャンバスのサイズを変更することを望んでいますが、アスペクト比はそのままにします。それは正確な質問ではありませんが、質問をもう少し一般的な文脈に入れるだけで「収まります」。
ウィンドウには縦横比 (幅/高さ) があり、キャンバス オブジェクトも同様です。これら 2 つの縦横比を相互にどのように関連させたいかは、明確にする必要がある 1 つのことです。その質問に対する「1 つのサイズですべてに適合する」という答えはありません。欲しいです。
明確にする必要がある最も重要なことは、html キャンバス オブジェクトには width 属性と height 属性があることです。次に、同じオブジェクトの css にも幅と高さの属性があります。これらの 2 つの幅と高さは異なり、どちらも別の用途に役立ちます。
幅と高さの属性を変更することは、いつでもキャンバスのサイズを変更できる方法の 1 つですが、すべてを再描画する必要があります。これには時間がかかり、常に必要というわけではありません。ある程度のサイズ変更を達成できるためです。 css 属性を介して。この場合、キャンバスを再描画しません。
ウィンドウのサイズ変更で発生する可能性のある4つのケースがあります(すべてフルスクリーンのキャンバスから始まります)
1: 幅を 100% のままにし、縦横比をそのままにします。その場合、キャンバスを再描画する必要はありません。ウィンドウのサイズ変更ハンドラーさえ必要ありません。あなたに必要なのは
$(ctx.canvas).css("width", "100%");
ctx はキャンバス コンテキストです。フィドル: resizeByWidth
2: 幅と高さの両方を 100% のままにし、結果として縦横比を変更して、引き伸ばされた画像の効果を持たせたい。キャンバスを再描画する必要はありませんが、ウィンドウのサイズ変更ハンドラーが必要です。ハンドラーでは、
$(ctx.canvas).css("height", window.innerHeight);
フィドル:messWithAspectratio
3: 幅と高さの両方を 100% のままにしたいのですが、縦横比の変更に対する答えは、画像を引き伸ばすこととは別のものです。次に、再描画する必要があり、受け入れられた回答で概説されている方法でそれを行います。
フィドル:再描画
4: ページの読み込み時に幅と高さを 100% にしたいが、その後は一定のままにする (ウィンドウのサイズ変更には反応しません。
フィドル:修正
モードが設定されている 63 行目を除いて、すべてのフィドルのコードは同じです。フィドル コードをコピーしてローカル マシンで実行することもできます。その場合、?mode=redraw のようにクエリ文字列引数を介してモードを選択できます。
私もこの質問に対する答えを探していましたが、受け入れられた答えは私にとって壊れていました。どうやら window.innerWidth の使用は移植性がありません。一部のブラウザーでは動作しますが、Firefox は気に入らないことに気付きました。
Gregg Tavares は、この問題に直接対処する優れたリソースをここに投稿しました: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (アンチパターン # の 3 と 4 を参照)。
window.innerWidth の代わりに canvas.clientWidth を使用するとうまくいくようです。
グレッグの提案するレンダー ループは次のとおりです。
function resize() {
var width = gl.canvas.clientWidth;
var height = gl.canvas.clientHeight;
if (gl.canvas.width != width ||
gl.canvas.height != height) {
gl.canvas.width = width;
gl.canvas.height = height;
return true;
}
return false;
}
var needToRender = true; // draw at least once
function checkRender() {
if (resize() || needToRender) {
needToRender = false;
drawStuff();
}
requestAnimationFrame(checkRender);
}
checkRender();
<!DOCTYPE html>
<html>
<head>
<title>aj</title>
</head>
<body>
<canvas id="c"></canvas>
</body>
</html>
CSSを使用
body {
margin: 0;
padding: 0
}
#c {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden
}
(動靜能量の回答を拡大)
ボディを埋めるようにキャンバスをスタイルします。キャンバスにレンダリングするときは、そのサイズを考慮してください。
http://jsfiddle.net/mqFdk/356/
<!DOCTYPE html>
<html>
<head>
<title>aj</title>
</head>
<body>
<canvas id="c"></canvas>
</body>
</html>
CSS:
body {
margin: 0;
padding: 0
}
#c {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden
}
Javascript:
function redraw() {
var cc = c.getContext("2d");
c.width = c.clientWidth;
c.height = c.clientHeight;
cc.scale(c.width, c.height);
// Draw a circle filling the canvas.
cc.beginPath();
cc.arc(0.5, 0.5, .5, 0, 2*Math.PI);
cc.fill();
}
// update on any window size change.
window.addEventListener("resize", redraw);
// first draw
redraw();