2010-11-26 154 views
112

我想創建佔用視口寬度和高度100%的畫布元素。HTML5帆布100%寬度視口高度?

您可以在我的示例here中看到正在發生的情況,但它正在Chrome和FireFox中添加滾動條。我怎樣才能防止額外的滾動條,並提供正確的窗口的寬度和高度作爲畫布的大小?

+0

參見:https://stackoverflow.com/questions/4037212 – hippietrail 2017-08-23 23:36:51

回答

211

爲了使畫布全屏幕寬度和高度始終,這意味着即使在瀏覽器的大小時,你需要的內部運行平局循環一個將畫布的大小調整爲window.innerHeight和window.innerWidth的函數。

例子: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 */ 

這就是你如何正確地使畫布全寬和黑瀏覽器的高分辨率。你只需要把所有的繪圖代碼放到drawStuff()函數的畫布上。

6

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 
    } 
+0

這工作,但它留下我的畫布沒有定義的寬度和高度。畫布寬度和高度必須在我相信的元素上定義。 – aherrick 2010-11-26 22:49:41

+0

@aherrick:不,你不必在canvas元素上設置一個明確的寬度/高度來使其工作。此代碼應該可以正常工作。 – 2011-09-13 14:04:01

+14

其實是的,畫布元素確實需要明確的寬度/高度集合。沒有它,他們默認一些瀏覽器預設(在鉻,我認爲它是300x150px)的大小。所有繪製到畫布上的圖形都會以此大小進行解釋,然後縮放到視口大小的100%。試着在你的畫布上繪製___任何東西,看看我的意思 - 它會被扭曲。 – 2011-12-13 08:46:01

24

您可以嘗試viewport units(CSS3):

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

風格(在動靜能量的答案擴大)畫布補身體。渲染到畫布時考慮其大小。

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

我會回答如何有一個動態的畫布大小在適應更普遍的問題窗口大小調整。被接受的答案適當地處理了寬度和高度都應該是100%的情況,這是要求的,但是這也會改變畫布的寬高比。許多用戶會希望畫布調整窗口大小,但保持縱橫比不變。這不是確切的問題,但它「適合」,只是把問題放到一個稍微更一般的上下文中。

窗口將有一些寬高比(寬度/高度),畫布對象也是如此。你如何讓這兩個縱橫比相互關聯是你必須清楚的一件事,對這個問題沒有「一刀切」的答案 - 我會通過一些你可能會遇到的常見案例想。

最重要的事情,你必須清楚:在HTML Canvas對象的寬度屬性和高度屬性;然後,同一對象的css也具有寬度和高度屬性。這兩個寬度和高度是不同的,對於不同的事情都是有用的。

更改寬度和高度屬性是您可以隨時更改畫布大小的一種方法,但是您必須重新繪製所有內容,這需要時間並不總是必要的,因爲某些大小改變你可以通過CSS屬性來完成,在這種情況下你不會重畫畫布。

我看到4箱子你可能希望在窗口大小調整到發生什麼(都開始採用了全屏幕畫布)

1:所需的寬度將保持100%,並且要寬高比留因爲它是。在這種情況下,你不需要重畫畫布。你甚至不需要窗口調整大小處理程序。所有你需要的是

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

其中CTX是你的畫布背景。 撥弄:resizeByWidth

2:你想的寬度和高度二者留100%,並且希望在寬高比產生的變化有一個伸展出的圖像的效果。現在,您仍然不需要重新繪製畫布,但是您需要一個窗口大小調整處理程序。在處理程序中,你做

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

小提琴:messWithAspectratio

3:你要的寬度和高度都留100%,但答案在寬高比的變化是什麼,從拉伸的圖像不同。然後,您需要重新繪製,並按照接受的答案中列出的方式進行。

小提琴:redraw

4:你想要的寬度和高度是在頁面加載100%,但保持不變之後(到窗口大小調整沒有反應

小提琴:fixed

所有小提琴具有相同的代碼,除了線63在模式設置,也可以複製小提琴代碼到你的本地計算機上運行,​​在這種情況下,您可以選擇通過查詢字符串參數的模式,如?模式=重繪

8

我也在尋找這個問題的答案,但接受的答案是爲我打破。顯然使用window.innerWidth是不可移植的。它在某些瀏覽器中可以工作,但我注意到Firefox不喜歡它。

格雷格·塔瓦雷斯張貼在這裏有很大的資源,直接解決了這個問題: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (見反模式#的3和4)。

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

這裏的格雷格建議的渲染循環:

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