HTML5 Canvas 100%视口宽度?

时间:2022-11-12 07:25:09

I am trying to create a canvas element that takes up 100% of the width and height of the viewport.

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

You can see in my example here that is occurring, however it is adding scroll bars in both Chrome and FireFox. How can I prevent the extra scroll bars and just provide exactly the width and height of the window to be the size of the canvas?

您可以在我的示例中看到正在发生的情况,但是它在Chrome和FireFox中都添加了滚动条。如何防止额外的滚动条,只是提供窗口的宽度和高度作为画布的大小?

6 个解决方案

#1


223  

In order to make the canvas full screen width and height always, meaning even when the browser is resized, you need to run your draw loop within a function that resizes the canvas to the window.innerHeight and window.innerWidth.

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

Example: 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 */

That is how you properly make the canvas full width and height of the browser. You just have to put all the code for drawing to the canvas in the drawStuff() function.

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

#2


27  

You can try viewport units (CSS3):

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

canvas {   height: 100vh;   width: 100vw;   display: block;}

#3


13  

I'll answer the more general question of how to have a canvas dynamically adapt in size upon window resize. The accepted answer appropriately handles the case where width and height are both supposed to be 100%, which is what was asked for, but which also will change the aspect ratio of the canvas. Many users will want the canvas to resize on window resize, but while keeping the aspect ratio untouched. It's not the exact question, but it "fits in", just putting the question into a slightly more general context.

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

The window will have some aspect ratio (width / height), and so will the canvas object. How you want these two aspect ratios to relate to each other is one thing you'll have to be clear about, there is no "one size fits all" answer to that question - I'll go through some common cases of what you might want.

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

Most important thing you have to be clear about: the html canvas object has a width attribute and a height attribute; and then, the css of the same object also has a width and a height attribute. Those two widths and heights are different, both are useful for different things.

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

Changing the width and height attributes is one method with which you can always change the size of your canvas, but then you'll have to repaint everything, which will take time and is not always necessary, because some amount of size change you can accomplish via the css attributes, in which case you do not redraw the canvas.

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

I see 4 cases of what you might want to happen on window resize (all starting with a full screen canvas)

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

1: you want the width to remain 100%, and you want the aspect ratio to stay as it was. In that case, you do not need to redraw the canvas; you don't even need a window resize handler. All you need is

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

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

where ctx is your canvas context.fiddle: resizeByWidth

其中ctx是你的canvas context.fiddle:resizeByWidth

2: you want width and height to both stay 100%, and you want the resulting change in aspect ratio to have the effect of a stretched-out image. Now, you still don't need to redraw the canvas, but you need a window resize handler. In the handler, you do

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

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

fiddle: messWithAspectratio

3: you want width and height to both stay 100%, but the answer to the change in aspect ratio is something different from stretching the image. Then you need to redraw, and do it the way that is outlined in the accepted answer.

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

fiddle: redraw

4: you want the width and height to be 100% on page load, but stay constant thereafter (no reaction to window resize.

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

fiddle: fixed

All fiddles have identical code, except for line 63 where the mode is set. You can also copy the fiddle code to run on your local machine, in which case you can select the mode via a querystring argument, as ?mode=redraw

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

#4


8  

I was looking to find the answer to this question too, but the accepted answer was breaking for me. Apparently using window.innerWidth isn't portable. It does work in some browsers, but I noticed Firefox didn't like it.

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

Gregg Tavares posted a great resource here that addresses this issue directly:http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html(See anti-pattern #'s 3 and 4).

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

Using canvas.clientWidth instead of window.innerWidth seems to work nicely.

使用canvas.clientWidth而不是window.innerWidth似乎很好用。

Here's Gregg's suggested render loop:

这是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 oncefunction checkRender() {   if (resize() || needToRender) {     needToRender = false;     drawStuff();   }   requestAnimationFrame(checkRender);}checkRender();

#5


7  

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

<!DOCTYPE html><html><head>    <title>aj</title></head><body>    <canvas id="c"></canvas></body></html>

with CSS

body {        margin: 0;        padding: 0     }#c {      position: absolute;      width: 100%;      height: 100%;      overflow: hidden   }

#6


2  

(Expanding upon 動靜能量's answer)

(扩大动静能量的答案)

Style the canvas to fill the body. When rendering to the canvas take its size into account.

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

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 drawredraw();

#1


223  

In order to make the canvas full screen width and height always, meaning even when the browser is resized, you need to run your draw loop within a function that resizes the canvas to the window.innerHeight and window.innerWidth.

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

Example: 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 */

That is how you properly make the canvas full width and height of the browser. You just have to put all the code for drawing to the canvas in the drawStuff() function.

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

#2


27  

You can try viewport units (CSS3):

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

canvas {   height: 100vh;   width: 100vw;   display: block;}

#3


13  

I'll answer the more general question of how to have a canvas dynamically adapt in size upon window resize. The accepted answer appropriately handles the case where width and height are both supposed to be 100%, which is what was asked for, but which also will change the aspect ratio of the canvas. Many users will want the canvas to resize on window resize, but while keeping the aspect ratio untouched. It's not the exact question, but it "fits in", just putting the question into a slightly more general context.

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

The window will have some aspect ratio (width / height), and so will the canvas object. How you want these two aspect ratios to relate to each other is one thing you'll have to be clear about, there is no "one size fits all" answer to that question - I'll go through some common cases of what you might want.

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

Most important thing you have to be clear about: the html canvas object has a width attribute and a height attribute; and then, the css of the same object also has a width and a height attribute. Those two widths and heights are different, both are useful for different things.

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

Changing the width and height attributes is one method with which you can always change the size of your canvas, but then you'll have to repaint everything, which will take time and is not always necessary, because some amount of size change you can accomplish via the css attributes, in which case you do not redraw the canvas.

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

I see 4 cases of what you might want to happen on window resize (all starting with a full screen canvas)

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

1: you want the width to remain 100%, and you want the aspect ratio to stay as it was. In that case, you do not need to redraw the canvas; you don't even need a window resize handler. All you need is

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

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

where ctx is your canvas context.fiddle: resizeByWidth

其中ctx是你的canvas context.fiddle:resizeByWidth

2: you want width and height to both stay 100%, and you want the resulting change in aspect ratio to have the effect of a stretched-out image. Now, you still don't need to redraw the canvas, but you need a window resize handler. In the handler, you do

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

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

fiddle: messWithAspectratio

3: you want width and height to both stay 100%, but the answer to the change in aspect ratio is something different from stretching the image. Then you need to redraw, and do it the way that is outlined in the accepted answer.

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

fiddle: redraw

4: you want the width and height to be 100% on page load, but stay constant thereafter (no reaction to window resize.

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

fiddle: fixed

All fiddles have identical code, except for line 63 where the mode is set. You can also copy the fiddle code to run on your local machine, in which case you can select the mode via a querystring argument, as ?mode=redraw

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

#4


8  

I was looking to find the answer to this question too, but the accepted answer was breaking for me. Apparently using window.innerWidth isn't portable. It does work in some browsers, but I noticed Firefox didn't like it.

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

Gregg Tavares posted a great resource here that addresses this issue directly:http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html(See anti-pattern #'s 3 and 4).

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

Using canvas.clientWidth instead of window.innerWidth seems to work nicely.

使用canvas.clientWidth而不是window.innerWidth似乎很好用。

Here's Gregg's suggested render loop:

这是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 oncefunction checkRender() {   if (resize() || needToRender) {     needToRender = false;     drawStuff();   }   requestAnimationFrame(checkRender);}checkRender();

#5


7  

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

<!DOCTYPE html><html><head>    <title>aj</title></head><body>    <canvas id="c"></canvas></body></html>

with CSS

body {        margin: 0;        padding: 0     }#c {      position: absolute;      width: 100%;      height: 100%;      overflow: hidden   }

#6


2  

(Expanding upon 動靜能量's answer)

(扩大动静能量的答案)

Style the canvas to fill the body. When rendering to the canvas take its size into account.

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

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 drawredraw();