Ecco un’idea per una progress bar un po’ diversa dal solito. L’aspetto è quello dei V-meter digitali degli apparecchi audio. Solo che l’andamento della progressione non è logaritmico ma decimale e percentuale.
Può essere utilizzata come strumento di monitoraggio di operazioni lunghe eseguite sul server perché, grazie alla tecnologia Ajax, è possibile recuperare valori ad intervelli regolari da uno script PHP.
I requisiti per un corretto funzionamento sono:
- Javascript abilitato
- PHP con supporto GD 2.0.1 o successivi
- FreeType library
La progress bar viene generata dinamicamente da uno script PHP che esegue l’eco di un’immagine in formato PNG. I valori passati in querystring servono per colorare le barre. La percentuale viene calcolata normalizzando il valore sul minimo e il massimo, con un’approssimazione per difetto alla decina inferiore. (p.e.: 52% accende 5 barre). Il default per il minimo e il massimo è rispettivamente 0 e 100
Ecco il codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | //============================================================================== // PROGRESS BAR V-METER STYLE //============================================================================== if (!empty($_GET['value'])){ $value = intval($_GET['value']); $min = empty($_GET['min']) ? 0 : intval($_GET['min']); $max = empty($_GET['max']) ? 100 : intval($_GET['max']); } else{ $value = 0; $min = 0; $max = 100; } $nValue = floor((($value-$min) / ($max-$min)) * 100); header("Content-type: image/png"); $string = $nValue." %"; $font = 'arial.ttf'; $width = 110; $height = $width; $im = @imagecreatetruecolor ($width,$height); $width -=5; $height -=5; $background_color = imageColorAllocate($im, 0, 0, 0); $color = imageColorAllocate($im, 0, 255, 0); imagefill($im, 0, 0, $background_color); for($i=0;$i<10;$i++){ $x1 = $width; $y1 = $height-2 - ($i*10); $x2 = $width-10 - ($i*10); $y2 = $height-10 - ($i*10); if ($i<(floor($nValue/10))){ imageFilledRectangle($im, $x1, $y1, $x2, $y2, $color); } else{ imagerectangle($im, $x1, $y1, $x2, $y2, $color); } } $text_color = imagecolorallocate ($im, 255, 255, 255); imagettftext($im, 14, 0, 5, $height-10, $text_color, $font, $string); imagepng($im); imagedestroy($im); |
Volendo una più ampia compatibilità, è possibile evitare di utilizzare la funzione imagettftext()
sostituendola con imagestring()
, in questo caso vengono utilizzati i font interni con codifica latin2. Però non sono altrettanto belli e le dimensioni possibili sono solo 5. Il valore più grande restituisce una dimensione di carattere piuttosto piccola… ove possibile è preferibile usare i TTF
Questo è il codice di esempio per rappresentare la progress bar in una pagina web con un po’ di Ajax per rigenerare dinamicamente l’immagine ogni 2 secondi:
1 2 3 4 5 6 7 8 9 10 11 12 | <script type="text/javascript" language="javascript"> <!-- var xml = ""; function getPage() { var url = "./randgen.php"; if (window.XMLHttpRequest) { xml = new XMLHttpRequest(); } else if (window.ActiveXObject) { xml = new ActiveXObject("Microsoft.XMLHTTP"); } else { alert("Your browser lacks the needed ability to use Ajax"); return false; } xml.onreadystatechange = processPage; xml.open("GET", url, true); xml.send(""); setTimeout('getPage()', 2*1000); } function processPage() { if (xml.readyState == 4) { if (xml.status == 200) { document.getElementById("myProgBar").src="./progbar.php?value=" + xml.responseText; } else { alert("There was a problem retrieving the XML data:\n" + xml.statusText); } } } //--> </script> <script type="text/javascript" language="javascript"> getPage(); </script> |
Test della progress bar V-meter style
1 |
Lo script randgen.php genera dei numeri casuali da 0 a 100 solo a scopo dimostrativo, nella pratica dovrà generare il valore da rappresentare nella progress bar.
randgen.php:
1 2 3 4 5 6 7 8 | $min = empty($_GET['min']) ? 0 : intval($_GET['min']); $max = empty($_GET['max']) ? 100 : intval($_GET['max']); // headers are sent to prevent browsers from caching header('Expires: Fri, 25 Dec 1980 00:00:00 GMT'); // time in the past header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); echo rand($min,$max); |
Il pacchetto completo è scaricabile qui
Conclusioni:
Siccome adoro i V-meter analogici, per capirci quelli che si trovavano sui grandi amplificatori HiFi degli anni ’70, stavo pensando anche a qualcosa del genere per il futuro, peccato che con la grafica ho qualche difficoltà…!
Riferimenti ed approfondimenti: