Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Grafica SVG con Raphael

Guida all'uso della libreria Raphael, un'ottima soluzione per la creazione di grafica e animazioni basate su SVG
Guida all'uso della libreria Raphael, un'ottima soluzione per la creazione di grafica e animazioni basate su SVG
Link copiato negli appunti

Questa è la traduzione dell'articolo SVG with a little help from Raphaël di Brian Suda, pubblicato originariamente su A List Apart il 20 Luglio 2010. La traduzione viene qui presentata con il consenso dell'editore (A List Apart Magazine) e dell'autore.

Raphaël è una libreria Javascript leggera che, nel contesto di una pagina web, rende a schermo grafica SVG dinamica, inclusi grafici, animazioni vettoriali, componenti per l'interfaccia utente. Ora forse state pensando: posso farlo anche con jQuery, con Google Charts, anche con Flash. È vero, ma Raphaël offre nuove possibilità, caratteristiche e funzionalità non ancora disponibili con queste tecnologie. Impareremo allora come creare immagini vettoriali scalabili che funzionano sui vari browser e degradano in maniera intelligente.

Un linguaggio aperto per il web aperto

Il web gira tutto intorno agli standard aperti e a tecnologie non proprietarie. Raphaël, che usa il linguaggio SVG (uno standard del W3C) e una licenza open source MIT, rientra perfettamente in tale contesto.

Ma cosa fare con Internet Explorer 6? Non supporta SVG! È vero, ma IE6 supporta il linguaggio proprietario VML (Vector Markup Language). Per quanto riguarda le altre versioni del browser di Microsoft, IE9 supporterà SVG 1.1; IE7 e IE8 non sanno cosa fare con un file SVG, così Raphaël seleziona automaticamente la modalità di rendering giusta. Insomma, Raphaël allontana dalle preoccupazioni dello sviluppatore tutte le questioni che riguardano i browser. Lo stesso codice Javascript creerà una bella grafica SVG o VML in base alle caratteristiche del browser. Si scrive il codice una volta sola ed esso funziona dovunque. Inoltre, superando l'uso di Flash per la grafica vettoriale, possiamo distribuire il risultato su un numero maggiore di dispositivi, tra cui quelli equipaggiati con WebKit per il mobile e i dispositivi basati su iOS. La vostra bella grafica vettoriale, scalabile e interattiva, renderà al meglio a qualunque risoluzione sui dispositivi supportati.

jQuery

E jQuery? Ci sono tantissimi plugin per la gestione della grafica. Perché affidarsi a Raphaël?

Tra gli interessanti plugin dedicati alla grafica ricordiamo jqPlot, Flot, jQuery SVG. Con jQuery ci affidiamo a una libreria che, compressa, supera i 50kb di peso. Aggiungiamo il core per la UI, alcuni plugin, le librerie extra per lavorare con IE. Byte su byte facciamo un bel pacchetto, ma abbiamo anche molti byte di cui non abbiamo bisogno.

Raphaël è nel complesso più piccola per creare grafica vettoriale di base. Controllare il peso in kb è qualcosa da considerare quando si sviluppano applicazioni su larga scala, ma lo è anche la scelta dello strumento giusto per il lavoro che si deve portare a termine.

Non deve diventare comunque uno scenario del tipo 'o l'uno o l'altro'. Se usate già jQuery, è possibile aggiungere Raphaël senza conflitti di sorta. Molte di queste librerie Javascript possono convivere in perfetta armonia, cosa che rende molto più semplice la vita degli sviluppatori.

Immagini dinamiche

Prima che avessimo a disposizione tutte queste librerie, questi servizi web, questi strumenti, le immagini generate dinamicamente erano create sul server attraverso script CGI. Come sono cambiate le cose! Ora abbiamo accesso a servizi come Google Charts e altri che usano il protocollo REST. Basta specificare i parametri per ottenere in risposta un magnifico grafico.

Incorporare Google Charts in un elemento <img> è un modo veloce e flessibile per creare grafici a barre, ma è un approccio che ha i suoi svantaggi. Dal momento che si tratta di un elemento immagine, abbiamo a disposizione solo l'attributo alt. Per etichettare le varie regioni del grafico dobbiamo usare l'attributo longdesc o una mappa immagine alterata. Tutti i dati sono compresi e bloccati nei pixel dell'immagine, non nel codice HTML. Le immagini statiche sono rese poi ad una certa dimensione. Significa che zoomando l'immagine diventa tutta pixelata. Realizzando infatti grafici professionali, si scoprono presto i problemi derivanti dall'uso di formati raster come JPEG, GIF e PNG, che non scalano molto bene. SVG, invece, è un formato vettoriale, così è indipendente dalla risoluzione. Dal momento che il web è disponibile in tutte le forme e in tutte le dimensioni, e dal momento che sempre più spesso i dati transitano fuori e dentro il web, la grafica deve mantenere la sua risoluzione dalla qualità ottimale per la stampa fino ad una risoluzione bassa come quella dei 72dpi di certi schermi.

Esempi

Progressive enhancement

Raphaël usa Javascript per inserire la grafica SVG o VML nella pagina. Ciò significa che il nostro browser deve supportare Javascript per visualizzare la grafica risultante. Se è lecito aspettarsi che la maggior parte delle persone navigherà sul sito usando uno qualunque tra i browser più moderni, con Javascript attivo e il supporto per SVG, può accadere che i clienti/utenti più importanti non siano in tale condizione. I bot dei motori di ricerca, come quello di Google, non sono in grado di rendere il Javascript. Non vedono la vostra bella grafica. Vedono un div vuoto senza contenuti!

Qui entra in gioco un concetto chiave: quello di progressive enhancement. I dati grezzi in HTML sono la base di partenza. Possono anche non essere presentati in modo perfetto sotto forma di lista o tabella, ma sono semanticamente corretti e aggiungono un aggancio utile ai motori di ricerca per indicizzare i contenuti. È ora possibile usare il codice HTMl come una fonte di dati quando si realizzano grafici con Raphaël.

Nutritional information for product X
Calories 45%
Saturated Fats 25%
Protein 15%
Vitamin B 10%
Vitamin C 5%

Per prima cosa creiamo una tabella di valori che hanno come somma il 100%. Questi sono i valori per ciascuna fetta del grafico a torta. Possiamo migliorare la tabella di base se il browser ha il giusto supporto.

<table id="nutritionFacts">
  <caption>Nutritional information for product X</caption>
  <tr>
    <th scope="row">Calories</th>
    <td>45%</td>
  </tr>
  <tr>
    <th scope="row">Saturated Fats</th>
    <td>25%</td>
  </tr>
  <tr>
    <th scope="row">Protein</th>
    <td>15%</td>
  </tr>
  <tr>
    <th scope="row">Vitamin B</th>
    <td>10%</td>
  </tr>
  <tr>
    <th scope="row">Vitamin C</th>
    <td>5%</td>
  </tr>
</table>

Ora che abbiamo i nostri dati di base grezzi, possiamo aggiungere una serie di librerie Javascript esterne. Prima di tutto includiamo Raphaël:

<script src="raphael.js" type="text/javascript" charset="utf-8"></script>

Poi useremo il sistema di plugin di Raphaël per includere quello relativo ai grafici a torta:

<script src="pie.js" type="text/javascript" charset="utf-8"></script>

Ciò ci fornisce l'accesso a tutti gli strumenti di cui abbiamo bisogno per convertire la tabella in un grafico SVG. Per generare il grafico a torta, dobbiamo innanzitutto creare due array, uno per le etichette, il secondo per i valori:

var values = [],
  labels = [],
  nfTable = document.getElementById("nutritionFacts"),
  i = 0,
  rows = nfTable.rows.length;
for( ;i < rows; i++) {
  trRow = nfTable.getElementsByTagName("tr")[i];
  labels.push(trRow.getElementsByTagName("th")[0].firstChild.nodeValue);
  values.push(parseInt(trRow.getElementsByTagName("td")[0]
  .firstChild.nodeValue, 10));
}
nfTable.style.position = 'absolute';
nfTable.style.left = '-999em';

Ora rintracciamo tutti gli elementi <tr> ed eseguiamo un loop su di essi, inserendo ciascun <th> nell'array delle etichette e ciascun <td> nell'array dei valori. Infine, nascondiamo la tabella, dal momento che la rimpiazzeremo successivamente con il grafico a torta.

raphael("myHolderPie", 540, 400).pieChart(270, 200, 100,
  values, labels, "#fff");

Per rendere il grafico a torta usiamo l'oggetto raphael, specifichiamo l'id di un elemento e alcune dimensioni. In questo caso, stiamo usando il div myHolderPie. Assegniamo ad esso una larghezza di 540px e un'altezza di 400px. Attacchiamo poi la funzione pieChart a quell'area. La funzione pieChart comprende diverse variabili, tra cui il punto centrale da sinistra a destra. In questo caso stiamo iniziando da 270px a partire dal lato sinistro del div contenitore. L'argomento successivo è 200, che equivale al numero di pixel a partire dall'alto dell'elemento contenitore. Il valore 100 dice al codice di rendere un grafico a torta con un diametro di 100px. Potete provare ad usare valori di 200px o 50px per vedere cosa accade. I due argomenti successivi sono i valori relativi al grafico e le etichette realizzate con jQuery. L'ultimo argomento è il valore esadecimale per il colore usato nel bordo del grafico. Eliminando questo argomento il grafico sarà senza bordo.

Sul sito graphaël trovate ulteriori informazioni sui tipi di grafici che potete usare e creare.

Tenete in mente che ogni volta che sostituite una tabella o altro tipo di informazione con un bel grafico o con un'interfaccia interattiva, dovrete considerare quanto perdete e quanto guadagnate. L'accessibilità è un fattore importante. Se i vostri lettori hanno solo una tastiera, possono continuare a usare il tasto di tabulazione per accedere ai dati? Gli utenti non vedenti possono accedere all'informazione presente nel nuovo contenuto come facevano con l'originale? In questo caso una tabella accessibile viene sostituita con un elemento molto meno accessibile, ma la vecchia tabella è stata nascosta ed è ancora disponibile per gli utenti di screen reader. Tuttavia, il nuovo contenuto limita l'uso da parte di quegli utenti che usano solo la testiera. Il supporto per le specifiche ARIA del W3C e per la regola tabIndex="0" in SVG aiuterebbe a superare il problema relativo all'accessibilità nel futuro, ma al momento ciò non è parte del plugin Raphaël.

Fine prima parte.

Animazioni

Raphaël comprende anche diverse interessanti funzionalità relative alla creazione di animazioni. Una funzionalità molto interessante è la capacità di disegnare un tracciato. Immaginate di lavorare per l'ufficio del turismo di Edimburgo. Il castello di Edimburgo è una meta molto popolare. Volete mostrare la via più rapida e facile per raggiungerlo partendo dalla stazione dei treni. Non sarebbe bello se si potesse visualizzare su una mappa un tracciato animato del percorso?

Realizzare una cosa del genere con Raphaël è semplicissimo.

Map of Edinburgh

Prima di tutto avete bisogno di una mappa per lo sfondo. Poi avrete bisogno di creare il tracciato da seguire e infine di poche righe di Javascript per assemblare il tutto.

Per iniziare, dunque, andiamo a creare un'area in cui inserire il nostro SVG. Nell'esempio useremo il div myMapHolder e creeremo un'area larga 540px e alta 403px.

var myMap = raphael("myMapHolder", 540, 403);

Successivamente inseriremo una mappa come sfondo. Ho usato uno screenshot catturato sul sito Open Street Map, ma potete usare qualunque immagine. Per essere sicuri che gli utenti che non hanno Javascript a disposizione possano comunque visualizzare la mappa, aggiungiamo un elemento <img> con un link alla mappa all'interno del div myMapHolder. La prima cosa da fare con Javascript è quella di rimuovere l'immagine di base così che possa essere caricata la mappa più dinamica al suo posto.

var myMapHolder = document.getElementById("myMapHolder");
myMapHolder.removeChild(myMapHolder.childNodes[0]);
var myImage = myMap.image("map.png", 0, 0, 540, 40

Ho posizionato a 0 pixel dall'alto e da sinistra la mappa, quindi ho specificato le dimensioni dell'immagine (540x403px).

var myPath = myMap.path("M513.859,35.222l-95.332,24.667l" +
    "18.666,76.667l-131.334,46c0,0-10.667," +
    "3.333-11.333,13.333c-0.891,13.371-42.748," +
    "23.018-42.748,23.018s-13.252,3.648-9.252," +
    "18.315s14.667,43.333,14.667,43.333l-104.667,22.667")
                  .attr({
                    stroke: "#f00",
                    opacity: .7,
                    "stroke-width": 5
                  })

Poi viene la parte più complicata. Il codice per il tracciato animato in SVG. Ho tracciato il tutto in Illustrator e ho salvato il path come SVG per poi incollarlo nel codice; è il modo ad oggi più semplice per creare rapidamente un tracciato complesso. Come potete vedere, abbiamo anche una funzione attr() per specificare il colore, l'opacità e la larghezza del tracciato. Il codice che abbiamo usato creerà un path opaco al 70%, rosso, largo 5px.


var myMarker = myMap.ellipse(513.859,35.333, 7, 7).attr({
  stroke: "none",
  opacity: .7,
  fill: "#f00"
});

Una volta impostati il tracciato e la mappa, dobbiamo creare un piccolo puntino. Ecco il codice per creare un cerchio con un raggio di 7px partendo dal punto 513.859,35.333. Abbiamo anche aggiunto alcuni attributi addizionali per rimuovere il bordo, cambiare l'opacità e il colore del puntino.

function run() {
  myMarker.animateAlong(p, 20000, false, function () {
    myMarker.attr({ cx: 513.859, cy: 35.333, rotation: 0 });
    run();
  });
}
run();

Infine, assembliamo tutto in un'animazione. Creiamo una funzione run() che muove il puntino lungo il percorso.

Quando l'esecuzione iniziale è terminata, l'animazione viene eseguita in loop.

Ora, per animare il puntino, lo piazziamo nella variabile myMarker e scriviamo myMarker.animationAlong(). Questa funzione ha diversi argomenti. Prima specifichiamo il percorso che vogliamo seguire, nel nostro caso myPath; poi impostiamo una durata per la lunghezza del tempo in cui il puntino dovrà percorrere il tracciato; L'argomento successivo ruota l'oggetto lungo un tracciato. Non vogliamo questo effetto, per cui settiamo su false. Infine, abbiamo una funzione di callback che in questo caso resetta il puntino sulla sua posizione di partenza per creare il loop.

Benefici dell'uso di SVG sul web

Man mano che HTML5 guadagna spazio in termini di popolarità, SVG ha un nuovo rivale nell'elemento <canvas>. Entrambi servono a disegnare elementi grafici sullo schermo, cosa che può far dubitare su quale dei due usare. La più grande differenza è che tutti gli elementi SVG sono parte del DOM. Con canvas possiamo accedere solo all'elemento radice <canvas>.

Poiché SVG è parte del DOM, possiamo aggiungere eventi a tutte le porzioni individuali di una grafica SVG. Azioni come onClick, onTap oppure onHover rendono la grafica SVG flessibile fino al punto di poter essere un sostituto completo di Flash. Dato che questi eventi possono essere eseguiti a runtime, a seconda delle caratteristiche del browser e del dispositivo, abbiamo ampie possibilità per una strategia di progressive enhancement. Con canvas il disegno non è parte del DOM e così sacrifichiamo l'interattività a favore di un risparmio in termini di risorse di memoria nel rendering dell'albero del DOM. Incorporare in una pagina una grafica SVG molto complessa potrebbe rallentare un computer, troppo impegnato nella resa di migliaia di nodi DOM.

SVG è scalabile, così man mano che più browser si spostano in direzione del meccanismo di zoom per aumentare le dimensioni del testo e delle immagini, SVG mantiene contorni nitidi. L'elemento canvas è invece rasterizzato, per cui produce la classica pixelatura quando viene ingrandito.

SVG: uno standard del W3C

SVG è uno standard del W3C. Significa che nessuno oserà prendersi il pallone e tornare a casa lasciandovi lì con tonnellate di codice inutile. Dal momento che è non solo aperto come linguaggio, ma anche non sottoposto a royalty, sempre più applicazioni, dispositivi e servizi saranno in grado di consumare e servire SVG. Un ecosistema molto favorevole si sta sviluppando, tale da non far prevedere la scomparsa di SVG. Significa anche che non bisogna preoccuparsi dei dettagli implementativi. Le applicazioni fanno tutto il lavoro sporco e duro, creando i nodi e i tracciati SVG. Il codice XML è sempre lì, comunque, per quanti vogliano metterci mano e modificarlo.

Conclusioni

SVG è una tecnologia matura già da molti anni. Ora, con il supporto di tutti i principali browser (tra cui IE9), è ad un punto di svolta. Il fatto che stiamo vedendo librerie Javascript dedicate come Raphaël scritte da persone brillanti come Dmitry Baranovskiy, è solo il segno di ciò che sta per arrivare. Creare grafica basata su standard aperti, vettoriale, animata, con curve scalabili, ben definite, regioni cliccabili e forme di ogni tipo sarà davvero eccitante nel futuro del web.

Ti consigliamo anche