w3school - javascript draw graphics




Ridimensiona il canvas HTML5 per adattarlo alla finestra (10)

Come posso ridimensionare automaticamente l'elemento <canvas> HTML5 per adattarlo alla pagina?

Ad esempio, posso ottenere un <div> in scala impostando le proprietà height e width su 100%, ma un <canvas> non verrà ridimensionato, vero?


A meno che tu non voglia che la tela migliori automaticamente i dati dell'immagine (questo è ciò di cui parla la risposta di James Black, ma non sembrerà carina), devi ridimensionarla da te e ridisegnare l'immagine. Centrare una tela


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: 0px;
}

Per ora non ho avuto grandi impatti negativi sulle prestazioni.


Impostando la larghezza e l'altezza dello spazio delle coordinate del canvas in base alle dimensioni del browser, è necessario ridimensionare e ridisegnare ogni volta che il browser viene ridimensionato.

Una soluzione meno complessa è quella di mantenere le dimensioni disegnabili nelle variabili Javascript, ma impostare le dimensioni del canvas in base alle dimensioni schermo.width, schermo.altezza. Usa i CSS per adattarli:

#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 dove la risoluzione dello schermo è erroneamente riportata, come potrebbe essere con due monitor non corrispondenti), quindi lo sfondo non verrà mostrato e le proporzioni dei pixel non varieranno. I pixel della tela saranno direttamente proporzionali alla risoluzione dello schermo, a meno che non si usi CSS per ridimensionare la tela.


La seguente soluzione ha funzionato per me al meglio. Dato che sono relativamente nuovo alla programmazione, mi piace avere conferma visiva che qualcosa sta funzionando nel modo in cui 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 e si trova sempre lungo il bordo della finestra, visibile su tutti e 4 i lati, cosa che NON era il caso per alcune delle altre risposte precedenti. Spero che sia d'aiuto.


Se il tuo div completamente riempito la pagina Web, allora è possibile riempire quel div e quindi avere una tela che riempie il div.

Potresti trovare interessante questo dato che potresti dover usare un css per usare la percentuale, ma dipende da quale browser stai usando e quanto è in accordo con le specifiche: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#the-canvas-element

Le dimensioni intrinseche dell'elemento canvas equivalgono alle dimensioni dello spazio delle coordinate, con i numeri interpretati nei pixel CSS. Tuttavia, l'elemento può essere dimensionato arbitrariamente da un foglio di stile. Durante il rendering, l'immagine viene ridimensionata per adattarsi a questa dimensione del layout.

Potrebbe essere necessario ottenere l'offset Larghezza e altezza del div o ottenere l'altezza / larghezza della finestra e impostarlo come valore del pixel.


Se sei interessato a preservare le proporzioni e farlo in puro CSS (date le proporzioni) puoi fare qualcosa di simile qui sotto. La chiave è il padding-bottom sull'elemento ::content che dimensiona l'elemento container . Questo è dimensionato rispetto alla larghezza del suo genitore, che è 100% di default. Il rapporto specificato qui deve corrispondere al rapporto delle dimensioni sull'elemento 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>


Un approccio CSS puro che aggiunge alla soluzione di @jerseyboy sopra.
Funziona in Firefox (testato in v29), Chrome (testato in v34) e Internet Explorer (testato in 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 attenzione, come dice @jerseyboy nel suo commento:

Riscalare la tela con i CSS è problematico. Almeno su Chrome e Safari, le posizioni degli eventi mouse / tocco non corrisponderanno a 1: 1 con le posizioni dei pixel della tela e dovrai trasformare i sistemi di coordinate.


Usando jQuery puoi seguire il ridimensionamento della finestra e cambiare la larghezza della tua tela usando 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();
    });

}());

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




canvas