Come realizzare una progress bar CSS3 per una HTML Mobile App

gennaio 02, 2014
Share on Facebook0Tweet about this on Twitter0Pin on Pinterest0Share on Google+0

In altri articoli ho discusso l’importanza delle performance per quanto riguarda lo sviluppo di HTML mobile app tramite CSS3 e Javascript.

Durante la realizzazione di un’applicazione destinata a dispositivi mobile è importante sviluppare ogni effetto e animazione tenendo conto delle performance, fattore che su smartphone o tablet con sistemi operativi iOS, Android e Windows Phone diventa un vero e proprio must, se si vuole fornire all’utente un’interfaccia piacevole, fluida e reattiva.

In questo post voglio proporti il “modo performante” di realizzare una progress bar CSS3 con HTML5 e Javascript che risulti leggera ai fini del processo di rendering e piacevole all’occhio dell’utente, mentre egli interagisce con l’interfaccia.

Per capire meglio quali sono i punti chiave del codice CSS3, ma soprattutto la differenza visiva, ci soffermeremo su come scrivere la stessa animazione anche in modo poco performante.

Come-realizzare-una-progress-bar-CSS3-per-una-HTML-Mobile-App

Due progress bar CSS3 a confronto

Il mio principale intento con questo articolo, oltre quello di mostrarti diverse strade per realizzare lo stesso effetto, è sottolineare la differenza che si può avere agendo con due tecniche separate:

  1. quella che sfrutta la composizione dei layer grafici (alta performance e fluidità)
  2. quella che costringe il browser a ripetere l’intero processo di rendering per ogni keyframe dell’animazione (bassa performance e movimenti scattosi)

Al fine di comprendere meglio i concetti di processo di rendering e dei layer grafici ti consiglio di leggere rispettivamente questi due post (credimi, se sei un front-end developer ne vale proprio la pena):

  1. Come ottimizzare le animazioni per i dispositivi mobile
  2. Scrivere HTML Mobile App fluide con i layer grafici e l’accelerazione hardware

In questo esperimento realizzeremo quindi due progress bar CSS3, la versione fluida, e quella con scarse prestazioni.

Il markup HTML

Vediamo il (semplice) markup HTML delle due progress bar:

 

In particolare usiamo la div con classe .progress-box come contenitore principale, il quale presenta al suo interno la barra che sarà animata (classe .progress-inner) e l’icona che mostreremo alla fine dell’animazione, per comunicare all’utente che l’operazione (qualunque essa sia) è andata a buon fine.

Come puoi vedere dal codice l’unica differenza tra le due progress bar sono le classi “fast” o “low” applicate al contenitore principale progress-box; è grazie ad esse che assegneremo ai due elementi DOM degli stili diversi per realizzare lo stesso tipo di effetto.

Gli stili CSS3

Impostiamo gli stili per il contenitore (progress-box), per la barra da animare (progress-inner) e per l’icona di completamento dell’operazione: alla prima attribuiamo la proprietà position:relative, mentre alla seconda e alla terza position:absolute, in modo da poterle muovere all’interno del contenitore con più facilità (utilizzando gli attributi “top“, “left” ):

Allo stato iniziale l’icona, che non deve essere visibile fino al completamento dell’operazione, è stata impostata non visibile tramite la trasparenza (opacity:0) e traslata “indietro” di 30px tramite la proprietà CSS3 transform: traslateX(-30px) (con tutti i relativi prefissi del caso per la compatibilità).

Vediamo ora come animare la progressabar con classe low “alla vecchia maniera”, tramite codice poco perforemante:

 

Abbiamo agito sulla proprietà “width“, che fa parte del primo step del processo di rendering e che quindi costringe il browser a ripetere tale processo (eseguendo tutti gli step che lo compongono) ad ogni keyframe dell’applicazione, provocando un effetto di “sfarfallio”.

Passiamo ora invece a degli stili decisamente più performanti, quelli della progress bar con classe fast:

Qui realizziamo l’animazione impostando la proprietà transition in modo da agire sul transform, per forzare la creazione dei layer grafici, i quali fanno parte del terzo step del processo di rendering. Così facendo la creazione dei relativi effetti viene delegata alla memoria grafica (la GPU).

Il codice Javascript

Passiamo ora al semplice codice javascript per gestire gli eventi di azione sui pulsanti che avviano e resettano l’operazione (“#start” e “#reset“):

Al click del pulsante #start impostiamo semplicemente la proprietà width al 100% per la progress lenta, e la proprietà “transform:scaleX” ad (che equivale al 100% ) per la progress fluida.

Al click del pulsante “#reset” riportiamo le due progress bar ai valori iniziali, avendo come risultato un’animazione con effetto contrario.

Conclusioni e considerazioni

Con la demo è possibile visualizzare la grande differenza tra la progress bar scritta in modo performante e quella scritta in modo poco performante: la prima risulta fluida e piacevole visivamente, mentre la seconda è scattante e presenta un notevole sfarfallio (ti consiglio di visualizzare l’esempio in un dispositivo mobile).

In un’eventuale HTML mobile app (ma anche in qualsiasi web app che sfrutta le funzionalità dei CSS3), impiegare più effetti con scarse performance, oltre ad una user-experience sgradevole, può provocare crash continui dell’applicazione, e incidere notevolmente sul giudizio che gli utenti attribuiscono al nostro prodotto (con conseguente impatto negativo sulla community).

Dall’altro lato invece, se scriviamo le nostre animazioni CSS3 in modo da sfruttare correttamente il lavoro della GPU, avremo come risultato un’applicazione piacevole, fluida e performante, e la differenza con quelle native sarà pressoché inesistente.

 

Crea la tua mobile app in HTML, CSS3 e Javascript

Utilizzando questa tecnica insieme a molte altre, ho realizzato più di 10 mobile app in HTML, CSS3 e Javascript (tra cui Tint e Dieta SI o NO?).

Se anche tu vuoi realizzare la tua applicazione in HTML, CSS e javascript da distribuire nei vari store, forse potrebbe interessarti il mio e-book HTML Mobile Accelerato.

HTML-mobile-accelerato-ebook-cover

Giacomo Freddi

Web Designer Freelance e Developer, si occupa del design e dello sviluppo di applicazioni web dal 2008, come molti freelance è abituato a gestire più ruoli e spaziare su più campi, ma la sua passione principale è quella della creazione di interfacce front-end e back-end utilizzando codice html5 e css3. Adora usare pattern MVC per i suoi Javascript.

  • Pingback: Progress bar CSS3 in HTML5 e Javacript per HTML...()

  • Pingback: Come realizzare un Mobile Action Sheet con Bootstrap 3 e Animazioni CSS3 | upCreative()

  • William

    Ciao Giacomo,

    ottimo post, è da un mesetto che seguo i tuoi articoli, mi sono anche iscritto alla newsletter per il tuo ebook in arrivo, complimenti davvero!!!

    ho una domanda da “rompiballe/pignolo” eheh…
    Ho fatto una prova impostanto un border radius alla progress bar, ho visto che la transizione con lo scaleX non visualizza (correttamente immagino per la sua natura) lo smussamento corretto fino a quando non arriva al 100%.
    In questi casi, per mantenere le performance e lo smussamento dei bordi, sarebbe meglio utilizzare un translateX? Anche se mi sa che così, non si vedrebbe lo smussamento iniziale della barra. Oppure c’è qualche soluzione alternativa? :)

    è un caso particolare lo so, se mai mi si dovesse presentare, “spingerò” per l’eliminazione dei bordi smussati…ehehe

    Grazie.

    Ciao

    • Giacomo Freddi

      Ciao William, sono contento che ti piaccia quello che scrivo, cerco sempre di essere il più utile possibile! Ti aggiornerò via newsletter per l’uscita del libro :)

      Hai fatto veramente un’ottima domanda, purtroppo credo che questo sia un problema legato ai browser, che ancora qualche volta presentano delle “lacune” sulle funzionalità CSS3, proprio come in questo caso.
      Applicando il border-radius al contenitore della progress (quello avente classe “.progress-box”), anche con l'”overflow:hidden” i bordi non vengono comunque arrotondati durante l’animazione (credo che ciò sia dovuto alla creazione dei layer grafici).
      Mentre invece applicandolo alla progress direttamente, i bordi sì, vengono visualizzati, ma con lo scale subiscono uno “stretch”, in quanto tutte le animazioni che richiedono la creazione di livelli grafici sono delegate alla CPU sotto forma di bitmap (in altre parole sono delle immagini vere e proprie, e gli angoli arrotondati con il border-radius fanno parte di esse).

      Comunque mi hai dato dell’ottimo materiale per un possibile futuro articolo, resta aggiornato, forse posterò una soluzione! ;)