根据浏览器窗口大小调整视口/画布的大小



我希望我的webgl应用程序视口和画布能够对浏览器窗口大小的更改做出反应(包括F11按钮)。也就是说,我希望画布总是100%的宽度和高度,我希望视口的大小和纵横比是合适的。前者我用简单的方式实现:

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

尽管我不确定这是不是该走的路。我试图通过在这里找到的一些信息来实现后者:Webgl gl.viewport更改,但显然我做错了什么。我确实意识到:

canvas.onresize = resizeViewport;

是错误的,因为画布的大小不会经常改变(它总是100%的宽度和高度),但我不知道该怎么做。

以下是该应用程序的在线版本:http://nps.netarteria.pl/gallery.

我认为这是有效的:

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。如果浏览器调整了画布的大小,无论其容器是什么,代码都会看到大小不再匹配,并更新画布的drawingbuffer的大小。

渲染画布的适当视口大小几乎总是:

// Set the viewport to be the size of the canvas's drawingBuffer.
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

而如果你使用的是典型的三维数学库,你也有一个投影矩阵和一个函数——通常称为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

更新了上面的代码。

更新2

从使用100%切换到使用100vw100vw,因为这些可以说是更正确的。它们描述了您想要的,即使画布具有视口的大小,就像以前的解决方案一样,使画布具有文档的大小,然后尝试强制文档具有窗口的大小。由于文档的内容可能比窗口大,因此可以说这是错误的解决方案。

最新更新