480 votes

Redimensionner le canevas HTML5 pour l'adapter à la fenêtre

Comment puis-je mettre automatiquement à l'échelle l'image HTML5 <canvas> pour s'adapter à la page ?

Par exemple, je peux obtenir un <div> à l'échelle en définissant le height y width à 100%, mais une <canvas> ne s'adaptera pas, n'est-ce pas ?

8 votes

Pourquoi canvas{width:100%;height:100%} ne fonctionne pas ?

46 votes

@zloctb - Cela augmente directement la taille de la toile, ce qui étire votre image.

14 votes

Voir le Principes fondamentaux de WebGL pour une explication détaillée de ce qu'il faut faire et ne pas faire pour les questions connexes.

427voto

devyn Points 2704

Je crois avoir trouvé une solution élégante à ce problème :

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, il n'y a pas eu d'impact négatif important sur les performances.

0 votes

Vous pouvez également régler cette fonction sur un intervalle distinct si vous le souhaitez.

0 votes

J'ai essayé et j'obtiens systématiquement des barres de défilement. J'ai vérifié la largeur de mon élément de fichier html (dans la console, en regardant le style calculé) et c'est toujours quelques pixels de moins que ce que renvoie window.innerWidth. Avez-vous une idée ?

7 votes

Vous devez probablement désactiver la marge avec body, html { margin: 0px;}

21voto

equiman Points 365

Ce que vous devez faire, c'est lier l'événement onresize à votre corps. Une fois l'événement capté, il vous suffit de redimensionner le canevas en utilisant 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>

1 votes

Vous pourriez simplement utiliser un écouteur d'événements.

0 votes

Il y a des marges et des barres de défilement, et vous devez redimensionner l'écran avant qu'il n'agisse.

0 votes

Que se passe-t-il si le canevas est plus grand que la fenêtre d'affichage (lorsque la fenêtre d'affichage est plus étroite ou plus courte) ? Cette solution ne semble pas gérer ce problème.

19voto

jerseyboy Points 515

Le fait de définir la largeur et la hauteur de l'espace de coordonnées du canevas en fonction des dimensions du client du navigateur vous oblige à redimensionner et à redessiner chaque fois que le navigateur est redimensionné.

Une solution moins compliquée consiste à conserver les dimensions du dessin dans des variables Javascript, mais à définir les dimensions de la toile en fonction des dimensions screen.width, screen.height. Utilisez le CSS pour l'adapter :

#containingDiv { 
  overflow: hidden;
}
#myCanvas {
  position: absolute; 
  top: 0px;
  left: 0px;
} 

En général, la fenêtre du navigateur ne sera jamais plus grande que l'écran lui-même (sauf si la résolution de l'écran est mal indiquée, comme cela peut être le cas avec des moniteurs doubles non adaptés), de sorte que l'arrière-plan n'apparaîtra pas et que les proportions des pixels ne varieront pas. Les pixels du canevas seront directement proportionnels à la résolution de l'écran, à moins que vous n'utilisiez une feuille de style en cascade pour mettre le canevas à l'échelle.

8 votes

Le redimensionnement du canevas à l'aide de CSS pose problème. Au moins sur Chrome et Safari, les positions des événements souris/touche ne correspondent pas 1:1 aux positions des pixels du canevas, et vous devrez transformer les systèmes de coordonnées.

14voto

petr Points 190
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);

1 votes

Joli, quand le rapport est important

8voto

Nickolay Points 14384

À moins que vous ne souhaitiez que le canevas augmente automatiquement la taille de vos données d'image (c'est ce dont parle la réponse de James Black, mais ce n'est pas très joli), vous devez les redimensionner vous-même et redessiner l'image. Centrer une toile

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X