代码之家  ›  专栏  ›  技术社区  ›  aherrick

HTML5画布100%宽度,视区高度?

  •  131
  • aherrick  · 技术社区  · 14 年前

    我正在尝试创建一个画布元素,它占据了视区宽度和高度的100%。

    你可以在我的例子中看到 here 不过,它在Chrome和Firefox中都添加了滚动条。我怎样才能防止额外的滚动条,只提供窗口的宽度和高度,使之与画布的大小完全一致?

    6 回复  |  直到 9 年前
        1
  •  238
  •   jaredwilli    13 年前

    为了使画布始终保持全屏宽度和高度,这意味着即使调整了浏览器的大小,也需要在将画布调整为window.innerheight和window.innerwidth的函数中运行绘制循环。

    例子: http://jsfiddle.net/jaredwilli/qFuDr/

    HTML

    <canvas id="canvas"></canvas>
    

    javascript

    (function() {
        var canvas = document.getElementById('canvas'),
                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
        }
    })();
    

    CSS

    * { 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 */
    

    这就是如何正确地使画布成为浏览器的整个宽度和高度。您只需在drawstufacture()函数中将用于绘图的所有代码放到画布上。

        2
  •  27
  •   Vitalii Fedorenko    9 年前

    你可以试试 viewport units (CSS3):

    canvas { 
      height: 100vh; 
      width: 100vw; 
      display: block;
    }
    
        3
  •  14
  •   mathheadinclouds    11 年前

    我将回答更一般的问题,即如何在窗口调整大小时动态调整画布的大小。接受的答案可以适当地处理宽度和高度都应该为100%的情况,这是要求的,但也会改变画布的纵横比。许多用户希望画布在窗口调整大小时调整大小,但同时保持纵横比不变。这不是一个确切的问题,但它“适合”,只是把问题放在一个稍微更一般的上下文中。

    窗口将具有一些纵横比(宽度/高度),画布对象也将具有。你要如何让这两个纵横比相互关联,这是你必须清楚的一件事,对于这个问题没有“一刀切”的答案-我将介绍一些你可能想要的常见情况。

    最重要的是,您必须清楚:HTML画布对象有一个宽度属性和一个高度属性;然后,同一对象的CSS也有一个宽度和一个高度属性。这两种宽度和高度是不同的,都对不同的事物有用。

    更改宽度和高度属性是一种方法,您可以随时更改画布的大小,但随后必须重新绘制所有内容,这将花费时间,并不总是必要的,因为您可以通过CSS属性完成一些大小更改,在这种情况下,您不必重新绘制画布。

    我看到了4个窗口调整大小时可能会发生的情况(全部从全屏画布开始)

    1:您希望宽度保持100%,并且希望纵横比保持原样。在这种情况下,不需要重新绘制画布;甚至不需要窗口大小调整处理程序。你只需要

    $(ctx.canvas).css("width", "100%");
    

    CTX是你的画布背景。 小提琴: resizeByWidth

    2:您希望宽度和高度都保持100%,并且希望所产生的纵横比变化具有拉伸图像的效果。现在,您仍然不需要重新绘制画布,但需要一个窗口大小调整处理程序。在处理程序中,

    $(ctx.canvas).css("height", window.innerHeight);
    

    小提琴: messWithAspectratio

    3:您希望宽度和高度都保持100%,但是纵横比变化的答案不同于拉伸图像。然后,您需要重新绘制,并按照公认答案中概述的方式进行。

    小提琴: redraw

    4:您希望页面加载时宽度和高度为100%,但此后保持不变(对窗口大小没有反应)。

    小提琴: fixed

    所有的小提琴都有相同的代码,除了设置模式的第63行。您还可以复制要在本地计算机上运行的小提琴代码,在这种情况下,您可以通过querystring参数选择模式,例如?模式=重绘

        4
  •  8
  •   David    9 年前

    我也在寻找这个问题的答案,但被接受的答案对我来说已经破灭了。显然,使用window.innerwidth是不可移植的。它在某些浏览器中确实可以使用,但我注意到火狐不喜欢它。

    Gregg Tavares在这里发布了一个很好的资源,可以直接解决这个问题: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (见反模式3和4)。

    使用canvas.clientwidth而不是window.innerwidth似乎工作得很好。

    以下是Gregg建议的渲染循环:

    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();
    
        5
  •  7
  •   Marc Audet    11 年前

    http://jsfiddle.net/mqFdk/10/

    <!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
       }
    
        6
  •  2
  •   Vincent Scheib    11 年前

    (扩展到__的答案)

    设置画布样式以填充主体。渲染到画布时,请考虑其大小。

    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();
    
    推荐文章