我正在尝试创建一个占视口宽度和高度 100% 的画布元素。
您可以在我的示例中看到这种情况正在发生,但是它在 Chrome 和 FireFox 中都添加了滚动条。如何防止额外的滚动条,只提供窗口的宽度和高度作为画布的大小?
为了使画布始终全屏宽度和高度,这意味着即使调整浏览器大小,您也需要在将画布大小调整为window.innerHeight
and的函数中运行绘制循环window.innerWidth
。
示例:http: //jsfiddle.net/jaredwilli/qFuDr/
<canvas id="canvas"></canvas>
(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
}
})();
* { 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()
函数中的画布即可。
您可以尝试视口单位(CSS3):
canvas {
height: 100vh;
width: 100vw;
display: block;
}
我将回答更一般的问题,即如何让画布在调整窗口大小时动态调整大小。接受的答案适当地处理了宽度和高度都应该为 100% 的情况,这是所要求的,但也会改变画布的纵横比。许多用户希望画布在窗口调整大小时调整大小,但同时保持纵横比不变。这不是确切的问题,但它“适合”,只是将问题置于更一般的背景下。
窗口将具有一定的纵横比(宽度/高度),画布对象也是如此。你希望这两个纵横比如何相互关联是你必须清楚的一件事,这个问题没有“一刀切”的答案——我将通过一些常见的案例来说明你可能会遇到的情况想。
最重要的事情你要清楚:html canvas 对象有一个 width 属性和一个 height 属性;然后,同一个对象的 css 也有一个 width 和一个 height 属性。这两个宽度和高度是不同的,它们都对不同的东西有用。
更改宽度和高度属性是您始终可以更改画布大小的一种方法,但是您必须重新绘制所有内容,这需要时间并且并非总是必要的,因为您可以完成一些大小更改通过 css 属性,在这种情况下,您不会重绘画布。
我看到了 4 种您可能希望在调整窗口大小时发生的情况(全部从全屏画布开始)
1:您希望宽度保持 100%,并且希望纵横比保持原样。在这种情况下,您不需要重新绘制画布;您甚至不需要窗口调整大小处理程序。所有你需要的是
$(ctx.canvas).css("width", "100%");
其中 ctx 是您的画布上下文。小提琴:resizeByWidth
2:您希望宽度和高度都保持 100%,并且希望由此产生的纵横比变化具有拉伸图像的效果。现在,您仍然不需要重绘画布,但您需要一个窗口调整大小处理程序。在处理程序中,你做
$(ctx.canvas).css("height", window.innerHeight);
3:您希望宽度和高度都保持 100%,但纵横比变化的答案与拉伸图像不同。然后您需要重新绘制,并按照接受的答案中概述的方式进行。
小提琴:重绘
4:您希望页面加载时的宽度和高度为 100%,但此后保持不变(对窗口调整大小没有反应。
小提琴:固定
所有小提琴都有相同的代码,除了第 63 行设置了模式。您还可以复制小提琴代码以在本地计算机上运行,在这种情况下,您可以通过查询字符串参数选择模式,如 ?mode=redraw
我也在寻找这个问题的答案,但接受的答案对我来说是个问题。显然使用 window.innerWidth 是不可移植的。它在某些浏览器中确实有效,但我注意到 Firefox 不喜欢它。
Gregg Tavares 在这里发布了一个很好的资源,直接解决了这个问题: http ://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (参见 anti-pattern #'s 3 和 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();
<!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/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();
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