Posts Tagged ‘Actionscript’

Actionscript BitmapData per la gestione di immagini come in libreria

// ottobre 26th, 2007 // 3 Comments » // Sviluppo e tips

La classe BitmapData (flash.display.BitmapData) ci permette di creare e manipolare in piena libertà le immagini tramite Actionscript per la creazione di effetti altrimenti irrealizzabili con i filtri messi a disposizione nell’apposito pannello di Flash.
Un oggetto BitmapData contiene tutte le informazioni sui pixel dell’immagine e può essere assegnato a un MovieClip utilizzando il metodo MovieClip.attachBitmap().
Gli usi possibili della classe BitmapData sono tantissimi e per una trattazione più specifica vi rimando alla guida ufficiale. Io invece mi vorrei soffermare su un uso molto utile di BitmapData nella gestione delle immagini (JPEG, GIF, PNG) caricate esternamente in quei casi in cui si ha il bisogno di riutilizzare più volte le immagini caricate.
Immagino abbiate presente l’utilizzo del metodo MovieClip.attachMovie() per “attaccare” un elemento in libreria a un MovieClip presente sullo stage. Il MovieClip in libreria dovrà essere stato identificato per il Linkage.
In un modo simile possiamo sfruttare il metodo MovieClip.attachBitmap() per gestire, come se le avessimo il libreria pronte all’uso, delle immagini caricate dall’esterno in un determinato momento del nostro movie Flash: vediamo come è possibile ricreare una situazione di questo genere in ActionScript.

Supponiamo che ad un certo istante del nostro movie venga chiamata una funzione che carica N immagini, che per comodità definiremo in un array ma che potrebbero anche essere definite in una struttura XML o altro.
Quindi prendiamo in esame il seguente codice incaricato del caricamento sequenziale delle immagini contenute nella cartella img in un MovieClip temporaneo temp che verrà rimosso al termine di ogni caricamento:

var imgPath = new Array("img/photo1.jpg","img/photo2.jpg");
var count:Number = 0;
function loadImage():Void{
	_root.createEmptyMovieClip("temp", _root.getNextHighestDepth());
	var mcl = new MovieClipLoader();
	var myListener = new Object();
	myListener.onLoadInit = function(target_mc) {
		target_mc.removeMovieClip();
		if(_root.count<_root.imgPath.length-1){
			_root.count++;
			_root.loadImage();
		} else {
			trace("Finito");
		}
	}
	mcl.addListener(myListener);
	mcl.loadClip(imgPath[count], temp);
}
loadImage();

Penso che la fattura di questa funzione sia comune a molti soprattutto per quanto riguarda l’utilizzo del metodo MovieClipLoader.loadClip() associato all’Event Listener onLoadInit. In pratica la funzione loadImage() viene richiamata da se stessa tante volte quante sono le immagini definite nell’array imgPath. Questa funzione non fa altro che posizionare un MovieClip temporaneo sullo stage e caricarci dentro l’immagine, controllare che sia caricata e poi rimuovere il MovieClip temporaneo. In effetti in questo modo non serve a niente tranne che a mettere in cache le immagini.
Vediamo ora come usare BitmapData per memorizzare le informazioni sulle immagini. Per fare questo dobbiamo importare la classe e per ogni immagine caricata creare un nuovo oggetto BitmapData e poi utilizzare il metodo BitmapData.draw() per “disegnare” una nuova immagine BitmapData a partire da ogni MovieClip temporaneo che nel nostro caso è identificato con target_mc.

import flash.display.BitmapData;
var bData:BitmapData = new BitmapData(target_mc._width, target_mc._height);
bData.draw(target_mc);

Inseriamo questo codice nella funzione e ad ogni ciclo memorizziamo l’oggetto bData in un nuovo array che chiamiamo bmp:

import flash.display.BitmapData;
var imgPath = new Array("img/photo1.jpg","img/photo2.jpg");
var count:Number = 0;
var bmp:Array = new Array();

function loadImage():Void{
	_root.createEmptyMovieClip("temp", _root.getNextHighestDepth());
	var mcl = new MovieClipLoader();
	var myListener = new Object();
	myListener.onLoadInit = function(target_mc) {
		var bData:BitmapData = new BitmapData(target_mc._width, target_mc._height);
		bData.draw(target_mc);
		bmp.push(bData);
		target_mc.removeMovieClip();
		if(_root.count<_root.imgPath.length-1){
			_root.count++;
			_root.loadImage();
		} else {
			trace("Finito");
		}
	}
	mcl.addListener(myListener);
	mcl.loadClip(imgPath[count], temp);
}

loadImage();

In questo modo le immagini vengono caricate nel MovieClip temporaneo, immagazzinate in un BitmapData ed eliminato il MovieClip temporaneo. Al termine del ciclo di caricamento ora chiamiamo una funzione che visualizzerà le immagini facendo il procedimento inverso: verranno creati dei MovieClip sullo stage tanti quanti i BitmapData registrati e attaccati ad essi le informazioni di ogni BitmapData come se le immagini fossero in libreria con Linkage specificato.

Lo script finale diventa quindi:

import flash.display.BitmapData;
var imgPath = new Array("img/photo1.jpg","img/photo2.jpg");
var count:Number = 0;
var bmp:Array = new Array();

function loadImage():Void{
	_root.createEmptyMovieClip("temp", _root.getNextHighestDepth());
	var mcl = new MovieClipLoader();
	var myListener = new Object();
	myListener.onLoadInit = function(target_mc) {
		var bData:BitmapData = new BitmapData(target_mc._width, target_mc._height);
		bData.draw(target_mc);
		bmp.push(bData);
		target_mc.removeMovieClip();
		if(_root.count<_root.imgPath.length-1){
			_root.count++;
			_root.loadImage();
		} else {
			showImages();
		}
	}
	mcl.addListener(myListener);
	mcl.loadClip(imgPath[count], temp);
}

loadImage();

function showImages():Void{
	for(var i=0; i<bmp.length; i++){
		_root.createEmptyMovieClip("copy"+i, _root.getNextHighestDepth())
		_root["copy"+i]._x = 200*i;
		_root["copy"+i]._y = 200*i;
		_root["copy"+i].attachBitmap(bmp[i], 1);
	}
}

In qualsiasi momento potrete richiamare e visualizzare i BitmapData semplicemente usando il metodo MovieClip.attachBitmap() come se fosse MovieClip.attachMovie(). Ci sono molti altri aspetti interessanti di questo utilizzo sia legati alle possibilità di smoothing offerte dall’attachBitmap() che dalle innumerevoli possibilità di modifica sulle immagini dal momento che sono dei BitmapData… a voi continuare lo studio.
Spero vi sia stato utile.

getURL in Flash projector

// dicembre 16th, 2006 // 11 Comments » // Sviluppo e tips

Utilizzando il comando getURL() per aprire un file HTML da un SWF caricato tramite lo standalone Player di Flash (com ad esempio un projector EXE su un CD-rom) abbiamo riscontrato difficoltà di funzionamento soprattutto quando il browser predefinito è Firefox. Invocando il getURL(“modules/mia_pagina.html”) non viene aperta la pagina richiesta… vediamo perché…

Prendiamo in considerazione la situazione in cui un Flash projector (pubblicato come tale da Flash) contiene una chiamata di tipo getURL() a un file HTML: in questo modo non ci addentriamo nella casistica degli SWF in locale per i quali entra in ballo tutta la questione riguardante le security restrictions introdotte nelle varie versioni. Un movie Flash pubblicato come eseguibile invece non è soggetto a queste restrizioni di sicurezza come descritto nella documentazione ufficiale.
Detto questo procediamo con il nostro esempio e vediamo cosa succede quando un pulsante (che ha come instance name “myButton”) contenuto nel Flash projector invoca un getURL, o l’equivalente navigateToURL in AS3.0, a una pagina HTML:

myButton.onRelease = function() {
	getURL("modules/mia_pagina.html", "_blank");
};

Se il browser predefinito sul computer dell’utente è Internet Explorer, o una versione di Netscape/Mozilla precedente Firefox, tendenzialmente il comando avrà effetto e si aprirà la pagina “mia_pagina.html”.
Però se il browser di default è Firefox allora succedono cose strane e imprevedibili: sulle piattaforme testate ad esempio capita che Firefox si apre con due tab di cui uno _blank e uno in cui viene visualizzata la pagina di ricerca di default (ad esempio Google).
Un bel problema! Così sono partite le miee ricerche e i test più svariati fino a capire che non si tratta di un bug del Flash Player ma di Firefox, o meglio, di come Firefox gestisce le Url passate sulla command line.
Chiudete tutti i browser e provate a scrivere sulla command line il comando:

firefox -url "http://www.yahoo.com/|http://www.google.com/"

Noterete che viene aperto Firefox con due tab: una per Yahoo e una per Google.
Torniamo a Flash ora… quando in un projector invochiamo un getURL(“modules/mia_pagina.html”, “_blank”), quindi a una pagina relativa, il Flash Player traduce questo path in assoluto. Se ad esempio il projector è su un CD-dom identificato con la lettera D, e il file mia_pagina.html posizionato nella directory “modules”, il path assoluto tradotto dal Flash Player sarà del tipo:

file:///D|modulesmia_pagina.html

Notate che è presente in questa stringa il carattere “|” (che si legge “pipe”) ed è proprio qui il problema. Quando Firefox riceve questo path, come nell’esempio fatto per la command line, cerca di aprire due tab e visualizzare le pagine specificate prima e dopo il “pipe”. Nel nostro caso tenterà di aprire senza successo le pagine “file:///d:” e “modulesmia_pagina.html” che, non essendoci corrispondenza con reali pagine, provocano l’errore.

La soluzione è quindi quella di tradurre il path assoluto da inviare al browser in modo da evitare la presenza del carattere “pipe” e l’insorgere del problema, che ricordiamo è limitato solo agli utenti Firefox… ma come ben sappiamo sono (siamo) una crescente realta da non sottovalutare.
Per fare questo ci viene in aiuto la proprietà _url di AS2.0 o la proprieà url di loaderInfo in AS3.0). Per un SWF in una pagina web questa proprietà corrisponde alla url del file SWF, mentre per un SWF standalone in locale come un projector/eseguibile questo restituisce il path assoluto “file:///” dell’SWF nel file system.

Facciamo una prova e creiamo un projector SWF con un textField sullo stage a cui diamo come instance name “tf”:

// AS2
tf.text = this._url;

// AS3
tf.text = this.loaderInfo.url;

Facendo un test nel nostro textField apparirà un testo tipo: “file:///D|/projector.exe”.
Quindi quello che dovremo fare nel nostro caso è sostituire il “pipe” con “:” e il nome del projector con il percorso relativo al file HTML da aprire. Ci facciamo aiutare da indexOf() e lastIndexOf() per individuare rispettivamente la posizione del carattere “pipe” | e dellultimo slash (/) che chiude il path del projector. Ed ecco il codice risultante in Actionscript 2.0:

 

var swfUrl:String = _root._url;
var lastSlashIndex:Number = swfUrl.lastIndexOf("/");
var pipeIndex:Number = swfUrl.indexOf("|");
var baseUrl:String;
if (pipeIndex >= 0) {
	baseUrl = swfUrl.substring(0, pipeIndex);
	baseUrl += ":";
} else {
	baseUrl = "";
}
baseUrl += swfUrl.substring(pipeIndex + 1, lastSlashIndex + 1);
myButton.onRelease = function() {
	var targetUrl:String = baseUrl + "modules/mia_pagina.html";
	getURL(targetUrl, "_blank");
};

The Complete Guide to Flex 2 with ActionScript 3.0

// novembre 9th, 2006 // No Comments » // Libri e recensioni

Flex2-Actionscript3Un libro prezioso che probabilmente andrà a ruba a Febbraio 2007. Sì, uscirà solo il 29 Gennaio ma sarà un bel regalo da farsi o a mettere nella wishlist di Amazon.
Il libro toccherà i temi riguardanti lo sviluppo con Flex 2 e Actionscript 3.0 e questa che segue è la descrizione ufficiale apparsa sul sito della casa editrice Friends of ED:

“Flex 2, Flex Builder 2, and ActionScript 3.0 is the unstoppable new combination representing a revolution in Flash application development.Flash and ActionScript 2 revolutionized web design with the introduction of Rich Internet Applications (RIA,) and now Flex 2 takes Flash way beyond its previous capabilities in delivering enterprise-level internet applications that vastly improve the user’s internet experience.

Flex 2 is based on an easy to learn markup language called MXML. Using it you can create a series of nested containers, which the Flex server then translates into a finished application.
Flex Builder 2 is an easy-to-use programming environment, based on the famed Eclipse development environment, that allows you to create applications in both Flex 2 and ActionScript 3.0.

To help you keep ahead of the game and get up to speed with Flex 2 and ActionScript 3.0, Flash development, and certified training expert, Charles E Brown has written this comprehensive guide to developing Flex 2 and ActionScript 3.0 applications using Flex Builder, to help you keep ahead of the game. He takes you step-by-step through:

  • Installation
  • The basics of MXML
  • Object Oriented Programming concepts
  • ActionScript 3.0 syntax
  • Building design and navigation containers
  • Styling Flex applications with Cascading Style Sheets
  • Data Connectivity
  • And much, much more!

No matter what level of web designer you are, by the end of the book you’ll be creating powerful Flash applications. The revolution starts here!”

Non manca che attendere per leggerselo di un fiato.