进入和离开全屏时调整画布大小

时间:2014-09-08 17:01:43

标签: javascript html5 canvas three.js

我想在进入和离开全屏时调整画布大小。我使用的是three.js及其THREE.WebGLRenderer

使用下面的代码我可以这样做,但它设置了窗口的尺寸"一次迭代" - 这意味着当我进入全屏时它会设置较小的高度(但是底部),然后我离开整个屏幕,它在垂直方向上过度拉伸。

代码:

  var width  = window.innerWidth,
      height = window.innerHeight;
  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(width, height);

  function toggleFullscreen(){
    var docElm = document.documentElement;
    if(!document.fullscreen){
      if (docElm.requestFullscreen) {
          docElm.requestFullscreen();
      }   
      else if (docElm.mozRequestFullScreen) {
          docElm.mozRequestFullScreen();
      }   
      else if (docElm.webkitRequestFullScreen) {
          docElm.webkitRequestFullScreen();
      }   
      else if (docElm.msRequestFullscreen) {
          docElm.msRequestFullscreen();
      }   
      document.fullscreen = true;
    } 
    else{
      if (document.exitFullscreen) {
          document.exitFullscreen();
      }   
      else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
      }   
      else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen();
      }   
      else if (document.msExitFullscreen) {
          document.msExitFullscreen();
      }   
      document.fullscreen = false;
    }
    renderer.setSize(window.innerWidth, window.innerHeight);
  }

...

<body>
<div onclick="toggleFullscreen()" id="button">Fullscreen</button>
</body>

4 个答案:

答案 0 :(得分:1)

在进入或离开全屏之前,会调用setSize()函数中的toggleFullscreen()函数。这意味着渲染器的大小由先前的窗口大小设置。

通过requestFullscreenexitFullscreen触发onresize事件进入或离开全屏,因此在setSize()事件处理函数中编写onresize函数。

window.onresize = function() {
    renderer.setSize(window.innerWidth, window.innerHeight);
}

答案 1 :(得分:1)

如果follow best practices全屏工作正常,则不需要对three.js代码进行任何更改。

Here's a working example that follows best practices(点击任意位置全屏)。此处的a bunch more samples that all use the same code显示,当您遵循最佳实践时,不必为所有不同的用例更改任何代码

在这种情况下的最佳做法意味着使用CSS并拥抱浏览器而不是反对它。这意味着设置你的CSS,使你的画布(和其他元素)伸展或缩放或移动到任何地方,无论你想要它们。然后查找浏览器的操作并设置画布的后备存储以匹配。

这是调整代码的大小,当你让CSS做它应该做的事情时它会起作用。

// Resize by clientWidth and clientHeight
var resize = function() {
    var width  = canvas.clientWidth;
    var height = canvas.clientHeight;
    if (canvas.width  != width ||
        canvas.height != height ) {

          // You have to pass false here otherwise three.js does
          // arguably the wrong thing and fights the CSS.

          renderer.setSize( canvas.clientWidth, canvas.clientHeight, false );

        camera.aspect = canvas.clientWidth / canvas.clientHeight;
        camera.updateProjectionMatrix();
    }
};

现在将画布CSS设置为100%大小

canvas {
  width: 100%;
  height: 100%;
}

如果您将容器放在容器中,就像另一个div设置一样,也是100%大小,并将body,html设置为100%

html, body {
  width: 100%;
  height: 100%;
  margin: 0px;
  padding: 0px;
  overflow: hidden;
}

如果你渲染每一帧只是在你的渲染循环中调用它,你就完成了。

var render = function() {
    resize();

    ...

    renderer.render( scene, camera );

    requestAnimationFrame( render, canvas );
};
render();

如果你没有渲染每一帧,那么在你进行渲染时调用resize,并在屏幕调整大小时调用render。

答案 2 :(得分:0)

好的最糟糕的是,到目前为止我唯一能提出的解决方案就是添加这个添加回调功能的结束

window.setTimeout(function(){
  renderer.setSize(window.innerWidth, window.innerHeight);
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
}, 500);

请告诉我它有多糟糕并提供另一种解决方案:)

答案 3 :(得分:0)

var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );

var canvas = renderer.domElement;
canvas.addEventListener('click', function(){
    canvas.requestFullscreen = canvas.requestFullscreen || 
        canvas.mozRequestFullScreen || 
        canvas.webkitRequestFullscreen || 
        canvas.msRequestFullscreen;
    canvas.requestFullscreen();
});
document.body.appendChild( canvas );

window.addEventListener('resize', function(event){
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth , window.innerHeight );
});