Disegnare con Two.js

La grafica avanzata è una grande parte del web in questi giorni, ma ci sono un paio di diversi renderer nel mix. Potresti usare la tela, ovviamente; ma SVG e WebGL sono anche opzioni. In questo tutorial, esamineremo una libreria di disegni relativamente nuova, two.js, che fornisce un'API che fa la stessa cosa con tutti e tre questi renderer. Se sei pronto, diamo un'occhiata!


Passaggio 1: impostazione

Il primo passo è creare un Due istanza e metterlo sulla pagina. Il Due contstructor prende un oggetto con un numero di parametri:

 var two = new Two (fullscreen: true);

In questo caso, stiamo usando il a schermo intero opzione, che rende l'area di disegno occupata dall'intera finestra del browser. Se volessimo che la nostra area di disegno avesse una dimensione specifica, potremmo usare il larghezza e altezza proprietà invece; entrambi prendono un numero per un valore in pixel. C'è anche il avvio automatico parametro; se è impostato su true, qualsiasi animazione verrà eseguita immediatamente quando la pagina viene caricata.

C'è anche il genere parametro: questo decide quale renderer sarà usato. Puoi scegliere tra canvas, SVG e WebGl. Non si digita semplicemente il nome, però: si utilizza una costante di tipo libreria: o Two.Types.canvas, Two.Types.svg, o Two.Types.webgl. Per essere chiari, two.js utilizzerà solo SVG; non esegue alcun tipo di rilevamento di funzionalità per vedere cosa il browser supporterà. Dovrai farlo da solo (e penso che sia una buona idea: piccoli strumenti, una cosa, e tutto il resto).

Quindi, una volta che abbiamo un Due esempio, cosa facciamo con esso. Innanzitutto, ti consigliamo di aggiungerlo alla pagina. Ha un appendTo metodo che accetta un elemento HTML come parametro, quindi impostiamo questo:

 

Quindi, in main.js, iniziamo con questo:

 var el = document.getElementById ("main"), two = new Two (fullscreen: true); two.appendTo (EL);

Con tutto questo, siamo pronti per disegnare alcune forme.


Passo 2 - Disegnare forme base

Inizieremo con le forme di base; mentre possiamo creare le nostre forme complesse con nuovo Two.Polygon, forme più semplici possono essere fatte con pochi metodi a portata di mano.

Iniziamo con le cerchie. Il makeCircle la funzione richiede tre parametri:

 var circle = two.makeCircle (110, 110, 100); circle.fill = "# 881111"; two.update ();

Esamineremo dal basso verso l'alto: la chiamata a two.update gli aggiornamenti stanno disegnando l'area e rendono effettivamente il contenuto. Tornando al cerchio, i primi due parametri sono le coordinate xey per il centro del cerchio. Quindi, il terzo parametro è il raggio per il cerchio. Tutti i two.make ... le funzioni restituiscono a Two.Polygon oggetto. Mentre seguiamo questo tutorial, vedrete diverse proprietà e metodi che è possibile utilizzare su queste forme. Ecco il primo: riempire. Come puoi immaginare, imposta il colore di riempimento: qualsiasi CSS valido lo farà.

Il risultato dovrebbe essere simile a questo:

Ora, per quanto riguarda i rettangoli? Il two.makeRectangle il metodo richiede quattro parametri. Proprio come il cerchio, i primi due parametri segnano il X e y coordinate per il centro del rettangolo. Quindi, param tre è larghezza e param four è il altezza del rettangolo.

 var rect = two.makeRectangle (115, 90, 150, 100); rect.fill = "orange"; rect.opacity = 0,25; rect.noStroke (); two.update ();

Di nuovo, stiamo usando il riempire proprietà. Stiamo anche utilizzando il opacità proprietà, che accetta un valore decimale compreso tra 0 e 1; qui abbiamo il quarto di opacità. Finalmente, stiamo usando il noStroke metodo, che rimuove il tratto (bordo) dal rettangolo. Ecco cosa abbiamo:

Anche le ellissi sono piuttosto semplici: come puoi immaginare, i primi due parametri impostano il centro dell'ellisse. Quindi, abbiamo larghezza e altezza:

 var ellipse = two.makeEllipse (100, 40, 90, 30); ellipse.stroke = "# 112233"; ellipse.linewidth = 5; ellipse.noFill (); two.update ();

Per le nuove proprietà: abbiamo ictus, che imposta il colore del bordo; per impostare la larghezza di quel bordo, usiamo il larghezza della linea proprietà. Quindi, ricorda noStroke? Il noFill il metodo è lo stesso, tranne che rimuove il colore di riempimento per la nostra forma (senza che le nostre forme siano predefinite in un riempimento bianco).

Certo, le forme più semplici sono le linee.

 var line = two.makeLine (10, 10, 110, 210); line.linewidth = 10; line.stroke = "rgba (255, 0, 0, 0.5)";

I primi due parametri sono i X e y per un capo della linea; il secondo set sono per l'altra estremità.

Probabilmente la forma più difficile da creare è la curva. Il two.makeCurve il metodo accetta tanti set di x, y parametri come desideri - ogni coppia è un punto in cui la linea si curva. Quindi, l'ultimo parametro è un booleano: fallo vero se la forma è aperta, significa che le estremità non si connettono. Se desideri che two.js disegni una linea che collega le due estremità delle curve, dovrebbe essere così falso.

 var curve = two.makeCurve (110, 100, 120, 50, 140, 150, 160, 50, 180, 150, 190, 100, true); curve.linewidth = 2; curve.scale = 1.75; curve.rotation = Math.PI / 2; // Quarter-turn curve.noFill ();

Sai larghezza della linea, ma per quanto riguarda scala? Possiamo usare questo per restringere o espandere la nostra forma; qui, stiamo espandendo la forma del 175%. Quindi, possiamo usare rotazione ruotare la nostra forma di un numero di radianti; stiamo facendo 90 gradi, che è mezzo radianti PI.

Infine, si potrebbe pensare che dal momento che abbiamo reso la forma aperta, non otterremo un riempimento; ma non è vero. Una curva non chiusa avrà ancora un riempimento, quindi stiamo usando noFill per rimuovere il riempimento e finire con solo la curva.

L'ultimo tipo di forma è il catch-all: è il poligono generale. In realtà, è praticamente come la curva, eccetto che le linee vanno dritte da un punto all'altro.

 var poly = two.makePolygon (110, 100, 120, 50, 140, 150, 160, 50, 180, 150, 190, 100); poly.linewidth = 4; poly.translation = new Two.Vector (60, 60); poly.stroke = "#cccccc"; poly.fill = "#ececec";

Come con la curva, abbiamo tante coppie di coordinate quante vorremmo, e quindi il booleano aperto; qui lo stiamo impostando falso, quindi la forma sarà chiusa.

Stiamo anche impostando a traduzione Qui; questo ci consente di spostare la forma a sinistra o a destra e in alto o in basso. Stiamo impostando il traduzione proprietà a a Two.Vector esempio. Il Two.Vector costruttore richiede due parametri: an X e a y. Questi finiscono per essere le coordinate per il centro della forma. In realtà non devi creare un nuovo vettore per questo; puoi semplicemente assegnare il X e y directory dei valori:

 poly.translation.x = 60; poly.translation.y = 60;

Ecco cosa otteniamo:


Passaggio 3: creazione di gruppi

Finora, abbiamo lavorato con singoli oggetti di forma; tuttavia, è possibile raggruppare le forme insieme e interagire con esse come un unico pezzo.

Puoi creare un gruppo con il two.makeGroup metodo. Quindi, possiamo usare il suo Inserisci metodo per aggiungere una forma al gruppo.

 var group = two.makeGroup (), rect = two.makeRectangle (0, 0, 100, 100), circ = two.makeCircle (50, 50, 50);

rect.fill = "red"; circ.fill = "blue"; group.add (rect); group.add (circ); two.update ();

Se lo gestisci, è piuttosto semplice; proprio come faresti senza gruppo bit.

Ma poi, possiamo lavorare con il gruppo, usando una qualsiasi delle trasformazioni che possiamo fare su una singola forma. Ad esempio, che ne dici di una traduzione?

 group.translation.x = 100; group.translation.y = 100; two.update ();

Come con le forme regolari, i gruppi vengono ordinati dal back-to-front al momento della creazione. Tuttavia, se aggiungi una forma a un gruppo e quindi a un altro gruppo, questa verrà rimossa dal primo gruppo. Questo è fantastico se hai bisogno di cambiare l'ordine delle forme in avanti e indietro durante l'animazione (che otterremo). Quindi, se iniziamo con questo:

 var topGroup = two.makeGroup (), bottomGroup = two.makeGroup (), rect = two.makeRectangle (100, 100, 100, 100), circ = two.makeCircle (150, 150, 50); rect.fill = "red"; circ.fill = "blue"; topGroup.add (rect); topGroup.add (circ); two.update ();

Abbiamo lo stesso di sopra:

Ma, se aggiungiamo il rect al bottomGroup anziché…

 bottomGroup.add (rect);

Ora, il nostro quadrato è in cima.

Passaggio 4: animare le forme

Infine, parliamo dell'animazione. Sai già che two.js rende le forme che hai creato quando chiami two.update (). Se chiami two.play () invece, è come chiamare aggiornare() ripetutamente, usando Request Animation Frame. Ogni volta che ciò accade, two.js attiva un evento di "aggiornamento". Ecco come possiamo produrre animazione: ascoltate l'evento "aggiornamento"; e quando succede, esegui una funzione per impostare il fotogramma successivo.

I nostri esempi finora sono stati piuttosto semplici, quindi facciamo un passo avanti: creeremo un pianeta orbitante con la sua luna orbitale. Ricorda, iniziamo creando due istanze:

 var el = document.getElementById ("main"), two = new Two (fullscreen: true). appendTo (el);

Successivamente, abbiamo bisogno di impostare alcune variabili.

 var earthAngle = 0, moonAngle = 0, distance = 30, raggio = 50, padding = 100, orbita = 200, offset = orbita + padding, orbite = two.makeGroup ();

Aumenteremo earthAngle e moonAngle per ottenere il nostro pianeta e la luna attorno alle loro orbite. Il distanza variabile è quanto lontano sarà la nostra luna dalla nostra terra. Il raggio è il raduis del nostro pianeta terra, e il imbottitura è quanto spazio avrà il nostro pianeta fuori dalla sua orbita. Detto orbita viene dal orbita variabile. Il compensare variabile è quanto lontano sarà il nostro pianeta spostato dal bordo della tela. Finalmente, il orbite il gruppo terrà i due cerchi dell'orbita, che ci permetteranno di mostrarli o nasconderli a volontà. Non ti preoccupare se sei un po 'confuso; vedrai come lavoreranno tutti insieme in un secondo.

Inizieremo con la linea dell'orbita terrestre. Certo, è solo un semplice cerchio:

 var earthOrbit = two.makeCircle (offset, offset, orbita); earthOrbit.noFill (); earthOrbit.linewidth = 4; earthOrbit.stroke = "#ccc"; orbits.add (earthOrbit); two.update ();

Non c'è niente di nuovo qui. Ecco cosa dovresti vedere:

Quindi, dobbiamo creare un pianeta e posizionarlo sulla sua orbita. In primo luogo, abbiamo bisogno di un mezzo per capire dove si trova l'orbita attorno al pianeta; e, naturalmente, questo deve cambiare per ogni frame di animazione. Quindi, creiamo una funzione che restituirà il centro X e y coordinate per l'orbita in base all'angolo corrente per il posizionamento attorno al cerchio e il raggio dell'orbita:

 function getPositions (angle, orbit) return x: Math.cos (angle * Math.PI / 180) * orbita, y: Math.sin (angolo * Math.PI / 180) * orbita; 

Sì, è un po 'di trigonometria, ma non preoccuparti troppo: in pratica, stiamo convertendo l'angolo (che è un grado) in un radiante, usando i metodi sinusoidale e coseno di JavaScript, e quindi moltiplicandolo per il orbita. Ora, possiamo usare questa funzione per aggiungere la terra alla foto:

 var pos = getPositions (earthAngle ++, orbit), earth = two.makeCircle (pos.x + offset, pos.y + offset, raggio); earth.stroke = "# 123456"; earth.linewidth = 4; earth.fill = "# 194878";

Iniziamo prendendo la posizione per il primo earthAngle (valore di 0, ricorda?); allora, facciamo il nostro terra basato su quelle posizioni (più l'offset) e colorarlo. Ecco cosa finiamo con:

Ora, animiamo questo pianeta. Il codice di associazione degli eventi proviene direttamente da Backbone, quindi potrebbe sembrare familiare:

 two.bind ("update", function (frameCount) var pos = getPositions (earthAngle ++, orbita); earth.translation.x = pos.x + offset; earth.translation.y = pos.y + offset;); two.play ();

Quello che sta succedendo qui è che ogni volta il aggiornare evento si verifica, stiamo usando il getPositions funzione per calcolare la posizione per l'angolo successivo sulla terra. Quindi, dobbiamo solo impostare il centro della terra in quelle nuove posizioni, oltre all'offset. Infine, chiamiamo two.play () per avviare gli eventi di aggiornamento. Se ricarichi la pagina ora, dovresti vedere la terra che gira attorno all'orbita.

Bel lavoro finora, eh? Ora, che ne dici della luna e del suo percorso orbitale? questo andrà al di sopra del legare dichiarazione.

 var moonOrbit = two.makeCircle (earth.translation.x, earth.translation.y, raggio + distance); moonOrbit.noFill (); moonOrbit.linewidth = 4; moonOrbit.stroke = "#ccc"; orbits.add (moonOrbit); var pos = getPositions (moonAngle, radius + distance), moon = two.makeCircle (earth.translation.x + pos.x, earth.translation.y + pos.y, raggio / 4); moonAngle + = 5; moon.fill = "# 474747";

Questo assomiglia molto al codice per il pianeta: noi centriamo il cerchio dell'orbita della luna al centro della terra usando il suo traduzione proprietà; il suo raggio è il raggio della terra più la distanza che la luna dovrebbe essere lontana dalla terra. Di nuovo, aggiungiamo il moonOrbit al orbite gruppo.

Successivamente, creiamo la luna, prima ottenendo la sua posizione desiderata e creando un cerchio in quella posizione. Per un raggio, useremo un quarto del raggio che abbiamo usato per la terra. Incrementeremo l'angolo della luna di 5 ogni volta, quindi si muoverà più velocemente della terra.

Disattivare l'animazione (commentando il two.bind dichiarazione), otteniamo questo:

Ultimo passo: animare la luna. Dentro quello stesso two.bind dichiarazione, aggiungi queste righe:

 var moonPos = getPositions (moonAngle, raggio + distanza); moon.translation.x = earth.translation.x + moonPos.x; moon.translation.y = earth.translation.y + moonPos.y; moonAngle + = 5; moonOrbit.translation.x = earth.translation.x; moonOrbit.translation.y = earth.translation.y;

Proprio come prima, otteniamo la nuova posizione per la luna e la posizioniamo rispetto alla terra. Quindi, spostiamo anche l'anello dell'orbita lunare in modo che rimanga centrato sulla terra.

Con tutto questo a posto, il nostro piccolo esempio è completo: ecco una foto dell'azione:

Come ho detto, possiamo anche nascondere le orbite. Dal momento che sono entrambi nel orbite gruppo, possiamo usare il visibile proprietà del gruppo:

 orbits.visible = false;

E adesso:


Conclusione

Bene, questa è una conclusione su questo tutorial. Pensi che userai two.js in uno dei tuoi progetti? O forse hai un'alternativa migliore? Ne sentiamo parlare nei commenti!