2010-11-26 19 views
112

Estoy tratando de crear un elemento canvas que ocupe el 100% del ancho y alto de la ventana gráfica.Lienzo HTML5 Altura del 100% de ancho de la ventana gráfica?

Puede ver en mi ejemplo here que está ocurriendo, sin embargo, está agregando barras de desplazamiento en Chrome y FireFox. ¿Cómo puedo evitar las barras de desplazamiento adicionales y simplemente proporcionar exactamente el ancho y alto de la ventana para que sea del tamaño del lienzo?

+0

Ver también: https://stackoverflow.com/questions/4037212 – hippietrail

Respuesta

211

Con el fin de hacer que el ancho de la pantalla completa de la lona y la altura siempre, es decir, incluso cuando se cambia el tamaño del navegador, lo que necesita para hacer funcionar su bucle de tracción dentro de una función que cambia el tamaño del lienzo a window.innerHeight y window.innerWidth.

Ejemplo: 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 */ 

Esa es la forma correcta de hacer el ancho completo y Hei lienzo altura del navegador. Solo tiene que poner todo el código para dibujar en el lienzo en la función drawStuff().

+1

¿Por qué es necesario eliminar el relleno y establecer el ancho y la altura? al 100%? – Kos

+1

Creo que es principalmente para anular la hoja de estilo de usuario que el navegador tiene por defecto. Si está utilizando algún tipo de archivo css normalizado o restablecido, esto no es necesario ya que ya se habrá solucionado. – jaredwilli

+1

Si espera un gran cambio de tamaño; en un dispositivo de retrato/paisaje, por ejemplo, le gustaría '' 'rebotar''' el tamaño, de lo contrario, inundaría el navegador. – dooburt

6

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

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

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

</body> 
</html> 

con CSS

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

Esto funciona, pero deja mi lienzo sin una anchura y una altura definida.El ancho y la altura del lienzo deben definirse en el elemento que creo. – aherrick

+0

@aherrick: No, no tiene que tener un ancho/alto explícito establecido en el elemento canvas para que funcione. Este código debería funcionar bien. –

+14

En realidad sí, los elementos canvas necesitan un conjunto explícito de ancho/alto. Sin él, tienen el tamaño predeterminado de algunos navegadores (en Chrome, creo que es 300x150px). Todo el dibujo en el lienzo se interpreta a este tamaño y luego se escala al 100% del tamaño de la ventana gráfica. Intenta dibujar ___ cualquier cosa___ en tu lienzo para ver lo que quiero decir: se distorsionará. –

24

Usted puede intentar viewport units (CSS3):

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

Agrega 'display: block;' y hace el trabajo. – superlukas

+13

Intenté esto y descubrí que en Chrome y Firefox, el lienzo simplemente muestra la imagen estirada en la vista completa. Incluso elementos recién dibujados se estiran también. –

+6

@Daniel tiene razón, esta respuesta es * incorrecta *. No establecerá la dimensión interna del contexto del lienzo, sino las dimensiones del elemento DOM. Para la diferencia, vea [mi respuesta a una pregunta relacionada] (http://stackoverflow.com/questions/4032179/how-do-i-get-the-width-and-height-of-a-html5-canvas/31195651#31195651). –

1

(Ampliando 動靜 能量 's respuesta) Estilo

el lienzo para llenar el cuerpo. Cuando renderice en el lienzo, tenga en cuenta su tamaño.

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

voy a responder a la cuestión más general de cómo tener un lienzo adaptarse dinámicamente al tamaño cambio de tamaño de la ventana. La respuesta aceptada maneja adecuadamente el caso donde se supone que el ancho y la altura son del 100%, que es lo que se solicitó, pero que también cambiará la relación de aspecto del lienzo. Muchos usuarios querrán que el lienzo cambie el tamaño del tamaño de la ventana, pero manteniendo intacta la relación de aspecto. No es la pregunta exacta, pero "encaja", simplemente colocando la pregunta en un contexto un poco más general.

La ventana tendrá una relación de aspecto (ancho/alto), y también lo hará el objeto canvas. Cómo desea que estas dos proporciones de aspecto se relacionen entre sí es algo que tendrá que tener en claro, no existe una respuesta de "talla única" para esa pregunta. Iré a través de algunos casos comunes de lo que podría querer.

Lo más importante que debe tener en claro: el objeto de lienzo html tiene un atributo de ancho y un atributo de alto; y luego, el CSS del mismo objeto también tiene un ancho y un atributo de altura. Esos dos anchos y alturas son diferentes, ambos son útiles para diferentes cosas.

Cambiar los atributos de ancho y alto es un método con el que siempre puede cambiar el tamaño de su lienzo, pero luego tendrá que volver a pintar todo, lo que llevará tiempo y no siempre es necesario, debido a su tamaño cambio que puede lograr a través de los atributos css, en cuyo caso no vuelve a dibujar el lienzo.

veo 4 casos de lo que es posible que desee pasar en cambiar el tamaño de la ventana (todo a partir de un lienzo en pantalla completa)

1: desea que el ancho de permanecer 100%, y desea que la relación de aspecto para quedarse como era. En ese caso, no necesita volver a dibujar el lienzo; ni siquiera necesita un controlador de cambio de tamaño de ventana. Todo lo que necesita es

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

donde ctx es su contexto de lienzo. violín: resizeByWidth

2: quiere que el ancho y el alto permanezcan al 100%, y desea que el cambio resultante en la relación de aspecto tenga el efecto de una imagen estirada. Ahora, todavía no necesita volver a dibujar el lienzo, pero necesita un controlador de cambio de tamaño de ventana. En el controlador, lo hace

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

violín: messWithAspectratio

3: desea anchura y la altura a la vez permanecer 100%, pero la respuesta al cambio en la relación de aspecto es algo diferente de la extensión de la imagen. Luego debe volver a dibujar, y hágalo de la forma que se describe en la respuesta aceptada.

violín: redraw

4: desea que la anchura y la altura para ser el 100% de la carga de la página, pero se mantenga constante a partir de entonces (sin reacción al cambio de tamaño de ventana

violín:. fixed

Todos Los violines tienen un código idéntico, excepto la línea 63 donde está configurado el modo. También puede copiar el código del violín para ejecutar en su máquina local, en cuyo caso puede seleccionar el modo mediante un argumento querystring, como? mode = redraw

+0

fyi: '$ (ctx.canvas) .css (" ancho "," 100% ");' es equivalente a '$ (canvas) .css ("ancho", "100%"); '(el lienzo del contexto es solo el lienzo) –

8

Estaba buscando encontrar la respuesta a esta pregunta también, pero la respuesta aceptada se estaba rompiendo para mí. Al parecer, usar window.innerWidth no es portátil. Funciona en algunos navegadores, pero noté que a Firefox no le gustó.

Gregg Tavares publicado un gran recurso aquí que soluciona este problema directamente: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (Ver anti-patrón # 's 3 y 4).

Uso de canvas.clientWidth en lugar de window.innerWidth parece funcionar muy bien.

Aquí es Gregg sugirió render bucle:

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