【问题标题】:How do you resize a canvas without flicker?如何在不闪烁的情况下调整画布大小?
【发布时间】:2013-07-20 16:33:11
【问题描述】:

许多 Three.js 示例在调整窗口大小或框架具有白色边框时会闪烁。例如:http://threejs.org/examples/webgl_animation_skinning.html

另一方面,WebGL Aquarium 不闪烁。这是怎么做到的?

【问题讨论】:

    标签: canvas three.js webgl


    【解决方案1】:

    AFAICT 大多数 Three.JS 示例通过查看窗口大小或容器大小,然后设置 canvas.width、canvas.height 来手动设置画布的大小。

    另一方面,包括 WebGL Aquarium 在内的 TDL 示例使用 CSS 让浏览器缩放画布,然后在 requestAnimationFrame 回调中更新画布后备存储的大小。

    这是一个例子

    const gl = document.querySelector("#c").getContext("webgl");
    
    function render() {
      resizeCanvasToDisplaySize(gl.canvas);
    
      gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
      
      // Draw a 2 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(2, 2, gl.canvas.width - 4, gl.canvas.height - 4);
      gl.clearColor(0, 0, 1, 1);  // blue
      gl.clear(gl.COLOR_BUFFER_BIT);
    
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    function resizeCanvasToDisplaySize(canvas) {
      const width  = canvas.clientWidth;
      const height = canvas.clientHeight;
      if (canvas.width !== width || canvas.height !== height) {
        canvas.width  = width;
        canvas.height = height;
      }
    }
    body {
      margin: 0;
    }
    #c {
      width: 100vw;
      height: 100vh;
      display: block;
    }
    <canvas id="c"></canvas>

    或小提琴http://jsfiddle.net/greggman/pfWS3/

    【讨论】:

      【解决方案2】:

      调整窗口大小后需要立即调用渲染。

      更好的是,您可以拥有requestAnimationFrame 并在一个函数调用中调整大小然后渲染。它将确保回流和渲染在一次回流中立即发生,而不是分开导致闪烁。

      【讨论】:

        【解决方案3】:
        function onWindowResize() {
        
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
        
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.render(scene, camera);
            }
        

        【讨论】:

          猜你喜欢
          • 2011-05-18
          • 2012-02-07
          • 2013-03-25
          • 2021-07-21
          • 2023-02-05
          • 2013-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多