Dart: l’applicazione di esempio “Swipe”

Di - 9 December 2012 - in

Nell’articolo di oggi analizzeremo un’applicazione di esempio inclusa in Dart Editor, Swipe, applicazione molto semplice: le parole che compongono un testo palindromo vengono mostrate circolarmente e l’utente può scorrerle con le frecce della tastiera o al tocco nel caso di disposivi mobili.

Avviamo Dart Editor, apriamo l’applicazione Swipe dal menù Tools -> Welcome Page, la struttura della directory è minimale: c’è un foglio di stile, uno script Dart e il file HTML con la struttura grafica dell’applicazione. Aprendo la scheda Outline dal menù Tools -> Outline possiamo vedere quali sono gli attributi ed i metodi dell’applicazione nell’ordine in cui essi vengono invocati:

  • target
  • figureWidth
  • anglePos
  • timeoutHandle
  • main()
  • initialize3D()
  • spinFigure(Element, int)
  • startSpin(Element, int)
  • stopSpin()

L’attributo target si riferisce all’elemento HTML che contiene le parole del testo, e la funzione che associa questo elemento al suo identificatore è query():

target = query('#target'); // swipe.dart:19

In Dart questa operazione è molto più intuitiva ed immediata rispetto all’equivalente in Javascript:

target = document.getElementById('target');

figureWidth e anglePos si riferiscono rispettivamente alla larghezza ed alla angolatura di ogni box contentente una parola; timeoutHandle è una variabile tramite la quale viene gestito il timeout delle animazioni.

Uno dei vantaggi delle applicazioni in Dart è che hanno un entry point, ovvero la funzione main(), che ci consente una migliore lettura e comprensione del codice; vediamo cosa accade quando l’applicazione viene avviata:

  1. target = query('#target');

    Associa all’identificatore target l’elemento #target;

  2. initialize3D();

    Questa funzione inizializza il rendering degli oggetti e l’animazione 3D; come prima cosa aggiunge la classe CSS “transformable” all’elemento HTML #target, poi ottiene il numero di figli e associa ad essi gli attributi CSS relativi all’animazione:

     target.classes.add("transformable");
     num childCount = target.children.length;
    
     . . .
    
      for (int i = 0; i < childCount; i++) {
          var panel = target.children[i];
          panel.classes.add("transformable");
          panel.style.transform =
             "rotateY(${i * (360 / childCount)}deg) translateZ(${radius}px)";
       }

    dopodichè viene invocata la funzione spinFigure();

Seguono una serie di funzioni che associano all’applicazione funzioni di callback agli eventi TouchEvent e KeyboardEvent; è importante notare che nella funzione on.touchMove() le variabili touchStartX e newTouchX assumono il valore del tocco iniziale e del tocco finale sullo schermo, e quindi determinano la direzione dell’animazione:

target.on.touchMove.add((TouchEvent event) {
event.preventDefault();

if (touchStartX != null && event.touches.length > 0) {
  int newTouchX = event.touches[0].pageX;

  if (newTouchX > touchStartX) {
    spinFigure(target, (newTouchX - touchStartX) ~/ 20 + 1);
    touchStartX = null;
  } else if (newTouchX < touchStartX) {
    spinFigure(target, (newTouchX - touchStartX) ~/ 20 - 1);
    touchStartX = null;
  }
}
});

Per quanto riguarda la gestione di un KeyboardEvent la porzione di codice è la seguente:

 document.on.keyDown.add((KeyboardEvent event) {
switch (event.keyCode) {
  case KeyCode.LEFT:
    startSpin(target, -1);
    break;
  case KeyCode.RIGHT:
    startSpin(target, 1);
    break;
}
});

document.on.keyUp.add((event) => stopSpin());
}

Il codice è molto semplice da leggere: ad esempio se il tasto premuto — event.KeyCode — è “sinistra”, allora la direzione dell’animazione sarà verso sinistra startSpin(target, -1);

La funzione document.on.keyUp.add((event) => stopSpin()); assume che l’animazione dovrà essere interrotta nel momento in cui l’utente smetterà di tenere premuto il tasto.

Le funzioni startSpin() e stopSpin() si occupano della gestione dell’handle timeoutHandle e rispettivamente avviano e interrompono l’animazione, quest’ultima gestita da spinFigure(Element figure, int direction), che prende in ingresso l’elemento figure, ovvero il blocco che contiene la singola parola, e dopo l’elaborazione dei valori correnti associa all’elemento style.transform le funzioni translateZ e rotateY:

figure.style.transform =
  'translateZ(-${figureWidth}px) rotateY(${anglePos}deg)';

Se si vuole provare l’applicazione dal proprio dispositivo mobile basterà digitare l’indirizzo:

http://127.0.0.1:3030/home/utente/dart/swipe/swipe.html

sostituendo 127.0.0.1 con l’IP interno (generalmente 192.168.x.y) della macchina sul quale è in esecuzione l’applicazione; quando il dispositivo mobile sarà collegato, l’applicazione verrà compilata in Javascript e nella console verrà mostrato un messaggio tipo:

Remote connection from 192.168.0.3 [Mozilla/5.0 (Linux; U; Android 4.0.4; it-it; ST21i Build/11.0.A.4.22) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30]
Compiling /swipe/swipe.dart...
Using snapshot /Applications/dart/dart-sdk/lib/_internal/compiler/implementation/dart2js.dart.snapshot

Nelle prossime settimane continueremo a parlare di web apps, introdurremo i Web Components e vedremo come questi ultimi possono farci risparmiare tempo nella scrittura di un’applicazione.

Leave a Reply

Claudio d'Angelis Articolo scritto da

Programmatore e studente di Informatica, appassionato di musica, web e sistemi UNIX. Collabora con Googlab dall’Ottobre 2012.

Contatta l'autore

Previous post:

Next post: