HTML5 Canvas 100%视口宽度?

ahe*_*ick 141 jquery html5 canvas viewport

我正在尝试创建一个占用视口宽度和高度100%的画布元素.

你可以在我的例子看到这里正在发生,但它是在Chrome和FireFox中添加滚动条.如何防止额外的滚动条,只提供窗口的宽度和高度作为画布的大小?

jar*_*lli 248

为了使画布全屏宽度和高度始终如此,即使在调整浏览器大小时,也需要在将画布大小调整为window.innerHeight和window.innerWidth的函数中运行绘制循环.

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

HTML

<canvas id="canvas"></canvas>
Run Code Online (Sandbox Code Playgroud)

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
    }
})();
Run Code Online (Sandbox Code Playgroud)

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 */
Run Code Online (Sandbox Code Playgroud)

这就是你如何正确地使画布的全宽和高度的浏览器.您只需将绘制的所有代码放入drawStuff()函数中的画布.

  • `display:block`:这不仅会删除滚动条,而且还会从文档正文的高度中删除2px,这通常是在块内的文本行下添加的.所以+1为此 (19认同)
  • 加一表示没有 jQuery (4认同)
  • 为什么有必要去除衬垫并将宽度,高度设置为100%? (2认同)
  • 我相信它主要用于覆盖浏览器默认的用户样式表.如果你正在使用某种规范化或重置css文件,这是没有必要的,因为这已经得到了解决. (2认同)
  • 如果你期望大量调整大小; 例如,在肖像/风景设备上,你想要```debounce```调整大小,否则你会淹没浏览器. (2认同)

Vit*_*nko 28

您可以尝试视口单元(CSS3):

canvas { 
  height: 100vh; 
  width: 100vw; 
  display: block;
}
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个并发现在Chrome和Firefox中,画布只是将图像拉伸到完整视口.即使是新绘制的元素也会被拉伸. (16认同)
  • **此方法不起作用,它会拉伸文本.你很遗憾*********使用JS.** (16认同)
  • @Daniel是对的 - 这个答案是错误的*.它不会设置画布上下文的内部维度,而是设置DOM元素的维度.有区别的,请参阅[我对相关问题的回答](http://stackoverflow.com/questions/4032179/how-do-i-get-the-width-and-height-of-a-html5-canvas/ 31195651#31195651). (8认同)
  • 添加`display:block;`并完成工作. (4认同)

mat*_*uds 14

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

窗口将具有一些宽高比(宽度/高度),画布对象也是如此.你希望这两个纵横比如何相互关联是你必须要清楚的一件事,这个问题没有"一刀切"的答案 - 我会经历一些你可能会遇到的常见情况想.

最重要的是你必须清楚:html canvas对象有一个width属性和一个height属性; 然后,同一个对象的css也有一个width和height属性.这两个宽度和高度是不同的,两者都适用于不同的东西.

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

我看到4种你可能想要在窗口调整大小时发生的事情(全部以全屏画布开始)

1:您希望宽度保持100%,并且您希望宽高比保持不变.在这种情况下,您不需要重绘画布; 你甚至不需要一个窗口大小调整处理程序.所有你需要的是

$(ctx.canvas).css("width", "100%");
Run Code Online (Sandbox Code Playgroud)

其中ctx是您的画布上下文.小提琴:resizeByWidth

2:您希望宽度和高度都保持100%,并且您希望得到的宽高比变化具有拉伸图像的效果.现在,您仍然不需要重绘画布,但需要一个窗口调整大小处理程序.在处理程序中,你这样做

$(ctx.canvas).css("height", window.innerHeight);
Run Code Online (Sandbox Code Playgroud)

小提琴:messWithAspectratio

3:您希望宽度和高度都保持100%,但宽高比变化的答案与拉伸图像不同.然后你需要重绘,并按照接受的答案中概述的方式进行重绘.

小提琴:重绘

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

小提琴:固定

除了设置模式的第63行外,所有小提琴都有相同的代码.您还可以复制小提琴代码以在本地计算机上运行,​​在这种情况下,您可以通过查询字符串参数选择模式,如?mode = redraw


Dav*_*vid 8

我也想找到这个问题的答案,但接受的答案对我来说是打破了.显然使用window.innerWidth是不可移植的.它在某些浏览器中有效,但我注意到Firefox并不喜欢它.

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();
Run Code Online (Sandbox Code Playgroud)


nop*_*ole 7

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

<!DOCTYPE html>
<html>
<head>
    <title>aj</title>
</head>
<body>

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

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

用CSS

body { 
       margin: 0; 
       padding: 0
     }
#c { 
     position: absolute; 
     width: 100%; 
     height: 100%; 
     overflow: hidden
   }
Run Code Online (Sandbox Code Playgroud)

  • 实际上是的,canvas元素确实需要一个明确的宽度/高度设置.没有它,它们默认为某些浏览器预设(在chrome中,我认为它是300x150px)大小.所有绘制到画布的图形都以此大小进行解释,然后缩放到视口大小的100%.尝试在画布上绘制___anything___以查看我的意思 - 它会被扭曲. (16认同)
  • canvas 元素的内在尺寸等于坐标空间的大小,数字以 CSS 像素解释。但是,元素可以通过样式表任意调整大小。在渲染过程中,图像被缩放以适应此布局大小。 (2认同)