HTML5 Canvas 100% 宽度视口高度?

发布于 2024-10-04 19:20:04 字数 167 浏览 5 评论 0原文

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夏末的微笑 2024-10-11 19:20:04

为了使画布始终全屏宽度和高度,这意味着即使调整浏览器大小,您也需要在将画布大小调整为 window.innerHeight 和 <代码>window.innerWidth。

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

HTML

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

JavaScript

(function() {
  const canvas = document.getElementById('canvas');
  const 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 */

这就是你正确的方式使画布充满浏览器的宽度和高度。您只需将用于绘制到画布的所有代码放入 drawStuff() 函数中即可。

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.

Example: http://jsfiddle.net/jaredwilli/qFuDr/

HTML

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

JavaScript

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

不甘平庸 2024-10-11 19:20:04

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

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

You can try viewport units (CSS3):

canvas { 
  height: 100vh; 
  width: 100vw; 
  display: block;
}
萌化 2024-10-11 19:20:04

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

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

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

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

我看到您在调整窗口大小时可能希望发生的情况有 4 种情况(全部从全屏画布开始)

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

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

ctx 是您的画布上下文。
fiddle: resizeByWidth

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

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

以下操作: messWithAspectratio

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

fiddle: redraw

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

小提琴:已修复

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

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.

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.

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.

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

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

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

where ctx is your 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

$(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.

fiddle: redraw

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

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

我的鱼塘能养鲲 2024-10-11 19:20:04

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
   }

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
   }
爱你是孤单的心事 2024-10-11 19:20:04

我也在寻找这个问题的答案,但接受的答案对我来说是破坏性的。显然使用 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();

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.

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).

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

Here's Gregg's suggested render loop:

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();
假扮的天使 2024-10-11 19:20:04

(扩展动静能量的答案)

设计画布以填充身体。渲染到画布时,请考虑其大小。

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

(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 draw
redraw();
海的爱人是光 2024-10-11 19:20:04

对于手机,最好使用它,

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

因为更改方向后会显示不正确。将方向更改为纵向时,“视口”将会增加。查看完整内容
示例

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文