Redimensionner la toile HTML5 pour l'adapter à la fenêtre

comment adapter automatiquement l'élément HTML5 <canvas> à la page?

par exemple, je peux obtenir un <div> à l'échelle en réglant les propriétés height et width à 100%, mais un <canvas> ne sera pas à l'échelle, n'est-ce pas?

347
demandé sur shekhar 2009-11-03 05:02:07

14 réponses

je crois avoir trouvé une solution élégante à cela:

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;
}

N'a pas eu d'impact négatif sur mes performances jusqu'à présent.

328
répondu devyn 2010-06-20 06:43:09

la solution suivante a fonctionné pour moi le mieux. Puisque je suis relativement nouveau au codage, j'aime avoir la confirmation visuelle que quelque chose fonctionne de la façon dont je m'y attends. 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>

le bord bleu vous montre le bord de la toile redimensionnée, et est toujours le long du bord de la fenêtre, visible sur les 4 côtés, ce qui n'était PAS le cas pour certaines autres réponses ci-dessus. Espérons que cela aide.

44
répondu Craig Morrison 2016-08-12 12:17:56

fondamentalement, ce que vous devez faire est de lier l'événement onresize à votre corps, une fois que vous attrapez l'événement, vous avez juste besoin de redimensionner la toile en utilisant la fenêtre.innerWidth et de la fenêtre.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>
20
répondu equiman 2011-09-08 22:18:59

la définition de la largeur et de la hauteur de l'espace de coordonnées canvas en fonction des dimensions du client navigateur exige que vous redimensionniez et retraciez chaque fois que le navigateur est redimensionné.

une solution moins alambiquée consiste à maintenir les dimensions dessinables dans les variables Javascript, mais à définir les dimensions de la toile en fonction de l'écran.largeur de l'écran.dimensions de hauteur. Utiliser 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 le l'écran lui-même (sauf si la résolution de l'écran est mal rapportée, comme il pourrait l'être avec les moniteurs doubles non-appariés), de sorte que l'arrière-plan ne s'affichera pas et les proportions de pixels ne varieront pas. Les pixels de la toile seront directement proportionnels à la résolution de l'écran à moins que vous n'utilisiez CSS pour dimensionner la toile.

18
répondu jerseyboy 2011-12-01 14:39:11

a pur CSS ajouter à la solution de @jerseyboy ci-dessus.

Fonctionne avec 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 soin, comme @jerseyboy le dit dans son commentaire:

Le réajustement de la toile avec CSS est gênant. Au moins sur Chrome et Les positions Safari, mouse/touch event ne correspondront pas 1:1 avec position des pixels sur la toile, et vous devrez transformer les coordonnées système.

10
répondu Volker E. 2016-09-05 06:32:37

à moins que vous ne vouliez que la toile fasse une mise à niveau automatique de vos données d'image (C'est ce dont parle la réponse de James Black, mais elle ne sera pas jolie), vous devez la redimensionner vous-même et redessiner l'image. centrage d'une toile

8
répondu Nickolay 2017-05-23 12:34:53
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);
8
répondu Petr 2013-10-16 09:59:10

si votre div a complètement rempli la page web, alors vous pouvez remplir cette div et avoir une toile qui remplit la div.

, Vous pouvez trouver cela intéressant, car vous pourriez avoir besoin d'utiliser un css à utiliser un pourcentage, mais, cela dépend du navigateur que vous utilisez, et combien il est en accord avec la spécification: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#the-canvas-element

les dimensions intrinsèques de la toile élément égal à la taille du espace de coordonnées, les numéros de interprété en pixels CSS. Cependant, l'élément peut être dimensionné arbitrairement par une feuille de style. Lors du rendu, l'image est adaptée à cette mise en page taille.

vous pouvez avoir besoin d'obtenir la largeur de décalage et la hauteur de la div, ou d'obtenir la hauteur/largeur de la fenêtre et de définir que la valeur du pixel.

4
répondu James Black 2009-11-03 02:29:18

si vous êtes intéressé à préserver les rapports d'aspect et le faire dans CSS pur (étant donné le rapport d'aspect) vous pouvez faire quelque chose comme ci-dessous. La clé est le padding-bottom sur l'élément ::content qui mesure l'élément container . Elle est dimensionnée 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>
3
répondu mrmcgreg 2016-08-12 12:05:03

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();
});
2
répondu Martin Wantke 2014-11-28 16:39:05
(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();
    });

}());
1
répondu lokers 2014-03-25 17:41:37

en utilisant jQuery vous pouvez suivre la redimensionnement de la fenêtre et changer la largeur de votre toile en utilisant jQuery aussi bien.

quelque chose comme ça

$( 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;">
1
répondu Rafael Andrade 2018-03-29 20:48:15

je pense que c'est ce que nous devrions faire exactement: 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);
0
répondu Arvind Bhardwaj 2014-01-04 04:31:11

j'utilise sketch.js donc après avoir exécuté la commande init pour la toile, je change la largeur et la hauteur avec jquery. Il fonde les dimensions sur l'élément parent.

$('#DrawCanvas').esquisse.)(attr ('height',$('#DrawCanvas')).parent.)(hauteur.))(attr ('width',$('#DrawCanvas')).parent.)(largeur ());

-2
répondu moeiscool 2015-01-06 05:43:04