2011-08-24 1 views
10

L'elemento HTML5 <canvas> non accetta le dimensioni relative (percentuale) per le sue proprietà width e height.Ridimensionamento relativo HTML Canvas

Quello che sto cercando di realizzare è avere il mio quadro relativo alla finestra. Questo è ciò che mi è venuta in mente finora, ma mi chiedo se c'è un modo migliore che è:

  1. Più semplice
  2. Non richiede avvolgendo il <canvas> in un <div>.
  3. Non dipende da jQuery (lo uso per ottenere la larghezza/altezza del div genitore)
  4. Idealmente, non ridisegnare il navigatore di ridimensionamento (ma credo che potrebbe essere un requisito)

Vedi sotto per il codice, che disegna un cerchio al centro dello schermo, il 40% di larghezza fino a un massimo di 400 pixel.

demo dal vivo: http://jsbin.com/elosil/2

Codice:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Canvas of relative width</title> 
    <style> 
     body { margin: 0; padding: 0; background-color: #ccc; } 
     #relative { width: 40%; margin: 100px auto; height: 400px; border: solid 4px #999; background-color: White; } 
    </style> 
    <script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
    <script> 
     function draw() { 
      // draw a circle in the center of the canvas 
      var canvas = document.getElementById('canvas'); 
      var relative = document.getElementById('relative'); 
      canvas.width = $(relative).width(); 
      canvas.height = $(relative).height(); 
      var w = canvas.width; 
      var h = canvas.height; 
      var size = (w > h) ? h : w; // set the radius of the circle to be the lesser of the width or height; 
      var ctx = canvas.getContext('2d'); 
      ctx.beginPath(); 
      ctx.arc(w/2, h/2, size/2, 0, Math.PI * 2, false); 
      ctx.closePath(); 
      ctx.fill(); 
     } 

     $(function() { 
      $(window).resize(draw); 
     }); 
    </script> 
</head> 
<body onload="draw()"> 
    <div id="relative"> 
     <canvas id="canvas"></canvas> 
    </div> 
</body> 
</html> 

risposta

14

La tela width e height attributi sono separati da width e height stili della stessa tela. Gli attributi width e height sono le dimensioni della superficie di rendering della tela, in pixel, mentre i relativi stili scelgono una posizione nel documento in cui il browser deve disegnare il contenuto dalla superficie di rendering. Accade solo che il valore predefinito per gli stili width e height, , se non specificato, sia la larghezza e l'altezza della superficie di rendering. Quindi hai ragione al primo posto: non c'è motivo di avvolgerlo in un div. Puoi impostare valori percentuali per tutti gli stili sul tuo elemento canvas, proprio come qualsiasi altro elemento.

Per # 3, è piuttosto semplice (e cross-browser) ottenere le dimensioni di cose con clientWidth e clientHeight, a condizione che non si stia utilizzando il riempimento sul proprio elemento canvas.

Ho codificato la versione leggermente semplificata here.

Per # 4, hai ragione di essere sfortunato. È possibile controllare prima di impostare larghezza e altezza e lasciare la tela da sola se non è necessario ridimensionarla, il che eliminerebbe alcuni dei ridisegni, ma non è possibile eliminarli tutti.

MODIFICA: Portman ha sottolineato che ho incasinato lo stile di centratura. Versione aggiornata here.

+0

Grazie. È interessante notare che sembra * che * sia necessario avvolgere un 'canvas' in un' div' se si vuole centrarlo. 'margine: 0 auto' non sembra centrare una tela come fa un div. – Portman

+1

@Portman No, puoi ancora. Ho appena dimenticato di mettere display: block nello stile canvas (il suo valore predefinito è inline-block, che non centra in questo modo). Risposta aggiornata con questa soluzione. – sethobrien

1

OK. Ecco la tecnica che ho usato per implementare lo stesso.

Supponiamo di avere l'altezza di tela = 400, per l'altezza della finestra = 480, e si desidera modificare l'altezza relativamente se l'altezza della finestra cambia in 640.

canvas = document.getElementById("canvas"); 
canvas.height=window.innerHeight*400/480; 

ps: Non inizializzare l'altezza della tela all'interno del tag html.

Utilizzare 'window.innerHeight' (che restituisce l'altezza della finestra del browser ..allo stesso modo 'window.innerWidth') qualsiasi dove si desidera calcolare le posizioni relative sulla finestra.

Spero che tu abbia ottenuto ciò di cui avevi bisogno.

5

Come detto da sethobrien un elemento canvas ha TWO coppie larghezza/altezza degli attributi.

  1. canvas.width/canvas.height sono circa la dimensione in pixel del buffer che contiene sarà il risultato di comandi di disegno.

  2. canvas.style.width/canvas.style.height sono circa le dimensioni utilizzate per mostrare l'oggetto canvas nella finestra del browser e possono essere in qualsiasi delle unità supportate da css.

È infatti possibile impostare canvas.width e canvas.height solo una volta, fare il disegno nella tela, impostando i parametri di dimensione stile in percentuale e poi dimenticare ridisegnare il contenuto tela. Ovviamente questo significa che il browser eseguirà il ridimensionamento come per un'immagine normale caricata dalla rete in modo che il risultato visibile mostri gli artefatti di ridimensionamento dei pixel.

È necessario ridisegnare il contenuto del canvas dopo il ridimensionamento dell'elemento canvas solo se si desidera ottenere risultati perfetti per i pixel.