Comment puis-je redimensionner automatiquement l'élément HTML5 <canvas>
pour l'adapter à la page?
Par exemple, je peux obtenir un <div>
à l'échelle en définissant les propriétés height
et width
à 100%, mais un <canvas>
ne sera pas mis à l'échelle, n'est-ce pas?
Je crois avoir trouvé une solution élégante à ceci:
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;
}
Jusqu'à présent, cela n'a eu aucun impact négatif important sur les performances.
La solution suivante a fonctionné pour moi le meilleur. Étant donné que je suis relativement nouveau en codage, j'aime bien avoir la confirmation visuelle que quelque chose fonctionne comme je le souhaite. Je l'ai trouvé sur le site suivant: http://htmlcheats.com/html/resize-the-html5-canvas-dyamically/
Voici le code:
<!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>
La bordure bleue indique le bord du canevas en cours de redimensionnement et se trouve toujours le long du bord de la fenêtre, visible sur les 4 côtés, ce qui n'était PAS le cas de certaines des réponses précédentes. J'espère que ça aide.
Fondamentalement, ce que vous devez faire est de lier l'événement onresize à votre corps. Une fois que vous l'avez saisi, il vous suffit de redimensionner la toile à l'aide de window.innerWidth et 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>
Pour définir la largeur et la hauteur de l'espace de coordonnées de la zone de dessin en fonction des dimensions du client du navigateur, vous devez redimensionner et redessiner chaque fois que le navigateur est redimensionné.
Une solution moins compliquée consiste à conserver les dimensions pouvant être dessinées dans les variables Javascript, mais à définir les dimensions de la zone de travail en fonction des dimensions screen.width, screen.height. Utilisez CSS pour s'adapter:
#containingDiv {
overflow: hidden;
}
#myCanvas {
position: absolute;
top: 0px;
left: 0px;
}
La fenêtre du navigateur ne sera généralement jamais plus grande que l’écran lui-même (sauf dans les cas où la résolution de l’écran est mal rapportée, comme cela pourrait être le cas avec deux moniteurs non appariés), ainsi l’arrière-plan ne sera pas affiché et les proportions en pixels ne varieront pas. Les pixels de la toile seront directement proportionnels à la résolution de l'écran, sauf si vous utilisez CSS pour redimensionner la toile.
Une approche pure CSS s'ajoutant à la solution de @jerseyboy ci-dessus.
Fonctionne dans Firefox (testé en v29), Chrome (testé en v34) et Internet Explorer (testé 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>
Lien vers l'exemple: http://temporaer.net/open/so/140502_canvas-fit-to-window.html
Mais prenez garde, comme le dit @jerseyboy dans son commentaire:
Le redimensionnement de la toile avec CSS est gênant. Au moins sur Chrome et Les positions Safari, souris/événement tactile ne correspondront pas 1: 1 à positions de pixel de la toile, et vous devrez transformer la coordonnée systèmes.
À moins que vous souhaitiez que la zone de dessin optimise automatiquement les données de votre image (c'est ce que dit la réponse de James Black, mais cela ne sera pas joli), vous devez le redimensionner vous-même et redessiner l'image. Centrer une toile
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);
Si votre div remplit complètement la page Web, vous pourrez alors remplir cette div et disposer ainsi d'un canevas remplissant la div.
Cela peut vous intéresser, car vous devrez peut-être utiliser un CSS pour utiliser un pourcentage, mais cela dépend du navigateur que vous utilisez et de son degré d’accord avec la spécification: http: // www .whatwg.org/specs/applications-Web/travail-actuel/multipage/the-canvas-element.html # the-canvas-element
Les dimensions intrinsèques de la toile élément égal à la taille de la espace de coordonnées, avec les nombres interprété en pixels CSS. Toutefois, l'élément peut être dimensionné de manière arbitraire par une feuille de style. Pendant le rendu, l'image est redimensionnée pour s'adapter à cette présentation Taille.
Vous devrez peut-être obtenir l'offsetWidth et la hauteur de la div ou la hauteur/largeur de la fenêtre et la définir comme valeur de pixel.
Si vous souhaitez conserver les proportions et le faire en CSS pur (compte tenu des proportions), vous pouvez procéder comme suit. La clé est le padding-bottom
sur l'élément ::content
qui dimensionne l'élément container
. Ceci est dimensionné par rapport à la largeur de son parent, qui est 100%
par défaut. Le rapport spécifié ici doit correspondre au rapport des tailles sur l'élément 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>
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();
});
}());
Premièrement, vous ne pouvez pas utiliser les attributs width et height pour changer la taille (du moins à ma façon) car cela la casse. Vous pouvez faire ceci: HTML:
<canvas id = 'myCanvas'></canvas>
JS:
var canvas = document.getElementById('myCanvas');
var W = window.innerWidth;
var H = window.innerHeight;
canvas.width = W;
canvas.height = H;
(S'il vous plaît pardonnez-moi pour les fautes de frappe, j'ai tendance à le faire beaucoup)
Avec jQuery, vous pouvez suivre le redimensionnement de la fenêtre et modifier la largeur de votre toile à l’aide de jQuery.
Quelque chose comme ca
$( 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;">
Je pense que c'est exactement ce que nous devrions faire: http://www.html5rocks.com/fr/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);