jQuery HTML5 Canvas 100% 宽视口的高度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4288253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:00:18  来源:igfitidea点击:

HTML5 Canvas 100% Width Height of Viewport?

jqueryhtmlcanvasviewport

提问by aherrick

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 herethat 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中添加滚动条。如何防止出现额外的滚动条并仅提供与画布大小相同的窗口的宽度和高度?

回答by jaredwilli

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/

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

HTML

HTML

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

JavaScript

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

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() 函数中的画布上。

回答by Vitalii Fedorenko

You can try viewport units(CSS3):

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

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

回答by mathheadinclouds

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 是您的画布上下文。小提琴: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

小提琴: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

回答by nonopolarity

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

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

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

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

</body>
</html>

with CSS

使用 CSS

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

回答by David

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

回答by Vincent Scheib

(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/

http://jsfiddle.net/mqFdk/356/

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

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

</body>
</html>

CSS:

CSS:

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

Javascript:

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

回答by dzanis

For mobiles, it's better to use it

对于手机,最好使用它

canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;

because it will display incorrectly after changing the orientation.The “viewport” will be increased when changing the orientation to portrait.See full example

因为更改方向后会显示不正确。将方向更改为纵向时会增加“视口”。请参阅完整 示例