Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript
Code

Creare il carosello perfetto, parte 1

by
Difficulty:AdvancedLength:LongLanguages:
This post is part of a series called Create the Perfect Carousel.
Create the Perfect Carousel, Part 2

Italian (Italiano) translation by Cinzia Sgariglia (you can also view the original English article)

I caroselli sono un punto base di siti di streaming e di e-commerce. Sia Amazon e Netflix li utilizzano come strumenti di navigazione di spicco. In questo tutorial, valuteremo il design interattivo di entrambi e utilizzeremo i nostri risultati per implementare il carosello perfetto.

In questa serie di tutorial, impareremo anche alcune funzioni di Popmotion, un motion engine di JavaScript. Offre strumenti di animazione come le interpolazioni (utile per l'impaginazione), il puntatore tracking (per lo scorrimento) e fisica della forza elastica (per il nostro delizioso tocco finale).

La Parte 1 valuterà come Amazon e Netflix hanno implementato lo scorrimento. Quindi implementeremo un carosello che può essere scorso tramite tocco.

Entro la fine di questa serie, avremo implementato lo scorrimento con la rotellina e con il touchpad, l'impaginazione, le barre di avanzamento, la navigazione da tastiera e alcuni piccoli tocchi utilizzando la fisica della forza elastica. Avremo anche mostrato qualche composizione funzionale di base.

Perfetto?

Che cosa ci vuole perché un carosello sia "perfetto"? Deve essere accessibile da:

  • Mouse: Dovrebbe offrire i pulsanti precedente e successivo che siano facili da cliccare e non nascondere il contenuto.
  • Tocco: Dovrebbe monitorare il dito e poi scorrere con lo stesso moto come quando il dito si solleva dallo schermo.
  • Rotellina di scorrimento: Spesso trascurata, l'Apple Magic Mouse e i trackpad di molti notebook offrono lo scorrimento orizzontale morbido. Noi dovremmo sfruttare tali funzionalità!
  • Tastiera: Molti utenti preferiscono, o non sono in grado di utilizzare un mouse per la navigazione. È importante che facciamo il nostro carosello accessibile, così anche questi utenti possono utilizzare il nostro prodotto.

Infine, porteremo le cose a un ulteriore passo in più e renderemo questo un pezzo di UX sicuro e delizioso facendo in modo che il carosello risponda chiaramente e istintivamente con la fisica della forza elastica quando la barra di scorrimento raggiunge la fine.

Installazione

In primo luogo, prendiamo il codice HTML e CSS necessari per costruire un rudimentale carosello facendo un fork da questo CodePen.

La Pen è impostata con Sass come preprocessore CSS e Babel per fare transpiling in ES6 JavaScript. Ho incluso anche Popmotion, a cui si può accedere con window.popmotion.

Potete copiare il codice in un progetto locale, se preferite, ma è necessario garantire che il vostro ambiente supporti Sass ed ES6. È necessario anche installare Popmotion con npm install popmotion.

Creazione di un nuovo carosello

Su qualsiasi pagina, potremmo avere molti caroselli. Quindi abbiamo bisogno di un metodo per incapsulare lo stato e la funzionalità di ciascuno.

Ho intenzione di utilizzare una factory function anziché una class. Le factory function evitano la necessità di utilizzare la spesso confusa parola chiave this e semplifichereremo il codice ai fini di questa esercitazione.

Nel vostro editor di JavaScript, aggiungete questa semplice funzione:

Aggiungeremo il nostro codice specifico per il carosello all'interno di questa funzione carousel.

I come e i perché dello scorrimento

Il nostro primo compito è quello di fare lo scorrimento del carosello. Ci sono due modi con cui potremmo cavarcela:

Lo scorrimento nativo del browser

La soluzione più ovvia sarebbe quella di impostare overflow-x: scoll sulla barra di scorrimento. Questo permette modo lo scorrimento nativo su tutti i browser, inclusi dispositivi touch e con rotellina del mouse orizzontale.

Tuttavia, ci sono degli svantaggi con questo approccio:

  • Il contenuto all'esterno del contenitore non sarebbe visibile, cosa che può essere restrittiva per il nostro design.
  • Limita anche i modi con cui possiamo usare le animazioni per indicare che abbiamo raggiunto la fine.
  • I browser per il desktop avranno una barra di scorrimento orizzontale (anche se accessibile!) brutta.

In alternativa:

Animare translateX

Noi potremmo anche animare con la proprietà translateX del carosello. Questo sarebbe molto versatile poiché saremmo in grado di realizzare esattamente il disegno che ci piace. translateX è anche molto performante, a differenza della proprietà CSS left può essere gestito dalla GPU del dispositivo.

Il lato negativo è che dovremmo reimplementare la funzionalità di scorrimento utilizzando JavaScript. Che è più lavoro e più codice.

Come approcciano lo scorrimento Amazon e Netflix ?

I caroselli sia di Amazon che di Netflix fanno diversi compromessi nell'affrontare questo problema.

Amazon anima la proprietà left del carosello quando è in modalità "desktop". L'animazione left è una scelta incredibilmente povera, poiché cambiandola innesca un ricalcolo del layout. Questo è impegnativo per la CPU, e per le vecchie macchine sarà difficile lottare per raggiungere i 60fps.

Chiunque prenda la decisione di aggiungere un'animazione left invece di translateX deve essere un vero idiota (spoiler: io, nel 2012. Non eravamo di larghe vedute in quei giorni).

Quando viene rilevato un dispositivo touch, il carosello utilizza lo scorrimento nativo del browser. Il problema con l'attivazione di questo solo in modalità "mobile" è che gli utenti desktop con scorrimento della rotellina orizzontale lo perdono. Significa anche che qualsiasi contenuto di fuori del carosello dovrà essere visivamente tagliato:

Screenshot of Amazon illustrating lack of design bleed

Netflix anima correttamente la proprietà translateX del carosello, e lo fa su tutti i dispositivi. Questo consente loro di avere un design che esce fuori dal carosello:

Screenshot of Netflix carousel illustrating design bleed

Questo, a sua volta, permette loro di fare un disegno di fantasia dove gli elementi sono ingrossati di fuori dei bordi di x e y del carosello e gli elementi circostanti si spostino:

Screenshot of Netflix carousel illustrating enlarged item

Purtroppo, la reimplementazione dello scorrimento di Netflix per i dispositivi touch è insoddisfacente: utilizza un sistema di paginazione gestuale che sembra lento e macchinoso. Non c'è alcuna considerazione per le rotelline di scorrimento orizzontale.

Possiamo fare di meglio. Programmiamo!

Lo scorrimento come un professionista

La nostra prima mossa è quello di prendere il nodo .slider. Mentre siamo in argomento, prendiamo gli elementi che contiene così possiamo capire la dimensione della barra di scorrimento.

Misurare il carosello

Possiamo capire l'area visibile della barra di scorrimento misurando la larghezza:

Vogliamo anche la larghezza totale di tutti gli elementi contenuti all'interno. Per mantenere la nostra funzione carousel relativamente pulita, mettiamo questo calcolo in una funzione separata nella parte superiore del nostro file.

Utilizzando getBoundingClientRect per misurare l'offset left del nostro primo elemento e l'offset right del nostro ultimo elemento, possiamo usare la differenza tra loro per trovare la larghezza totale di tutti gli elementi.

Dopo la nostra misurazione di sliderVisibleWidth, scrivete:

Ora possiamo capire la distanza massima che il nostro carosello dovrebbe poter scorrere. È la larghezza totale di tutti i nostri elementi, meno una larghezza completa della nostra barra di scorrimento visibile. Ciò fornisce un numero che consente all'elemento più a destra di allinearsi alla destra della nostra barra di scorrimento:

Con queste misurazioni, siamo pronti per iniziare lo scorrimento del nostro carosello.

Impostazione di translateX

Popmotion è dotato di un renderer CSS per l'impostazione semplice e performante delle proprietà CSS. Inoltre è dotato di una funzione di valore che può essere utilizzata per tenere traccia dei numeri e, cosa importante (come vedremo presto), per interrogare la loro velocità.

Nella parte superiore del vostro file JavaScript, importateli in questo modo:

Quindi, sulla linea successiva impostate minXOffset, create un renderer CSS per la nostra barra di scorrimento:

E create un value per tenere traccia dell'offset di x della nostra barra di scorrimento e aggiornate la proprietà translateX della barra di scorrimento quando cambia:

Ora, spostando lo scorrimento orizzontalmente è semplice come scrivere:

Provatelo!

Scorrimento con tocco

Vogliamo che il nostro carosello inizi lo scorrimento quando un utente trascina la barra di scorrimento in senso orizzontale e arresti lo scorrimento quando un utente si ferma toccando lo schermo. I gestori eventi saranno simili a questo:

Nella nostra funzione startTouchScroll, vogliamo:

  • Interrompere qualsiasi azione che rafforzi sliderX.
  • Trovare il punto di tocco di origine.
  • Ascoltare il prossimo evento touchmove per vedere se l'utente sta trascinando orizzontalmente o verticalmente.

Dopo document.addEventListener, aggiungete:

Questo impedirà qualsiasi altra azione (come lo scorrimento d'impulso che implementeremo in stopTouchScroll) spostando la barra di scorrimento. Questo permetterà all'utente di "catturare" immediatamente la barra di scorrimento se scorre oltre un elemento o un titolo su cui vogliono cliccare.

Successivamente, abbiamo bisogno di memorizzare il punto di tocco di origine. Che ci permetterà di vedere dove l'utente sposta il dito dopo. Se è un movimento verticale, permetteremo lo scorrimento della pagina come al solito. Se si tratta di un movimento orizzontale, scorreremo invece la barra di scorrimento.

Vogliamo condividere questo touchOrigin tra i gestori di eventi. Così, dopo let action; aggiungete:

Indietro nel nostro gestore startTouchScroll, aggiungete:

Ora possiamo aggiungere un evento listener touchmove a document per determinare la direzione di trascinamento basata su questo touchOrigin:

La nostra funzione determineDragDirection sta per misurare la prossima posizione di tocco, verifica che effettivamente si è spostato e, in caso affermativo, misura l'angolo per determinare se è verticale o orizzontale:

Popmotion include alcune calcolatrici utili per misurare le cose come la distanza tra due coordinate x / y . Possiamo importarli così:

Quindi misurare la distanza tra i due punti è una questione di usare il calcolatore distance:

Ora se il tocco si è spostato, possiamo disattivare questo evento listener.

Misurate l'angolo tra i due punti con la calcolatore angle:

Possiamo usarlo per determinare se questo angolo è l'angolo orizzontale o verticale, passandolo alla seguente funzione. Aggiungete questa funzione in cima a tutto del nostro file:

Questa funzione restituisce true se l'angolo fornito è compreso tra -90 + /-45 gradi (verso l'alto) o 90 + /-45 gradi (verso il basso). Così possiamo aggiungere un'altra clausola return se questa funzione restituisce true.

Puntatore di rilevamento

Ora che sappiamo che l'utente sta tentando di scorrere il carosello, possiamo iniziare a tracciare il loro dito. Popmotion offre un'azione del puntatore che visualizzerà le coordinate x / y del puntatore del mouse o del tocco.

In primo luogo, importate pointer:

Per monitorare l'input del tocco, fornite l'origine dell'evento a pointer:

Vogliamo misurare la posizione iniziale di x del nostro puntatore e applicare qualsiasi movimento alla barra di scorrimento. Per questo, possiamo usare un trasformatore chiamato applyOffset.

I trasformatori sono funzioni pure che accettano un valore e lo restituiscono — sì — trasformato. Per esempio: const double = (v) => v * 2.

applyOffset è una funzione con applicazione parziale. Ciò significa che quando lo chiamiamo, viene creata una nuova funzione a cui può quindi essere passato un valore. In primo luogo la chiamiamo con un numero da cui vogliamo misurare l'offset, in questo caso il valore corrente di action.x e un numero da applicare a tale offset. In questo caso, è il nostro sliderX.

Quindi la nostra funzione applyOffset sarà simile a questa:

Ora possiamo usare questa funzione nel callback output del puntatore per applicare il movimento del puntatore alla barra di scorrimento.

Fermarsi con stile

Il carosello è ora trascinabile con il tocco! È possibile verificarlo utilizzando l'emulazione di dispositivi in strumenti per sviluppatori di Chrome.

Sembra un po' scadente, giusto? Potresti aver incontrato lo scorrimento che sembra come prima: si solleva il dito, e lo scorrimento si interrompe di colpo. O lo scorrimento si interrompe di colpo e poi una piccola animazione riprende a falsificare una continuazione dello scorrimento.

Non intendiamo far ciò. Possiamo usare l'azione fisica di Popmotion per prendere la vera velocità di sliderX e applicare l'attrito ad esso per un periodo di tempo.

In primo luogo, aggiungetelo alla nostra lista crescente di importazioni:

Quindi, alla fine della nostra funzione stopTouchScroll, aggiungete:

Qui, from e velocity vengono impostati con il valore corrente e la velocità di sliderX. Questo garantisce che la nostra simulazione fisica ha le stesse condizioni di partenza iniziale del movimento di trascinamento dell'utente.

friction è impostato a 0.2. Friction è impostato come un valore da 0 a 1, dove 0 non rappresenta nessun attrito e 1 attrito assoluto. Provate a giocare con questo valore per vedere il cambiamento che rende alla "sensazione" del carosello quando un utente interrompe il trascinamento.

Numeri più piccoli lo faranno sentire più leggero e i numeri più grandi faranno il movimento più pesante. Per un movimento di scorrimento, sento che 0.2 sia un buon bilanciamento tra lento e irregolare.

Limiti

Ma c'è un problema! Se avete giocato con il vostro nuovo carosello, è ovvio. Noi non abbiamo delimitato il movimento, rendendo possibile di buttare via letteralmente il carosello!

C'è un altro trasformatore per questo lavoro, clamp. Questa è anche una funzione con applicazione parziale, il cui significato è che se la chiamiamo con un valore minimo e massimo, diciamo 0 e 1, restituirà una nuova funzione. In questo esempio, la nuova funzione limiterà qualsiasi numero dato ad esso compreso tra 0 e 1:

In primo luogo, importate clamp:

Vogliamo utilizzare questa funzione di bloccaggio attraverso il nostro carosello, allora aggiungete questa linea dopo che definiamo minXOffset:

Stiamo andando a modificare i due output che abbiamo impostato sulle nostre azioni utilizzando alcun leggere composizioni funzionali con il trasformatore pipe.

Pipe

Quando chiamiamo una funzione, la scriviamo così:

Se vogliamo dare l'output di tale funzione a un'altra funzione, noi potremmo scriverla così:

Questo diventa un po' difficile da leggere, ed è sempre peggio, se aggiungiamo ancora più funzioni.

Con pipe, noi possiamo comporre una nuova funzione fuori di foo e bar che possiamo riutilizzare:

È anche scritto in un inizio naturale -> ordine di arrivo, che lo rende più facile da seguire. Possiamo usare questo per comporre applyOffset e clamp in un'unica funzione. Importate pipe:

Sostituite il callback di output del nostro pointer con:

E sostituite il callback di output di physics con:

Questo tipo di composizione funzionale può ordinatamente creare processi descrittivi passo dopo passo dalle funzioni più piccole e riutilizzabili.

Ora, quando trascinate e lanciate il carosello, esso non si muove all'esterno dei suoi limiti.

La fermata brusca non è molto soddisfacente. Ma questo è un problema per una parte successiva!

Conclusioni

Questo è tutto per la parte 1. Finora, abbiamo dato un'occhiata ai caroselli esistenti per vedere la forza e la debolezza dei diversi approcci allo scorrimento. Abbiamo utilizzato l'input di rilevamento di Popmotion e di fisica per animare con efficienza il translateX del nostro carosello con lo scorrimento tramite tocco. Abbiamo anche introdotto la composizione funzionale e le funzioni ad applicazione parziale.

Si può prendere una versione commentata del "riassunto della situazione" su questo CodePen.

Nelle prossime puntate, vedremo:

  • lo scorrimento con la rotellina del mouse
  • rimisurazione del carosello quando la finestra viene ridimensionata
  • impaginazione, con accessibilità da tastiera e mouse
  • tocchi deliziosi, con l'aiuto della fisica della forza elastica

Non vedo l'ora di vedervi lì!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.