Posts Tagged ‘ FLASH

Creating an AJAX OpenLaszlo Preloader for SWF Files

Since the SWF9 runtime in OpenLaszlo, the internal splashscreen isn’t anymore available. So if you need some preloader animation with a progressbar, you must implement an ajax-loader. You also have the option, to implement a preloader based on actionscript, but these isn’t multi runtime compatible and will not work with the HTML Runtime. So it’s the best solution, to implement a preloader for your OpenLaszlo applications based of JavaScript.

Click here for a quick demo 😉

In the first step, we will create the Preloader for the SWF10-Runtime. In a further step, we will change them for the HTML5-Runtime.
Sure you can use this preloader also for Flash- or Flex-Compiled SWF-Files 😉

At first we take the HTML embedding from a previous Solo Export, and extend it in the following steps.

<html>
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
		<meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
		<meta http-equiv="PRAGMA" content="NO-CACHE">
		<meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8">
		<meta http-equiv="EXPIRES" content="0">
		<meta name="viewport" content="width=device-width; initial-scale=1.0;">
		<meta name="keywords" content="" /> 
		<meta name="description" content="" /> 

		<title></title>

		<link rel="stylesheet" type="text/css" href="./css/style.css">
		<!--[if IE]>
			<link rel="stylesheet" type="text/css" href="./css/style.css">
		<![endif]-->
		
		<script type="text/javascript" src="./js/flash_detect.js"></script>
		<script type="text/javascript" src="./js/jquery-1.4.2.min.js"></script>
		<script type="text/javascript" src="./js/embed-compressed.js"></script>
		<script type="text/javascript" src="./js/custom.js"></script>
		<script type="text/javascript" src="./js/loader.js"></script>
        
	</head>
	<body>

		<noscript>
			<font class="statusFont">Please enable JavaScript in order to use this application.</font>
		</noscript>

		<div id="lzsplash">
		 	<p id="lzsplashp">
				<img id="loadstatusimage" src="./img/ajax-loader.gif" />
				<br />
				<br />
				<font id="loadstatus" class="statusFont">&nbsp;&nbsp;0% cached...</font>
			</p>
		</div>

	</body>
</html>

 
In this part we have included the required CSS and JavaScript-Files, checking if JavaScript is available and created a Div-Layer for our Preloader.

Attention: By integrating the preloader into your HTML design, do not change the hierachy of the Div-Structure. If you do that, the swfobject will be not displayed anymore in some Internet Explorer Versions. Another problem is the wmode attribute, that is used to let some other elements upper the flash displayed, this isn’t recommendable. The practice have showed, that within some Firefox browser that are running on Windows the Flash file isn’t correctly loaded.

Tip: For creating quick a nice loading animation as a gif, i use the www.ajax-loder.info Site. There you can create directly online your own load animation, by choosing an animation and colored it with your prefered color.
 
The embedded CSS-Files are only for styling and placing the Div-Layers. Further there is a Flash-Detection, which you can get on www.featureblend.com, so we could give the visitor a message and the download-link if there’s no Flash available.

if(FlashDetect.versionAtLeast(10)) var flashDetected = true;
else var flashDetected = false;

window.onload = function(){
	if(!flashDetected){
		document.getElementById('loadstatus').innerHTML = "Please download the current version of the Adode Flash Player:<br /><a href=\"http://get.adobe.com/de/flashplayer/\" target=\"_blank\">http://get.adobe.com/de/flashplayer/</a>";
	}
}

 
Additional we have integrated jQuery, for doing some Actions a quite bit faster 😉
 
The main-part of this Preloader is located in the loader.js:

// Reminds that the onload is already called
// The Internet Explorer sometimes seems to call that twice
var loadedCalled = false;


// Load Application
if(flashDetected) {
	lz.embed.swf({
		url: 'index.lzx.swf10.swf', 
		allowfullscreen: 'true', 
		width: '100%', 
		height: '100%', 
		id: 'lzapp', 
		accessible: 'false'
	});

	// Make Application Container invisible
	if($.browser.msie) { 
		$('#lzappContainer').hide(); 
	}
	else {
		$('#lzappContainer').css('width', '0px');
		$('#lzappContainer').css('height', '0px'); 
	}

	// called with a percentage (0-100) indicating load progress
	lz.embed.lzapp.onloadstatus = function loadstatus(p) {

		// Set styles
		//if(!basicStylesSetted) setBasicStyle();
		$('#loadstatus').html('&nbsp;&nbsp;' + p + '% cached...'); 
                          
	}

	// called when this appli
cation is done loading
	lz.embed.lzapp.onload = function loaded() {
		
		// Check if the function is 
		// already called
		if(loadedCalled) return;
		else loadedCalled = true;

		// Set styles
		//if(!basicStylesSetted)  setBasicStyle();
		
		$('#lzappContainer').show();
   		$('#lzapp').show();
   		$('#lzsplash').hide();
	}
}

 
The ‘lz.embed.swf(..);‘ initials the Application-Loading and placement, the ‘lz.embed.lzapp.onloadstatus‘ fires the current percent-number for feeding the progressbar and the ‘lz.embed.lzapp.onload‘ will be fired when the Application is ready to use.
That’s all. The main-problem by all this work is, to get it work in every Browser, like my prefered Browser the Internet Explorer 6 😛
 
Finishing Notice:
If you use a PHP-File as container for your HTML, and you want to pass some GET-, POST- or other PHP-Variables, there’s attention needed! These variables must be strictly checked, if you want to prävent a possible Script-Injection or bad variables.

As sample, you pass any ID by a GET- or Post-Parameter, like:

http://...index.php?anyID=123

 
You can catching the ID and pass it without any actions to your OpenLaszlo-/Flash-Application:

...
<script type="text/javascript">
//<![CDATA[
...
lz.embed.swf({url: 'index.lzx.swf10.swf?ses_id=?ses_id=<?php echo $ses_id; ?>&anyID=<?php echo $_GET['anyID']; ?>&lzr=swf10&lzproxied=false', allowfullscreen: 'false', width: '100%', height: '100%', id: 'lzapp', accessible: 'false', cancelmousewheel: false, appenddivid: 'lzappContainer'});
...
//]]>
</script>
...

 
This is very bad and dangerous!

If your visitor do change these ID you’ve catched from a GET- or Post-Parameter, like:

http://...index.php?anyID=123&badParameter1=bad&badParameter=superbad&

 
or even better:

http://...index.php?anyID=123 '}); document.title = 'mega bad'; //

 
Then maybe you have a problem. Everybody can inject any JavaScript into your site!
In the last sample, your visitor closed with ‘123 ‘});‘ the ‘lz.embed.swf(..);‘ and injects a new JavaScript action like ‘document.title = ‘mega bad’;‘. Finally he cuts the rest of your statements with a ‘ //‘, to get no JavaScript-Errors.

So, you must validate all passed Parameters in the head of your PHP-File strictly, copy these into their own self-created variables, validate them and use only this copies in your following code. Don’t use GET- or POST-varibles midst of your scripts.
Also, don’t access GET- or POST-Variables directly inner Functions or Class-Methods. Always pass all Variables you need as Function-Parameters.
That is best Practice!

Click here finally for a demo 😉

Sourcecode: OpenLaszlo - Preloader (1506)

If you found some bugs or have some Tips, please contact me.
Do you make some changes, because any Browser-Version has some fault, contact me too… So i can update these little Tutorial-Scripts, and give other guys also this corrected files.. 🙂

Create a webcam face detection within OpenLaszlo by using ActionScript3

Today i found a smart script for a webcam face detection on www.quasimondo.com.
Now i will try to do this within OpenLaszlo, thus post based also on this sample.. 😉

Click here for a quick demo 😉

First of all, we have to download the sourcecode in the Marilena_mod10.zip from www.quasimondo.com and extract it.

To be able to use the source code, we have to compile the ActionScript files into a SWC file. Therefore we need a Flex SDK. If you not already installed it, read here how do you do this under Ubuntu Linux.
When you have the Flex SDK available, navigate into the src directory from the extracted sourcecode and compile the SWC with the following action:

compc -source-path ./ -include-sources ./ -optimize -output ../faceDetection.swc

 
The result is the faceDetection.swc file, which must now be provided to OpenLaszlo. How you can do this, read it here in detail. In short, copy it into your flexlib directory within your OpenLaszlo WEB-INF directory.

Now you can import the required base libaries into a self implemented class by using a passthrough tag:

<class name="faceDetector" width="480" height="640">
	
	<switch>
		<unless property="$as3">
			<handler name="oninit">
			<![CDATA[
				Debug.error("ActionScript 3 required");
			]]>
			</handler>				
		</unless>
		<otherwise>
			<passthrough>
				import com.quasimondo.bitmapdata.CameraBitmap;
				import jp.maaash.ObjectDetection.ObjectDetector;
				import jp.maaash.ObjectDetection.ObjectDetectorEvent;
				import jp.maaash.ObjectDetection.ObjectDetectorOptions;
				...
			</passthrough>

			...

 
The first great step is now done and we will further implement a complete class for using the face detection, so that we in future just have include a tag for using it.
We will do this also on our base sample. The result is a port to OpenLaszlo of these, with just a few differences:

<!---	Object Variables -->
<attribute name="detector" type="expression"/>
<attribute name="camera" type="expression"/>
<attribute name="faceRectContainer" type="expression"/>
<attribute name="detectionMap" type="expression"/>
<attribute name="drawMatrix" type="expression"/>

<!---	Scale factor of the image -->
<attribute name="scaleFactor" type="number" value="4"/>

<!---	Is currently a face detected?! -->
<attribute name="faceDetected" type="boolean" value="false" />
	
<!---	Weight of the face rect -->
<attribute name="rectLineWeight" type="number" value="2"/>

<!---	Starting the initiation -->
<handler name="oninit">
<![CDATA[

	if(this.scaleFactor==0) {
		Debug.error("scaleFactor must be greater 0");
	}

	this.initUI();
	this.initDetector();
]]>
</handler>				

<!---	Init the UI -->
<method name="initUI" args="" returns="void">
<![CDATA[
	var view = new Sprite();
	this.getDisplayObject().addChild(view);

	this.camera = new CameraBitmap(this.width, this.height, 15);
	this.camera.addEventListener(Event.RENDER, this.cameraReadyHandler);
	view.addChild( new Bitmap(this.camera.bitmapData) );
			
	this.detectionMap = new BitmapData(this.width/this.scaleFactor, this.height/this.scaleFactor, false, 0);
	this.drawMatrix = new Matrix(1/this.scaleFactor, 0, 0, 1/this.scaleFactor);
		
	this.faceRectContainer = new Sprite();
	view.addChild(this.faceRectContainer);
]]>
</method>


<!---	Is called when the camera is ready -->
<method name="cameraReadyHandler" args="event:Event" returns="void">
<![CDATA[
	this.detectionMap.draw(this.camera.bitmapData, this.drawMatrix, null, "normal", null, true);
	this.detector.detect(this.detectionMap);
]]>
</method>


<!---	Init the detector -->
<method name="initDetector" args="" returns="void">
<![CDATA[

	// Creat a new ObjectDetector
	this.detector = new ObjectDetector();
	
	// ..and give them the required options 
	var options:ObjectDetectorOptions = new ObjectDetectorOptions();
	options.min_size  = 30;
	this.detector.options = options;
	this.detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE, this.detectionHandler);
]]>
</method>


<!---	Is called at every detection -->
<method name="detectionHandler" args="e:ObjectDetectorEvent" returns="void">
<![CDATA[				

	var g :Graphics = this.faceRectContainer.graphics;
	g.clear();
	if(e.rects) {
		g.lineStyle(this.rectLineWeight);
		e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
			
			// Set face detected
			if(!faceDetector.faceDetected) faceDetector.setAttribute("faceDetected", true);
										
			// Timer when face deteced is reset
			if(typeof this.resetDetectionDelegate == "undefined") {
				this.resetDetectionDelegate = new LzDelegate(faceDetector, "resetDetection");
				lz.Timer.addTimer(this.resetDetectionDelegate, 500);
			}
			else {
				lz.Timer.resetTimer(this.resetDetectionDelegate, 500);
			}
			g.drawRect( r.x * faceDetector.scaleFactor, r.y * faceDetector.scaleFactor, r.width * faceDetector.scaleFactor, r.height * faceDetector.scaleFactor );
		});
	}
						
]]>
</method>

<!---	Is called when no face is anymore detected -->
<method name="resetDetection" args="something" returns="void">
<![CDATA[
	if(this.faceDetected) this.setAttribute("faceDetected", false);
]]>
</method>	

 
After finishing the impĺementation of the face detection class, just have to include the new class and place the tag on the required target. We do the as sample in the source code from the snapShot article i have written some days ago:

<simplelayout axis="y" spacing="0" />
<view name="videoView" width="$once{canvas.imageWidth*2}" height="$once{canvas.imageHeight}">
	<simplelayout axis="x" spacing="0" />
	<view name="videoView" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
		<faceDetector name="faceDetector" id="faceDetector" scaleFactor="2" rectLineWeight="1"
					  width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}">
			<handler name="onfaceDetected">
			<![CDATA[
				Debug.write(this, "onfaceDetected("+this.faceDetected+")")
			]]>
			</handler>
		</faceDetector>
	</view>
	
	<view name="snapshot" width="$once{canvas.imageWidth}" height="$once{canvas.imageHeight}" />
</view>
			
<view layout="axis: x; spacing:0">
	<button text="Take a snapshot" onclick="canvas.takeSnapshot();" width="$once{canvas.imageWidth}" enabled="${faceDetector.faceDetected}" />
	<button text="Save snapshot" onclick="canvas.saveImage();" width="$once{canvas.imageWidth}" enabled="${canvas.shotAvailable}" />		
</view>	

 
How you see, we just exchange the videoview-tag with the faceDetection-tag, and add the faceDetected-constraint to the enabled attribute of the snapshot button.
This was very easy, or?! And the result pretty nice.. 🙂
Thanks in this place to Mario Klingemann and all other they have optimize and work on this code.

Click here for a demo 😉

Sourcecode: OpenLaszlo - FaceDetection.zip (1643)

If you found some bugs or have some Tips, please contact me.

Read and write files from local filesystem with OpenLaszlo by using ActionScript3

Today i will try to read and write local files from a local storage. After a few searches with google, i found several similar samples. Now i integrate these with the sample from www.mikechambers.com within my OpenLaszlo code. For both, reading and writing files, we need the usual main structure, with a runtime switch and passthrough for the actionscript libraries.

Click here for a quick demo 😉

At first, we have look at the reading of a file. For that we create a few small functions, some of them act as an event handler.
 
1. The function that invokes the loading. Here we instantiate a FileReference object, register the required eventlistener and open the browser window for selecting a file. Further you will find here the fileFilterValue variable, within you are able to restrict the allowed file types for selecting.

<!---	called when the user clicks the load file button -->
<method name="loadFile" returns="void">
<![CDATA[	
	
	// create the FileReference instance
	this.fr = new FileReference();

	// listen for when they select a file
	this.fr.addEventListener(Event.SELECT, this.onFileSelect);

	// listen for when then cancel out of the browse dialog
	this.fr.addEventListener(Event.CANCEL, this.onCancel);

	// open a native browse dialog that filters for text files
	this.fr.browse([new FileFilter(this.fileFilterValue, this.fileFilterValue)]);
								
]]>
</method>

 
2. The function that is called, when the user has selected a file. Here we register two further eventlistener, the onLoadError and onLoadComplete eventlistener, and starting the loading progress.

<!---	called when the user selects a file this.from the browse dialog -->
<method name="onFileSelect" args="e:Event" returns="void">
<![CDATA[
	Debug.write(this, "->onFileSelect()");

	// listen for when the file has loaded
	this.fr.addEventListener(Event.COMPLETE, this.onLoadComplete);

	// listen for any errors reading the file
	this.fr.addEventListener(IOErrorEvent.IO_ERROR, this.onLoadError);

	// load the content of the file
	this.fr.load();						
]]>
</method>

 
3. The onLoadComplete function is called, when the file is transferred to the flash application. Here we receive the file contents and clean up the FileReference instance.

<!---	called when the file has completed loading -->
<method name="onLoadComplete" args="e:Event" returns="void">
<![CDATA[
	Debug.write(this, "->onLoadComplete()");

	// get the data this.from the file as a ByteArray
	var data:ByteArray = this.fr.data;

	// Get the file content
	this.setAttribute("fileContent", data.readUTFBytes(data.bytesAvailable));
	
	// clean up the FileReference instance	
	this.fr = null;					
]]>
</method>

 
4. The onLoadError function will be called in case of a transfer-error.

<!---	called if an error occurs while loading the file -->
<method name="onLoadError" args="e:IOErrorEvent" returns="void">
<![CDATA[
	Debug.error(this, "->onLoadError(): " + e.text);					
]]>
</method>

 
5. The onCancel function is used of both, the reading and writing action, and is just called when the user aborts the file selecting browser window or file saving browser window.

<!---	called if the user cancels out of the file save dialog -->
<method name="onCancel" args="e:Event">
<![CDATA[
	Debug.write(this, "->onCancel()");
	this.fr = null;						
]]>
</method>

 
For the writing of files you need just the three following functions, some of that are also act as a event handler.

1. The saveFile function invokes the saving action. Here we instantiate again a FileReference object, register the requiered eventlistener and open the browser window for selecting the destination for the file.

<!---	called when the user clicks the save file button -->
<method name="saveFile" args="fileContent ='', fileName ='test.txt'" returns="void">
<![CDATA[	
	
	// create the FileReference instance
	this.fr = new FileReference();

	// listen for the file has been saved
	this.fr.addEventListener(Event.COMPLETE, this.onFileSave);

	// listen for when then cancel out of the save dialog
	this.fr.addEventListener(Event.CANCEL, this.onCancel);

	// listen for any errors that occur while writing the file
	this.fr.addEventListener(IOErrorEvent.IO_ERROR, this.onSaveError);

	// open a native save file dialog, using the default file name
	this.fr.save(fileContent, fileName);
								
]]>
</method>

 
2. The onSaveError function will be called in case of an error while saving.

<!---	called if an error occurs while saving the file -->
<method name="onSaveError" args="e:IOErrorEvent">
<![CDATA[
	Debug.write(this, "->onSaveError(): ", e.text);
	this.fr = null;								
]]>
</method>				

 
3. The onFileSave function will be called when the file is successfully saved.

<!---	called once the file has been saved -->
<method name="onFileSave" args="e:Event">
<![CDATA[
	Debug.write(this, "->onFileSave()");
	this.fr = null;							
]]>
</method>

 
All these functions are capsuled in a class, that is extends the node object.

<class name="readAndWriteFileReference" extends="node">

	<passthrough>
		import flash.net.FileReference;
		import flash.net.FileFilter;
		import flash.events.IOErrorEvent;
		import flash.events.Event;
		import flash.utils.ByteArray;
	</passthrough>

	<!---	FileReference -->
	<attribute name="fr" type="expression" />

	...

Is this class implemented, you will only need to create an instance of that and bind an eventlistener with it. Now you are able to load and write file contents, just by calling the load and save function. A canvas could look like:

<canvas name="readAndWriteFileReference" width="800" height="550">
	
	<include href="./readAndWriteFileReference.lzx" />
		
	<attribute name="columnWidth" type="number" value="400"/>
	<attribute name="textHeight" type="number" value="${canvas.height-canvas.buttonBar.height}"/>
	
	<readAndWriteFileReference name="readAndWriteFile">
		<handler name="onfileContent">
		<![CDATA[				
			canvas.textView.textLoad.setAttribute("text", this.fileContent);
		]]>
		</handler>				
	</readAndWriteFileReference>		
		
	<simplelayout axis="y" spacing="0" />
	<view name="textView" width="$once{canvas.columnWidth*2}" height="$once{canvas.textHeight}">
		<simplelayout axis="x" spacing="0" />
		<edittext name="textSave" width="$once{canvas.columnWidth}" height="$once{canvas.textHeight}" multiline="true" />
		<edittext name="textLoad" width="$once{canvas.columnWidth}" height="$once{canvas.textHeight}" multiline="true" />
	</view>
				
	<view name="buttonBar" layout="axis: x; spacing:0" height="27">
		<button text="Save file" onclick="canvas.readAndWriteFile.saveFile(canvas.textView.textSave.text, 'test.txt');" width="$once{canvas.columnWidth}" />
		<button text="Load file" onclick="canvas.readAndWriteFile.loadFile();" width="$once{canvas.columnWidth}" />		
	</view>	
				
</canvas>

And now, happy loading and saving 😉

Click here for a quick demo 😉

Sourcecode: OpenLaszlo - ReadAndWriteFileReference.zip (1101)

If you found some bugs or have some Tips, please contact me.

Change line-height in OpenLaszlo Flash/SWF10 Runtime

When you’re using OpenLaszlo by compiling to flash/swf10 Flash, the lineheight attribute within the text class is readonly. That’s sometimes problematic, if you getting strict specifications from your designer for create a website or GUI (graphic user interface). The designer wants that you do implement all the typographic specification that he gives you, pixel by pixel.

For this case, i’ve searched for a workaround to change the lineheight within text fields.
The result is the following class:

<?xml version="1.0" encoding="UTF-8" ?>
<library>
	<class name="lineHeightText" extends="text" multiline="true">
		
		<switch>
			<unless property="$as3">
				<method name="setLineHeight" args="newLineHeight:Number =0">
				<![CDATA[
					Debug.error("setLineHeight is not supported");
				]]>
				</method>				
			</unless>
		    <otherwise>
				<passthrough>
					import flash.text.*;
				</passthrough>
				
				<method name="setLineHeight" args="newLineHeight:Number =0, refreshHeight:Boolean =true">
				<![CDATA[
				
					// get an reference of this text
					var test = this.getDisplayObject();
					
					// set new line-height
					var format:TextFormat = new TextFormat();
					format.leading = newLineHeight-test.lineheight;
					
					// set line-height in the sprites
					test.lineheight = newLineHeight;
										
					// make this textfield bigger
					if(refreshHeight) this.setAttribute("height", newLineHeight*test.textfield.numLines);
					
					// set the new format
					test.textfield.setTextFormat(format);					
					test.textfield.defaultTextFormat = format;
								
				]]>
				</method>
				
			</otherwise>
		</switch>
		
	</class>
</library>

The usage is very simple:

<?xml version="1.0" encoding="UTF-8" ?>
<canvas name="lineHeight" width="100%" height="100%">
		
	<include href="./lineHeightText.lzx" />
	
	<lineHeightText fontsize="11" fgcolor="#000000" bgcolor="#abcdef" x="10" y="10" name="textarea1" width="200" selectable="true">
		[start]Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.[end]
	</lineHeightText>
	
	<lineHeightText fontsize="11" fgcolor="#000000" bgcolor="#abcdef" x="220" y="10" name="textarea2" width="200" selectable="true">
		<handler name="oninit">
		<![CDATA[
			this.setLineHeight(20);
		]]>
		</handler>
		[start]Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.[end]
	</lineHeightText>	

</canvas>

I hope this can help somebody.
If you find some errors, or have some questions or tips, write me.. 😉

Sourcecode: OpenLaszlo - LineHeight.zip (907)