Come posso ridimensionare automaticamente l' <canvas>
elemento HTML5 per adattarlo alla pagina?
Ad esempio, posso ottenere un <div>
ridimensionamento impostando le proprietà height
e width
su 100%, ma un <canvas>
non ridimensionerà, vero?
Come posso ridimensionare automaticamente l' <canvas>
elemento HTML5 per adattarlo alla pagina?
Ad esempio, posso ottenere un <div>
ridimensionamento impostando le proprietà height
e width
su 100%, ma un <canvas>
non ridimensionerà, vero?
Risposte:
Credo di aver trovato una soluzione elegante a questo:
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: 0;
}
Finora non ha avuto alcun impatto negativo sulle prestazioni per me.
body, html { margin: 0px;}
La seguente soluzione ha funzionato per me al meglio. Dato che sono relativamente nuovo nella programmazione, mi piace avere la conferma visiva che qualcosa sta funzionando come mi aspetto. L'ho trovato sul seguente sito: http://htmlcheats.com/html/resize-the-html5-canvas-dyamically/
Ecco il codice:
<!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>
Il bordo blu mostra il bordo della tela di ridimensionamento ed è sempre lungo il bordo della finestra, visibile su tutti e 4 i lati, il che NON era il caso di alcune delle altre risposte sopra. Spero che sia d'aiuto.
overflow: hidden
e display: block
è quello che mi mancava per farlo funzionare correttamente.
Fondamentalmente quello che devi fare è legare l'evento onresize al tuo corpo, una volta catturato l'evento devi solo ridimensionare la tela usando window.innerWidth e 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>
L'impostazione della larghezza e dell'altezza dello spazio delle coordinate del canvas in base alle dimensioni del client del browser richiede il ridimensionamento e il ridisegno ogni volta che il browser viene ridimensionato.
Una soluzione meno complicata consiste nel mantenere le dimensioni disegnabili nelle variabili Javascript, ma impostare le dimensioni della tela in base alle dimensioni screen.width, screen.height. Usa CSS per adattarsi:
#containingDiv {
overflow: hidden;
}
#myCanvas {
position: absolute;
top: 0px;
left: 0px;
}
La finestra del browser in genere non sarà mai più grande dello schermo stesso (tranne nei casi in cui la risoluzione dello schermo è dichiarata in modo errato, come potrebbe essere con due monitor non corrispondenti), quindi lo sfondo non verrà visualizzato e le proporzioni dei pixel non varieranno. I pixel dell'area di disegno saranno direttamente proporzionali alla risoluzione dello schermo a meno che non si utilizzi CSS per ridimensionare l'area di disegno.
Un approccio CSS puro che si aggiunge alla soluzione di @jerseyboy sopra.
Funziona con Firefox (testato nella v29), Chrome (testato nella v34) e Internet Explorer (testato nella 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>
Link all'esempio: http://temporaer.net/open/so/140502_canvas-fit-to-window.html
Ma fai attenzione, come afferma @jerseyboy nel suo commento:
Il ridimensionamento della tela con CSS è problematico. Almeno su Chrome e Safari, le posizioni degli eventi mouse / touch non corrisponderanno a 1: 1 con le posizioni dei pixel dell'area di disegno e dovrai trasformare i sistemi di coordinate.
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);
A meno che tu non voglia che la tela esegua l'upscaling automatico dei dati delle tue immagini (è di questo che parla la risposta di James Black, ma non sembrerà carina), devi ridimensionarla da te e ridisegnare l'immagine. Centrare una tela
Se il tuo div ha riempito completamente la pagina web, puoi riempire quel div e quindi avere una tela che riempie il div.
Potresti trovare questo interessante, poiché potresti aver bisogno di usare un css per usare la percentuale, ma dipende dal browser che stai usando e da quanto è in accordo con le specifiche: http://www.whatwg.org/ spec / web-apps / corrente-lavoro / multipagina / the-tele-element.html # the-tele-elemento
Le dimensioni intrinseche dell'elemento canvas equivalgono alla dimensione dello spazio delle coordinate, con i numeri interpretati in pixel CSS. Tuttavia, l'elemento può essere dimensionato arbitrariamente da un foglio di stile. Durante il rendering, l'immagine viene ridimensionata per adattarsi alle dimensioni del layout.
Potrebbe essere necessario ottenere offsetWidth e l'altezza del div, oppure ottenere l'altezza / larghezza della finestra e impostarlo come valore in pixel.
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();
});
Se sei interessato a preservare le proporzioni e farlo con CSS puro (date le proporzioni) puoi fare qualcosa come sotto. La chiave è l' padding-bottom
sulla ::content
elemento che ridimensiona l' container
elemento. Questo è dimensionato rispetto alla larghezza del suo genitore, che è 100%
di default. Il rapporto qui specificato deve corrispondere al rapporto delle dimensioni canvas
sull'elemento.
// 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>
Utilizzando jQuery è possibile tenere traccia del ridimensionamento della finestra e modificare la larghezza della tela utilizzando anche jQuery.
Qualcosa del genere
$( 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;">
(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();
});
}());
Penso che sia esattamente ciò che dovremmo fare: 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);
Sto usando sketch.js, quindi dopo aver eseguito il comando init per la tela, cambio larghezza e altezza con jquery. Basa le dimensioni sull'elemento padre.
$ ( '# DrawCanvas'). Schizzo (). Attr ( 'height', $ ( '# DrawCanvas'). Genitore (). Altezza ()). Attr ( 'width', $ ( '# DrawCanvas'). Genitore ().larghezza());