Filmati FLASH on demand (I Parte)
Pensavate di aver già fatto tutto con il PHP? Male! Scopriamo insieme come utilizzare al meglio l'estensione MING di PHP per la generazione di filmati Macromedia Flash con contenuto dinamico.
Tra le innumerevoli possibilità del linguaggio di programmazione per il web PHP c'è un interessantissimo supporto a librerie per la creazione dinamica della grafica di un sito. Grazie infatti alle funzioni dell'estensione GD, è possibile generare al volo, e soltanto con linee di codice,
|
| Figura 1 - L’home page di MING, la libreria oggetto di questo articolo con la quale è possibile realizzare filmati con tutte le caratteristiche più importanti di Flash. |
qualsiasi immagine nei formati JPEG e PNG, e grazie alle
librerie LibSWF e MING, con PHP diventa possibile anche la
creazione di immagini e filmati SWF (ShockWave Flash), il
formato per le animazioni in grafica vettoriale progettato da
Macromedia prettamente per il web.
Flash arricchisce il web di una multimedialità e di
un'interattività mai viste prima, ed è
ormai presente ovunque in Rete, visualizzabile dalla quasi
totalità degli utenti Internet; inoltre grazie alla
disponibilità delle specifiche del formato, rilasciate
al pubblico (vedi www.openswf.org), è supportato da
sempre più applicazioni di grafica.
MING
Oggetto dell'articolo sarà la libreria MING (http://ming.sourceforge.net), scritta in C, e
utilizzabile, oltre che da applicazioni scritte in questo
linguaggio, soprattutto in ambienti di programmazione
orientati agli oggetti come C++, Python, e ovviamente PHP (la
cui estensione è stata inserita dalla versione 4.0.5).
L'ultima versione è la 0.2a, e anche se il numero
possa far pensare a qualcosa di ancora non molto usabile, con
MING è invece possibile realizzare filmati con tutte
le caratteristiche più importanti di Flash; inoltre,
anche se il progetto da svariati mesi è stato fermo, a
causa della mancanza di tempo disponibile all'unico
sviluppatore (che ha adesso affidato in nuove mani la
continuazione del lavoro), ci sono buone probabilità,
grazie soprattutto alla disponibilità del codice
sorgente, che le funzionalità vengano estese a ogni
futura caratteristica di Flash.
La libreria
MING è strutturata in classi, ideate per ogni elemento
peculiare di Flash: ogni nuovo oggetto di una classe di MING
creato disporrà infatti di numerose funzioni in grado
di impostare quasi ogni proprietà che è
possibile gestire utilizzando ad esempio il software di
authoring visivo Flash. È dunque uno strumento
decisamente potente, e con la pratica, anche semplice da
utilizzare.
Creazione di un nuovo filmato
Per creare un nuovo filmato è necessario utilizzare
un nuovo oggetto per la classe SWFMovie(), utilizzando
l'operatore new:
$filmato = new SWFMovie();
Per configurare tutte le proprietà del filmato, basta utilizzare le apposite funzioni, descritte nella classe SWFMovie(), e richiamabili dall'oggetto $filmato appena creato. Ad esempio, potremmo impostarne le dimensioni, con
$filmato -> setDimension(320, 240);
dove il primo valore numerico sta per la larghezza in pixel ed il secondo per l'altezza; oppure scegliere un colore di sfondo, nel nostro caso verde chiaro, con la funzione
$filmato -> setBackground(0, 255, 0);
dove i valori numerici si riferiscono alla scala di colore RGB in valori da 0 a 255 per ogni colore primario, rosso, verde e blu. Potremmo inoltre definire proprietà come la velocità in fotogrammi per secondo (fps), il cui valore predefinito in Flash è 12, con la funzione:
$filmato -> setRate(12.0);
E anche un MP3 di sottofondo, con la funzione streamMP3(), da specificare come argomento per mezzo della funzione standard di apertura file fopen():
$filmato -> streamMP3(fopen("suono.mp3" , "rb"));
|
| Figura 2 – Linea retta e poligono. |
Inoltre sempre con l'oggetto #$filmato#, si accede alla funzione per passare al fotogramma successivo,
$filmato -> nextFrame();
e per creare dinamicamente il filmato in output oppure salvarlo in un file, con una delle due funzioni
$filmato->output();
oppure
$filmato -> save("filmato.swf");
Creazione di poligoni e linee rette
Prima della creazione dell'oggetto relativo al filmato,
abitualmente si procede con la definizione di forme, testo,
immagini e di tutto il suo contenuto. Inizieremo con il
disegno di una semplicissima linea retta, dopo aver
dichiarato un nuovo oggetto per la classe SWFShape():
$forma = new SWFShape();
Successivamente configureremo gli attributi della linea da tracciare; ad esempio, con la funzione setLine() è possibile scegliere in ordine: lo spessore, il colore secondo i tre valori RGB da 0 a 255, ed un quinto opzionale parametro riguardante la trasparenza (canale alpha) ed il suo eventuale valore sempre in scala da 0 a 255:
$forma -> setLine(3, 255, 0, 0);
La linea sarà dunque spessa 3 pixel, e di colore rosso saturo. Definite le caratteristiche, non resta che tracciarla: innanzitutto bisogna posizionare la "penna" nelle coordinate x,y dell'inizio del tracciato (a tal proposito ricordiamo che l'origine degli assi 0,0 in Flash risiede nel vertice dell'angolo in alto a sinistra), ad esempio:
$forma -> movePenTo(50, 50);
Subito dopo potremmo disegnare effettivamente la linea unendo il punto delle coordinate correnti, settate con movePenTo() e il punto definito dalla funzione di disegno linea drawLineTo(), come di seguito:
$forma -> drawLineTo(100, 50);
È dunque facile immaginare come sia semplice ed immediato realizzare poligoni, quadrati, rettangoli, rombi, con questa procedura: basterà semplicemente disegnarne ogni lato con la funzione drawLineTo(), con cui specificare coordinate assolute, oppure con la funzione gemella drawLine(), a cui passare coordinate relative. Ad esempio, per disegnare un quadrato, basteranno le seguenti linee di codice:
$quadrato=new SWFShape(); $quadrato->setLine(1, 0, 0, 0); $quadrato->movePenTo(0, 0); $quadrato->drawLineTo(0, 80); $quadrato->drawLineTo(80, 80); $quadrato->drawLineTo(80, 0); $quadrato->drawLineTo(0, 0);
Per tracciare linee chiuse e poligoni, è necessario prendere in considerazione come effettuare un loro eventuale riempimento.
|
| Figura 3 – Linee, curve e cerchi. |
Ebbene con MING è possibile utilizzare tutti i tipi di riempimento supportati da Flash, ovvero con colore solido, gradiente, o immagine bitmap; tuttavia è bene sapere che innanzitutto per attribuire un riempimento vengono utilizzate due funzioni: una per impostare le sue caratteristiche, ed un'altra successivamente per abbinarlo alla forma e renderlo attivo. Ad esempio, definiamo per il nostro quadrato un riempimento di colore solido blu semitrasparente:
$riempimentoQuadrato= $quadrato->addFill(0, 0, 150, 100);
Adesso, per applicarlo, sarà necessario utilizzare una delle due funzioni messe a disposizione da MING: setRightFill() se il nostro poligono sarà disegnato in senso orario, e setLeftFill() se in senso antiorario (come nel caso del nostro quadrato):
$quadrato-> setLeftFill($riempimentoQuadrato);
Ovviamente le funzioni di riempimento dovranno precedere
quelle di tracciatura.
|
| Figura 4 – Simboli e istanze con esempi di trasformazione. |
Creazione di curve di bezier e cerchi
A questo punto, a chi abbia qualsivoglia esperienza con
l'interfaccia di editing di Flash, sarà
sicuramente presente il numero di strumenti di disegno
messi a disposizione dal programma (mano libera, rettangolo/quadrato, ovale/cerchio, retta, curva di bezier): ebbene l'implementazione più difficile in MING risulta il disegno a mano libera, dal momento che questo dovrebbe essere ideato punto per punto. Ma per linee rette, rettangoli e altri poligoni abbiamo visto che procedura seguire, indiscutibilmente flessibile, grazie alla possibilità di associare anche funzioni personalizzate per automatizzare le operazioni e ottimizzare il codice; questo tuttavia vale anche per le curve di bezier, ovali e cerchi, che è possibile realizzare per mezzo della funzione drawCurveTo(), a cui passare come primi due argomenti le coordinate del punto di controllo, e come terzo e quarto le coordinate del punto di collegamento. Ad esempio, le seguenti linee di codice produrranno la linea curva verde come in figura 3:
$curva = new SWFShape(); $curva->setLine(5, 0, 200, 0, 220); $curva->movePenTo(25, 50); $curva->drawCurveTo(50, 0, 75, 50); $curva->drawCurveTo(100, 100, 125, 50); $curva->drawCurveTo(200, 50, 150, 100);
Per realizzare cerchi, invece, la procedura per il momento si complica leggermente. In MING infatti non esiste ancora una funzione immediata per la generazione di una circonferenza, e solo recentemente, lo stesso autore della libreria ha suggerito, in un messaggio alla mailing-list, alcune linee di codice per crearla tramite la funzione drawCurveTo(). È molto probabile tuttavia che nelle future versioni della libreria esisterà un supporto migliore ed una funzione dedicata, più immediata e semplice da utilizzare; per il momento si potrà utilizzare una funzione come quella seguente (disponibile anche tra gli esempi sul cdrom):
function drawCircle($forma, $raggio,
$x, $y){
$a = $raggio * 0.414213562;
$b = $raggio * 0.707106781;
$forma->movePenTo($x+$raggio, $y);
/* Creazione della circonferenza dalle
curve */
$forma->drawCurveTo($x+$raggio,
$y-$a, $x+$b, $y-$b);
$forma->drawCurveTo($x+$a,
$y-$raggio, $x, $y-$raggio);
$forma->drawCurveTo($x-$a,
$y-$raggio, $x-$b, $y-$b);
$forma->drawCurveTo($x-$raggio,
$y-$a, $x-$raggio, $y);
$forma->drawCurveTo($x-$raggio,
$y+$a, $x-$b, $y+$b);
$forma->drawCurveTo($x-$a,
$y+$raggio, $x, $y+$raggio);
$forma->drawCurveTo($x+$a,
$y+$raggio, $x+$b, $y+$b);
$forma->drawCurveTo($x+$raggio,
$y+$a, $x+$raggio, $y);
}
Successivamente potrà essere richiamata nel contesto di una nuova forma, ad esempio dopo aver stabilito i valori per il contorno ed il riempimento, e fornendo come argomenti la variabile dell'oggetto associato, la misura del raggio, e le coordinate x,y del centro:
$cerchio = new SWFShape(); $cerchio->setLine(1, 200, 0, 100, 200); $riempimentoCerchio=$cerchio-> addFill(50, 0, 200, 150); $cerchio-> setRightFill($riempimentoCerchio); drawCircle($cerchio2, 40, 150, 130);
Seguendo tali accorgimenti, anche la creazione di cerchi diventa semplice.
|
| Figura 5 – Esempio di inserimento di testo e di un'immagine. |
Simboli ed istanze
Una delle caratteristiche principali della grafica
vettoriale in generale, e di Flash in particolare, e insieme
una delle abitudini più importanti per l'autore di
un filmato SWF sono la gestione di una libreria di simboli e
l'utilizzo delle loro istanze. Per chi non avesse chiaro
l'argomento, ad esempio per chi non abbia mai utilizzato
il software di authoring Flash,
per mezzo di un paragone con la programmazione ad oggetti, sarà facile interpretare un simbolo come una classe e la sua istanza come un oggetto. L'utilizzo di simboli in Flash è importante nel caso di ripetizione di forme molto simili, in quanto oltre a velocizzare il lavoro, consentono di alleggerire considerevolmente la dimensione di un filmato; ogni istanza del simbolo successivamente potrà essere modificata nei suoi attributi, ad esempio riscalata, ruotata, o anche colorata diversamente. Con la creazione di forme tramite la classe SWFShape() di MING già creiamo simboli grafici; per la creazione invece di movieclip, basterà utilizzare una nuova classe SWFSprite(), che dispone di alcune funzioni come nextFrame() analogamente a SWFMovie(); mentre per la creazione di pulsanti esiste la classe SWFButton(). Ma vediamo come aggiungere nel filmato un'istanza di qualche forma tra quelle che abbiamo già creato (infatti le forme finora sono state create, o meglio definite, ma non ancora "aggiunte" al filmato):
$istanzaQuadrato=$filmato-> add($quadrato);
|
| Figura 6 – Un fotogramma di un'interpolazione forma. |
Con la funzione add() dell'oggetto $filmato abbiamo aggiunto il quadrato creato in precedenza, alla cui istanza d'ora in poi ci riferiremo per mezzo della variabile $istanzaQuadrato. Ad esempio nella figura 4 (che mostra il risultato del file simboli.php) è possibile notare vari esempi di modifica di varie istanze di due soli simboli, un quadrato giallo ed un poligono azzurro, creati inizialmente con le funzioni di SWFShape() e successivamente modificati, con alcune funzioni specifiche per le istanze, come di seguito elencate:
- moveTo() e move() per posizionare l'istanza rispettivamente in coordinate assolute e relative;
- rotateTo() e rotate() per ruotare l'istanza di un numero di gradi rispettivamente assoluto o relativo;
- scaleTo() e scale() per ridimensionare l'istanza rispettivamente in coordinate assolute e relative (con scaleTo() è anche possibile fornire un unico valore decimale compreso tra 0 e 1);
- skewXTo(), skewX() e skewYTo(), skewY() per inclinare l'istanza secondo un valore decimale assoluto o relativo, sull'asse X o Y; il valore 1.0 si riferisce ad un'inclinazione di 45 gradi.
- setDepth() per impostare l'ordine di visualizzazione degli elementi del filmato; se non specificato, quelli creati per ultimi si posizioneranno sopra quelli creati in precedenza.
- setName(): per definire un nome, utile per richiamare successivamente l'istanza in eventuale codice ActionScript;
- addColor() e multColor(): per modificare il colore di un oggetto, rispettivamente aggiungendo o moltiplicando i valori correnti con quelli specificati;
- remove(): per rimuovere l'oggetto.
Nei prossimi paragrafi vedremo come gestire gli altri tipi di simboli, ovvero i clip filmato (movieclip) e i pulsanti.