【问题标题】:Resize the canvas while entering and leaving fullscreen进入和离开全屏时调整画布大小
【发布时间】:2014-11-01 23:24:42
【问题描述】:

我想在进入和离开全屏时调整画布的大小。我正在使用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>

【问题讨论】:

    标签: javascript html canvas three.js


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      如果您 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。

      【讨论】:

        【解决方案3】:

        好吧,到目前为止我能想到的最糟糕也是唯一的解决方案是添加这个添加回调函数的结尾

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

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

        【讨论】:

          【解决方案4】:
          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 );
          });
          

          【讨论】:

            猜你喜欢
            • 2014-06-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-31
            相关资源
            最近更新 更多