我正在尝试创建一个画布元素,该元素占用视口宽度和高度的100%。
您可以在我的示例中看到这种情况的发生,但是它正在Chrome和FireFox中添加滚动条。如何防止多余的滚动条,仅将窗口的宽度和高度设置为画布的大小?
我正在尝试创建一个画布元素,该元素占用视口宽度和高度的100%。
您可以在我的示例中看到这种情况的发生,但是它正在Chrome和FireFox中添加滚动条。如何防止多余的滚动条,仅将窗口的宽度和高度设置为画布的大小?
Answers:
为了使画布始终保持全屏宽度和高度,这意味着即使调整了浏览器的大小,也需要在将画布调整为window.innerHeight和window.innerWidth的函数中运行绘制循环。
示例:http://jsfiddle.net/jaredwilli/qFuDr/
<canvas id="canvas"></canvas>
(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
}
})();
* { 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()函数中将所有用于绘制的代码放到画布上即可。
debounce
调整大小,否则将使浏览器泛滥。
display: block
:这不仅会删除滚动条,还会从文档正文的高度中删除2px,这些像素通常添加在块内的文本行下。因此+1
您可以尝试视口单位(CSS3):
canvas {
height: 100vh;
width: 100vw;
display: block;
}
display: block;
并完成工作。
我将回答一个更通用的问题,即如何在调整窗口大小时动态调整画布的大小。可接受的答案适当地处理了宽度和高度都假定为100%的情况,这是所要求的,但同时也会改变画布的纵横比。许多用户会希望在调整窗口大小的同时调整画布的大小,但同时保持宽高比不变。这不是确切的问题,但它“适合”,只是将问题放到了更一般的背景下。
窗口将具有某些纵横比(宽度/高度),画布对象也将具有纵横比。您要如何将这两个长宽比相互关联是一件事,您必须弄清楚,这个问题没有“一刀切”的答案-我将介绍一些您可能会遇到的常见情况想。
您必须清楚的最重要的事情是:html canvas对象具有width属性和height属性;然后,同一对象的css也具有width和height属性。这两个宽度和高度是不同的,两者都可用于不同的事物。
更改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行外,所有小提琴都具有相同的代码。您还可以复制小提琴代码以在本地计算机上运行,在这种情况下,可以通过querystring参数选择模式,如?mode = redraw
$(ctx.canvas).css("width", "100%");
相当于$(canvas).css("width", "100%");
(上下文的画布只是画布)
ctx.canvas
比3)短很多canvas.getContext('2d')
-这就是为什么我喜欢2)。因此,没有名为canvas的变量,但是有ctx.canvas。那就是ctx.canvas的来源。
<!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
}
我也想找到这个问题的答案,但是被接受的答案对我来说是个难题。显然,使用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();
(扩大动静能量的答案)
设置画布样式以填充主体。在渲染到画布时,请考虑其大小。
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();