javascript - ejemplos - Redimensionar el lienzo HTML5 para que se ajuste a la ventana
create canvas javascript (14)
¿Cómo puedo escalar automáticamente el elemento HTML5 <canvas>
para que se ajuste a la página?
Por ejemplo, puedo obtener un <div>
para escalar estableciendo las propiedades de height
y width
en 100%, pero un <canvas>
no escalará, ¿verdad?
A menos que desee que el lienzo amplíe sus datos de imagen automáticamente (de eso se trata la respuesta de James Black, pero no se verá bonita), debe cambiar el tamaño usted mismo y volver a dibujar la imagen. Centrando un lienzo
Básicamente, lo que tiene que hacer es vincular el evento onresize a su cuerpo, una vez que detecte el evento, solo necesita cambiar el tamaño del lienzo utilizando window.innerWidth y window.innerHeight.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Canvas Resize</title>
<script type="text/javascript">
function resize_canvas(){
canvas = document.getElementById("canvas");
if (canvas.width < window.innerWidth)
{
canvas.width = window.innerWidth;
}
if (canvas.height < window.innerHeight)
{
canvas.height = window.innerHeight;
}
}
</script>
</head>
<body onresize="resize_canvas()">
<canvas id="canvas">Your browser doesn''t support canvas</canvas>
</body>
</html>
Con jQuery, puede hacer un seguimiento del tamaño de la ventana y cambiar el ancho de su lienzo utilizando jQuery también.
Algo como eso
$( window ).resize(function() {
$("#myCanvas").width($( window ).width())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">
Creo que esto es lo que deberíamos hacer exactamente: http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/
function resizeGame() {
var gameArea = document.getElementById(''gameArea'');
var widthToHeight = 4 / 3;
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
var newWidthToHeight = newWidth / newHeight;
if (newWidthToHeight > widthToHeight) {
newWidth = newHeight * widthToHeight;
gameArea.style.height = newHeight + ''px'';
gameArea.style.width = newWidth + ''px'';
} else {
newHeight = newWidth / widthToHeight;
gameArea.style.width = newWidth + ''px'';
gameArea.style.height = newHeight + ''px'';
}
gameArea.style.marginTop = (-newHeight / 2) + ''px'';
gameArea.style.marginLeft = (-newWidth / 2) + ''px'';
var gameCanvas = document.getElementById(''gameCanvas'');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
}
window.addEventListener(''resize'', resizeGame, false);
window.addEventListener(''orientationchange'', resizeGame, false);
Creo que he encontrado una solución elegante para esto:
JavaScript
/* important! for alignment, you should make things
* relative to the canvas'' current width/height.
*/
function draw() {
var ctx = (a canvas context);
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
//...drawing code...
}
CSS
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
No ha tenido ningún gran impacto negativo en el rendimiento para mí, hasta ahora.
Estoy usando sketch.js, así que después de ejecutar el comando init para el lienzo, cambio el ancho y la altura con jquery. Basa las dimensiones en el elemento padre.
$ (''# DrawCanvas''). Sketch (). Attr (''height'', $ (''# DrawCanvas''). Parent (). Height ()). Attr (''width'', $ (''# DrawCanvas''). Parent ().anchura());
La configuración del ancho y la altura del espacio de coordenadas del lienzo según las dimensiones del cliente del navegador requiere que cambie el tamaño y vuelva a dibujar cada vez que se cambie el tamaño del navegador.
Una solución menos complicada es mantener las dimensiones dibujables en las variables de Javascript, pero establecer las dimensiones del lienzo según el ancho de pantalla, las dimensiones de pantalla y altura. Usa CSS para encajar:
#containingDiv {
overflow: hidden;
}
#myCanvas {
position: absolute;
top: 0px;
left: 0px;
}
Por lo general, la ventana del navegador nunca será más grande que la pantalla en sí misma (excepto cuando la resolución de la pantalla no se informa correctamente, ya que podría ser con monitores duales no coincidentes), por lo que el fondo no se mostrará y las proporciones de píxeles no variarán. Los píxeles del lienzo serán directamente proporcionales a la resolución de la pantalla a menos que use CSS para escalar el lienzo.
La siguiente solución me funcionó mejor. Como soy relativamente nuevo en la codificación, me gusta tener una confirmación visual de que algo está funcionando de la manera que espero. Lo encontré en el siguiente sitio: http://htmlcheats.com/html/resize-the-html5-canvas-dyamically/
Aquí está el código:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Resize HTML5 canvas dynamically | www.htmlcheats.com</title>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0px;
border: 0;
overflow: hidden; /* Disable scrollbars */
display: block; /* No floating content on sides */
}
</style>
</head>
<body>
<canvas id=''c'' style=''position:absolute; left:0px; top:0px;''>
</canvas>
<script>
(function() {
var
// Obtain a reference to the canvas element using its id.
htmlCanvas = document.getElementById(''c''),
// Obtain a graphics context on the canvas element for drawing.
context = htmlCanvas.getContext(''2d'');
// Start listening to resize events and draw canvas.
initialize();
function initialize() {
// Register an event listener to call the resizeCanvas() function
// each time the window is resized.
window.addEventListener(''resize'', resizeCanvas, false);
// Draw canvas border for the first time.
resizeCanvas();
}
// Display custom canvas. In this case it''s a blue, 5 pixel
// border that resizes along with the browser window.
function redraw() {
context.strokeStyle = ''blue'';
context.lineWidth = ''5'';
context.strokeRect(0, 0, window.innerWidth, window.innerHeight);
}
// Runs each time the DOM window resize event fires.
// Resets the canvas dimensions to match window,
// then draws the new borders accordingly.
function resizeCanvas() {
htmlCanvas.width = window.innerWidth;
htmlCanvas.height = window.innerHeight;
redraw();
}
})();
</script>
</body>
</html>
El borde azul le muestra el borde del lienzo de cambio de tamaño, y siempre está a lo largo del borde de la ventana, visible en los 4 lados, lo que NO fue el caso de algunas de las otras respuestas anteriores. Espero eso ayude.
Si está interesado en conservar las relaciones de aspecto y hacerlo en CSS puro (dada la relación de aspecto), puede hacer algo como a continuación. La clave es la padding-bottom
en el elemento ::content
que dimensiona el elemento container
. Este tamaño tiene un tamaño relativo al ancho de su padre, que es 100%
por defecto. La relación especificada aquí tiene que coincidir con la relación de los tamaños en el elemento del canvas
.
// Javascript
var canvas = document.querySelector(''canvas''),
context = canvas.getContext(''2d'');
context.fillStyle = ''#ff0000'';
context.fillRect(500, 200, 200, 200);
context.fillStyle = ''#000000'';
context.font = ''30px serif'';
context.fillText(''This is some text that should not be distorted, just scaled'', 10, 40);
/*CSS*/
.container {
position: relative;
background-color: green;
}
.container::after {
content: '' '';
display: block;
padding: 0 0 50%;
}
.wrapper {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
canvas {
width: 100%;
height: 100%;
}
<!-- HTML -->
<div class=container>
<div class=wrapper>
<canvas width=1200 height=600></canvas>
</div>
</div>
Si su div llenó completamente la página web, puede rellenar ese div y así tener un lienzo que rellene el div.
Puede que esto le resulte interesante, ya que puede necesitar usar un css para usar el porcentaje, pero depende del navegador que esté usando y de cuánto esté de acuerdo con la especificación: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#the-canvas-element
Las dimensiones intrínsecas del elemento del lienzo son iguales al tamaño del espacio de coordenadas, con los números interpretados en píxeles CSS. Sin embargo, el elemento puede dimensionarse arbitrariamente por una hoja de estilo. Durante el renderizado, la imagen se escala para adaptarse a este tamaño de diseño.
Es posible que deba obtener el ancho y la altura del div divisor, u obtener el alto / ancho de la ventana y establecerlo como el valor de píxel.
Un enfoque de CSS puro que se agrega a la solución de @jerseyboy anterior.
Funciona en Firefox (probado en v29), Chrome (probado en v34) e Internet Explorer (probado en v11).
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
canvas {
background-color: #ccc;
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById(''canvas'');
if (canvas.getContext) {
var ctx = canvas.getContext(''2d'');
ctx.fillRect(25,25,100,100);
ctx.clearRect(45,45,60,60);
ctx.strokeRect(50,50,50,50);
}
</script>
</body>
</html>
Enlace al ejemplo: http://temporaer.net/open/so/140502_canvas-fit-to-window.html
Pero cuídate, como lo dice @jerseyboy en su comentario:
Volver a escalar el lienzo con CSS es problemático. Al menos en Chrome y Safari, las posiciones de eventos de mouse / toque no corresponderán 1: 1 con las posiciones de píxeles de lienzo, y tendrá que transformar los sistemas de coordenadas.
CSS
body { margin: 0; }
canvas { display: block; }
JavaScript
window.addEventListener("load", function()
{
var canvas = document.createElement(''canvas''); document.body.appendChild(canvas);
var context = canvas.getContext(''2d'');
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(0, 0); context.lineTo(canvas.width, canvas.height);
context.moveTo(canvas.width, 0); context.lineTo(0, canvas.height);
context.stroke();
}
function resize()
{
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
draw();
}
window.addEventListener("resize", resize);
resize();
});
(function() {
// get viewport size
getViewportSize = function() {
return {
height: window.innerHeight,
width: window.innerWidth
};
};
// update canvas size
updateSizes = function() {
var viewportSize = getViewportSize();
$(''#myCanvas'').width(viewportSize.width).height(viewportSize.height);
$(''#myCanvas'').attr(''width'', viewportSize.width).attr(''height'', viewportSize.height);
};
// run on load
updateSizes();
// handle window resizing
$(window).on(''resize'', function() {
updateSizes();
});
}());
function resize() {
var canvas = document.getElementById(''game'');
var canvasRatio = canvas.height / canvas.width;
var windowRatio = window.innerHeight / window.innerWidth;
var width;
var height;
if (windowRatio < canvasRatio) {
height = window.innerHeight;
width = height / canvasRatio;
} else {
width = window.innerWidth;
height = width * canvasRatio;
}
canvas.style.width = width + ''px'';
canvas.style.height = height + ''px'';
};
window.addEventListener(''resize'', resize, false);