Animazioni CSS e Instant Developer Cloud

Gli elementi animati in un’applicazione rappresentano oggi una parte consolidata dell’esperienza collettiva degli utenti e, benché siano puri orpelli estetici, assolutamente inutili ai fini della funzionalità di un’app, non possono essere ignorati dagli sviluppatori. Gli utenti ormai se li aspettano ed essi contribuiscono a conferire un senso di professionalità, assolutamente errato, ai prodotti che sviluppiamo.

A meno che non si stia sviluppando videogiochi, questo tipo di artificio non è di grande apporto alla qualità complessiva di un software ma a noi sviluppatori nonostante si sia, per natura stessa del nostro mestiere, abituati a concentrarci più sull’arrosto che sul fumo, non resta molta alternativa al fare buon viso a cattivo gioco e finire per l’adottare questi bassi espedienti, tanto graditi dal pubblico e dai clienti (e invogliati dalle direttive di certi app store).

Instant Developer Cloud possiede già la capacità di gestire animazioni: per ogni elemento è possibile definire un flusso di informazioni (anche più di uno in effetti) che permettono di dare vita agli elementi statici della nostra interfaccia e di poterli poi integrare, con una serie di metodi ed eventi, nel ciclo di esecuzione di un’applicazione.

Ma diciamoci la verità: quanti di voi l’hanno realmente usato? É uno strumento potente, senza dubbio, ma con una debolezza proprio nel suo punto d’inizio: l’editor delle animazioni. É complesso da usare, a meno di non essere esperti in grafica d’animazione, e di non immediata chiarezza. O almeno, lo è per me, ma sospetto di essere in buona compagnia.

La mia strategia per risolvere la questione, è quella di utilizzare il codice CSS generato dai millemila siti che offrono questo servizio, anche in forma gratuita, ed incorporarlo nelle applicazioni sviluppate con Instant Developer Cloud.

Il vantaggio in questo caso, è che con pochi click si può ottenere una gradevole animazione atta ai nostri scopi, senza alcuna esperienza nel campo e possedendo solo una rudimentale conoscenza di come funziona la gestione tramite CSS degli elementi animati.

Vediamo con un esempio come si può sfruttare in IDC un’animazione creata in questo modo.

Creare un’animazione

Il primo passo, è ovviamente di procurarsi il codice che dia vita ad uno o più elementi della nostra interfaccia. Come dicevo, ci sono molti siti web che offrono questo servizio; personalmente faccio largo uso di questi due:

che, oltre ad offrire una buona varietà di piacevoli animazioni pronte all’uso, generano anche un codice CSS molto pulito (in particolar modo il primo).

Fatta la scelta, prendiamo il codice corrispondente che sarà sempre, nella forma, simile al seguente:

.scale-up-center
{
  -webkit-animation: scale-up-center 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
  animation: scale-up-center 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
}  

@-webkit-keyframes scale-up-center
{
  0%
  {
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
  }
  100%
  {
    -webkit-transform: scale(1);
    transform: scale(1);
  }
}

@keyframes scale-up-center
{
  0%
  {
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
  }
  100%
  {
    -webkit-transform: scale(1);
    transform: scale(1);
  }
}

dove in testa c’è la definizione del nome della classe da utilizzare su un qualsivoglia elemento dell’interfaccia ed a seguire la specifica di come deve svolgersi l’animazione (@keyframes).

Questo codice dovrà essere riportato in una risorsa di tipo CSS nel nostro progetto IDC.

Utilizzare un’animazione in IDC

Una volta che il codice CSS è stato inserito al suo posto nel nostro progetto IDC, è il momento di usarlo. Per farlo, è sufficiente utilizzare il metodo addClass(<nome classe CSS>) sull’elemento che vogliamo animare, al momento opportuno.

Ad esempio, potremmo decidere di dare inizio all’animazione quando un elemento viene cliccato, oppure quando viene mostrata la videata che lo contiene. Supponendo che il nostro elemento sia un’immagine riferita nel codice come $ImmagineAnimata, l’istruzione da utilizzare sarà:

$ImmagineAnimata.addClass("scale-up-center");

ed andrà posizionata nell’evento onClick dell’elemento o in quello onLoad della videata, a seconda di quando debba aver luogo l’animazione.

Immaginiamo che abbiate scelto di utilizzarla nell’evento onClick. Lanciate il progetto e fate click sull’immagine; essa prenderà magicamente vita sotto i vostri occhi. Non appena torna in posizione di quiete, supponiamo che abbiate voglia di animarla di nuovo. Cliccate dunque l’immagine per la seconda volta e… che succede? L’elemento grafico resta immobile, inchiodato al suo posto con una testardaggine che rasenta l’impudenza.

Prima di prendervela con la povera immagine però, è bene ricordare che questo è il comportamento normale. Non possiamo dare vita ad un elemento semplicemente aggiungendo di nuovo la classe dell’animazione; come avrete già capito, occorre prima rimuoverla.

A questo punto il vostro istinto vi avrà sicuramente suggerito di utilizzare allo scopo il metodo removeClass(nome classe CSS), per cui avrete già modificato il codice in qualcosa di simile a:

$ImmagineAnimata.addClass("scale-up-center");
$ImmagineAnimata.removeClass("scale-up-center");

o, se siete particolarmente temerari:

$ImmagineAnimata.removeClass(“scale-up-center”);
$ImmagineAnimata.addClass(“scale-up-center”);

se avete optato per il secondo caso, non avete sbagliato: in IDC tentare di rimuovere una classe non applicata ad un elemento sembra essere un’operazione sicura e non genera nessun errore o warning.

Ora lanciate di nuovo l’applicazione, ripetete i click e… niente, al secondo giro l’immagine resta sempre inchiodata al suo posto.

Perchè? Il motivo è presto detto: per riutilizzare più volte un’animazione su un elemento, questi dovrebbe essere rimosso e successivamente riaggiunto al DOM, operazione non sempllicissima da fare con IDC, ed in generale abbastanza scomoda.

Esiste per fortuna un’escamotage: se tra la rimozione (o l’aggiunta) della classe CSS aspettiamo un istante, diciamo 50 millisecondi, l’operazione viene “capita” correttamente dal renderer DOM e l’animazione rieseguita correttamente.

In pratica, il codice di cui sopra deve essere modificato in:

$ImmagineAnimata.removeClass(“scale-up-center”);
yield app.sleep(50);
$ImmagineAnimata.addClass(“scale-up-center”);

affinché l’effetto sia quello desiderato. Di norma, non occorre inserire un ritardo dopo l’addClass perché i tempi di reazione dell’utente sono sicuramente sufficienti per dare modo al DOM di capire cosa succede, anche nel caso in cui l’utente clicchi più volte di fila, innescando quindi un cliclo tra l’addClass ed il removeClass. Se volete essere particolarmente prudenti però, inserite pure un lieve ritardo anche dopo l’addClass o prima del removeClass.

Animazioni continue

Di buona norma, un ciclo di animazione ha un’inizio ed una fine, ossia parte con un elemento in quiete e termina lasciandolo in quiete. In alcuni casi particolari però occorre che l’animazione sia ripetuta ciclicamente. Come certamente saprete, i CSS prevedono questo comportamento, permettendo la definizione di un loop infinito di animazione e i servizi che producono codice già bell’è pronto allo scopo ne prevedono l’opzione.

A noi però può sorgere un problema: come la fermiamo un’animazione del genere, casomai fosse necessario? Com’è facile intuire, la risposta è semplice: basta togliere la classe al momento opportuno con removeClass.

In questo caso però, considerando che il nome della classe da aggiungere o togliere è sempre lo stesso, possiamo utilizzare il metodo toggleClass(<nome classe CSS>) che può compiere per noi entrambe le operazioni, regolandosi da solo.

Un altro vantaggio nell’utilizzo di toggleClass, oltre a farci risparmiare una riga di codice, è che non ci occorre introdurre un ritardo: le animazioni partiranno e si fermeranno sempre correttamente.

Non so se questo sia dovuto al fatto che i tempi di reazione dell’utente sono sufficienti al DOM per risistemarsi, alle corrette operazioni di Progamma dietro questo metodo o alla semplice fortuna; fatto sta che funziona, cosa di cui sono particolarmente contento.

Animazioni asimmestriche

Con questa espressione intendo quelle animazioni che, in un ciclo di due click, differiscono l’una dall’altra. Ad esempio, un pannello che appare alla prima pressione su un elemento grafico e poi scompare alla successiva pressione, con un’animazione differente. In casi come quello descritto, sono note anche come animazioni “di ingresso” e “di uscita” ma in generale, possono essere utilizzate per molti altri scopi.

Il loro utilizzo in un nostro progetto IDC è banale: basta avere la definizione delle due classi di animazione e l’accortezza di aggiungere e rimuoverle correttamente (e al momento giusto) esattamente come abbiamo già visto e tutto andrà liscio.

Ma in pratica?

Alla teoria è sempre buona norma far seguire la pratica, lo sappiamo bene. Per questo motivo ho creato un progetto di esempio, di accesso pubblico, a cui potete fare riferimento per provare sul campo quello che avete appena letto qui.

Il suo nome è “css-animation”, lo potete trovare cercando tra i progetti pubblici nella console.

Mi sarebbe piaciuto avere la possibilità di farlo aprire direttamente da qui, con un click su un link ad esempio, ma al momento questo non è possibile. @paolo.giannelli, che ne pensi di dotare la piattaforma anche questa possibilità? Può tornare comodo.

Conclusioni

Come vi sarete ben resi conto, utilizzare le animazioni CSS create con tool esterni in IDC è estremamente semplice, basta utilizzare al massimo due istruzioni, evitando di affrontare la difficoltà intrinseca dell’editor integrato, che richiede abilità di esperti animatori per essere sfruttato al meglio.

C’è però più di uno scotto da pagare. Poiché l’uso di questa tecnica esula dalla gestione integrata in IDC, ci si può ritrovare a gestire sorgenti CSS molto lunghi, con i nomi delle classi da applicare da ricercare in file che possono raggiungere e superare velocemente il migliaio di righe. É ovviamente possibile gestire un po’ la cosa, ad esempio tenendo i nomi delle classi in testa e suddividendo le animazioni in più file a tema, ma resta sempre un’operazione non troppo agevole.

In più, le animazioni vanno gestite da codice, facendo venire un po’ meno la natura RAD di Instant Developer Cloud, così come pure gli eventi su queste animazioni che non possono essere gestiti automaticamente dal framework e nell’IDE, come ormai siamo abituati a fare.

Personalmente, mi piacerebbe poter vedere ricondotto in qualche modo l’utilizzo di codice custom per le animazioni nel flusso di gestione automatico dell’IDE e perciò lancio una proposta in questo senso ai nostri amici di Progamma (@paolo.giannelli, potrebbe essere un’idea?).

E voi cosa ne pensate? Come avete risolto la necessità di utilizzare animazioni nei progetti IDC? Dite pure la vostra, leggerò volentieri i vostri pareri.

2 Mi Piace

Grazie mille per questo suggerimento, non ci sarei mai arrivato e avrei perso ore per capire come mai non funzionava… oppure avrei rimosso e riaggiunto l’elemento al DOM con tutte le implicazioni del caso.

@paolo.giannelli Vedo che iniziano a comparire articoli piuttosto lunghi e divisi in sezioni come questo, che sia il caso di aggiungere un riquadro di navigazione stile wiki con i titoli delle sezioni?
Non so se si riesce a farlo fare automaticamente, sulle varie wiki mi pare ci sia un template.

In effetti io ci ho perso ore prima di capire che bastava semplicemente dare al DOM il tempo di respirare e di scoprire che è un “trucco” comunemente usato, in alternativa al giro leva/rimetti dell’elemento nel DOM. Mi fa piacere che l’averlo condiviso con voi possa far risparmiare tempo e capocciate al muro anche ad altri.

@d.termini conviene rendere questi argomenti wiki così è possibile modificare lo stesso anche dopo che sono state date delle risposte e aggiungere le proprie considerazioni sul testo originale.
Per farlo occorre che l’autore renda wiki l’argomento andando in fondo al testo e cliccando sui tre puntini e poi dalla chiave inglese si clicca su Rendi Wiki.

Poi se identifichiamo un plugin di Discourse adatto lo installo.

1 Mi Piace