PHP: una classe per disegnare un orologio analogico

Orologio analogico Questo è un piccolo esercizio per imparare ad utilizzare le funzioni per disegnare con le lbrerieGD di PHP. La classe Analogclock utilizza tali funzioni per generare un’immagine PNG che rappresenta un orologio analogico. Come valori di input vengono passati al costruttore la larghezza dell’immagine, e al metodo display() i valori dell’ora, dei minuti e dei secondi che si desidera rappresentare. Volendo dare un effetto dinamico all’immagine, si può ricorrere ad uno script Javascript che ricarica la pagina, o meglio la sola immagine, ogni secondo, fornendo i parametri di ora, minuti e secondi aggiornati. E’ possibile impostare la classe in modo da escludere dalla visualizzazione la lancetta dei secondi, la visualizzazione digitale e infine, prelevare direttamente l’orario del server. Il confronto fra le due modalità di funzionamento è visibile in questo esempio.

La rappresentazione delle lancette dell’orologio non presenta grosse difficoltà perché le coordinate dei punti di inizio e di fine della linea non sono altro che l’origine del cerchio che rappresenta il quadrante, e, rispettivamente il coseno e il seno dell’angolo della lancetta. Poichè l’origine dell’immagine (il punto x = 0, y = 0) è fissato in alto a sinistra, per prima cosa bisogna traslare la circonferenza di riferimento di Π + Π /2. Il secondo aspetto da tenere presente è che la nostra immagine è un quadrato nel quale è inscritto il cerchio che rappresenta il quadrante dell’orologio. Dunque il raggio della circonferenza è la metà del lato del quadrato.

Vediamo ad esempio il codice per disegnare la lancetta dei secondi:

1
2
3
4
5
6
7
8
9
10
// ....
$delta = M_PI + M_PI / 2 ;  
// 2Π / 60 = Π / 30 !
$delta += (M_PI * 1 / 30) * $seconds ;
// circle centre coordinates: x = radius, y = radius.
$newX0 = $radius + cos($delta) * $radius;
$newY0 = $radius + sin($delta) * $radius ;
// $img is the resourse image and $colorSec is the allocated line color
imageLine($img, $radius, $radius, $newX0, $newY0, $colorSec);
// ....

L’intero codice sorgente della classe è disponibile qui
Il pacchetto completo del file di esempio è scaricabile qui

Vediamo come utilizzare la classe in pratica, questo il codice del file che genera l’immagine PNG con alcune opzioni attivate:

1
<!--?php require_once('analogclock.php'); $myClock = new Analogclock; //client mode: (remove comments): //$actualHour = intval($_GET['hour']); //$actualMin = intval($_GET['min']); //$actualSec = intval($_GET['sec']); //$myClock-&gt;showSeconds(false); //$myClock-&gt;display($actualHour, $actualMin, $actualSec); //server mode: $myClock-&gt;setAutotime(true); $myClock-&gt;display(); ?-->

E questo invece è il codice della pagina html nella quale viene visualizzato l’orologio con un po’ di javascript per ricaricare l’immagine ogni secondo:

<script type="text/javascript">
<!-- Begin function reFresh() { //location.reload(true); var today = new Date(); document.images['myClock'].src = 'test.php?hour=' + today.getHours() + '&amp;min=' + today.getMinutes() + '&amp;sec=' + today.getSeconds(); } // 1 minute = 60000 milliseconds. window.setInterval("reFresh()",1000); // End -->
</script>
<h1>Prova orologio</h1>
<script type="text/javascript">
    var today = new Date();
    document.write("<img src='test.php?hour=" + today.getHours() + "&amp;min=" + today.getMinutes() + "&amp;sec=" + today.getSeconds() + "' name='myClock' alt='Server Clock'/>");      
  </script>

Anche se in modalità server non sarebbe necessario passare al file test.php la querystring con i valori di ora, minuti e secondi (in quanto abbiamo attivato autotime) in realtà questo ci serve a forzare il browser a ricaricare l’immagine invece di prenderla dalla cache.

Conclusioni:

Come ho accennato all’inizio, questo vuole essere soprattutto un esercizio. Alcuni esempi di orologi analogici lato client molto più accattivanti del mio si trovano qui: CoolClock – The Javascript Analog Clock che però utilizzano canvas che non è ancora ben supportato da tutti i browser.
Avendo maggiore dimestichezza con il PHP piuttosto che con Javascript, ho preferito costruire un orologio lato server, che può benissimo funzionare con l’orario del client. Rimangono inoltre tutti gli altri vantaggi di uno script lato server tra i quali quello della piena compatibilità con tutti i browser!

Riferimenti ed approfondimenti:


Mario Spada ha scritto:

Ho leggermente modificato il codice per visualizzare in maniera fluida il movimento della lancetta delle ore. Adesso non si verifica più lo scatto fra un’ora e l’altra, il passaggio è progressivo. Anche il pacchetto per il download è stato aggiornato.
07.07.08 19:28
Peppe ha scritto:

Ciao! Perché nella barra del titolo mi fa il caricamento della pagina? Vorrei eliminarlo…
30.09.08 18:36
Mario Spada ha scritto:

Il caricamento che si nota sulla barra è inevitabile con javascript, perché è necessario ricaricare l’immagine (che è il risultato di uno script php) ogni secondo in modo da rendere efficacemente la lancetta dei secondi. L’unica cosa che mi viene in mente per ridurre l’effetto è quello di utilizzare la tecnologia AJAX.
07.10.08 19:39
Luca ha scritto:

Ciao sto utilizzando l’orologio ma noto che lo sfondo e’ bianco e quadrato c’e’ un modo per farlo diventare un cerchio o in alternativa avere lo sfondo trasparente?
Grazie bella classe ;-)