Archive for the ‘Actionscript’ Category

Pay Per View with Flash Media Server

Wednesday, August 15th, 2007

At JAJAH we are always looking for ways to leverage our payment system in new and exciting ways. One of the ideas that came up was to sell calls to videos. You call to a certain number and while the call is active, you can watch a certain video. Not a new concept at all, it’s been used in some industries for ages now ;). But, we only needed a demo for now and we needed a super quick way to create it. The obvious choice was to use Flash Media Server with some kind of ticketing system. For this demo we used a third party shared server from influxis which is more then enough in this case.

Creating a ticketing system with FMS couldn’t be easier, you can find some tutorials about it here, here and here. But let me summarize it for you. Create some kind of a temporary ticket (random number or GUID will do) and send it to the client (the Flash player), when the player request the video stream from the server, send this ticket to the FMS along with the request. The FMS in it’s turn validate this ticket against your server. Continue checking this ticket in a certain interval and as long as this ticket is valid, play the stream, if it become invalid kill the connection. Thats it. Most of the articles on the web about FMS tells you that Flash-Remoting is needed for any kind of communication from the FMS. It isn’t completely true. While using remoting may be beneficial in some cases, since FMS 2.0 it is easy to make asynchronous calls like webservices and loadvars. So you have more choise when developing your ticketing system. If you want to use Flash Remoting in dot.net consider using Midnightcoders WebOrb, as an alternative to Macromedia’s Flash Remoting MX (both didn’t install on Vista at the time, btw).
Since Jajah’s pay per view is only a demo, we didn’t exert ourselves to make it supper secure. you can learn more about securing your videos in this Adobe Flash Media Server article.

Jajah Pay Per View

To watch the pay per view demo, go to jajah.com, login or register and make a (free) call to this number +43-123456789. Your phone will ring, answer the call and behold. You will see a cool animation, an homage to IceAge. When you’ll hang up your phone, the animation will stop. If you’ll try to watch the movie after hanging-up, the stream won’t be served from the FMS since the ticket isn’t valid anymore.

Hostlynx 2.0 - Serious Flex app

Friday, July 13th, 2007

There is a claim that there isn’t enough serious Flex applications out there. I’ve recently had the honor to preview an impressive one, and also to conduct a short interview with Dima Gutzeit the Project Manager of this app, named Mailvision Hostlynx 2.0.
This is another one for you to showoff when arguing for the right technology for your next application, currently there are only some information and screenshots, but, I’ll let you know when a full demo is publicly available.

Hostlynx 2.0 - Screenshot2 small

Hostlynx 2.0 - Screenshot1 small

Q: What is Hostlynx 2.0?

A: Hostlynx 2 is the next generation of MailVision Class 5 SoftSwitch for VOIP telephony (SIP protocol). The product allows a system provider to setup a telephony network and offer advanced telephony services to its subscribers (IPCentrex). System management of the solution is based on Flex+Webservices.

Q: Who is the audience of this application?

A: Service providers and corporates who wishes to enter the fast evolving VOIP market.

Q: Why do you think Flash is the right technology for this project?

A: During the research for the project we have considered several technologies, including various AJAX toolkits, JSF and etc. The following convinced us to go with Flash/Flex: Flash player is installed on 98% of desktop computers so in majority of cases it will not require any client side installations. We wanted to deliver the best user experience we could and flash allowed us to do that.

Q: Generally, how is this app structured, client, backend, architecture etc’?

A: Our application uses webservices to communicate between client and server, where Flex application is used as a webservices client and JAXWS on the server side. When we started working with Flex (2.0) its webservices implementation was very weak and basic, so we had to create many workarounds on the server side to compensate. Flex 2.0.1 Hotfix 2 changed that, since we were part of the beta program for Hotfix2 and Adobe staff were kind enough to listen to our requests and enhance the webservices implementation.

Q: Have you used Cairngorm?

A: Yes, we do. Our application uses MVC, and this is done by using Cairngorm (2.0). ServiceLocator is responsible for all the webservices related stuff - sending requests and etc.

Q: How many people worked on the project?

A: Project development involved 2-3 developers and one designer. Project duration was around one year.

Q: Did any of the developers had previous experience with Flash or Flex?

A: That was one the “negative” factors when we decided on technology, since none of our developers had any previous experience not with Flash nor ActionScript. The learning curve was not a short one, since all the developers were from Java/JSP world.

Q: Will there be an online demo of the app?

A: We are on Beta 2 release, and a full featured demo will be available as soon as the application is stable enough.

Q: Do you have plans for creating similar apps?

A: I believe that the majority of future web/desktop projects of Mailvision will use Flex/AIR.

Q: What do you think is the future of the Flash platform and RIA in general?

A: Flex rocks :-).

Too much focus will kill you

Sunday, July 8th, 2007

I've just came across of a way to kill the Flash player with a few lines of AS 2.0. I know of at least one other way of killing the Flash player along with it's host, may it be the browser or the Flash IDE, but this was with the old 7th player, this time we're talking about the latest 9th version. It's a little awkward, and don't ask me how I got it, but, it involves a MovieClip, a TextField, Selection, Macromedia's Delegate, a filter, and a trace, yeah, it won't work without a call to trace. I think the main trouble maker is the Selection.onSetFocus, but, I couldn't recreate it without any of the above ingredients, and I have a feeling that AS2's trace is also problematic in Flash Player 9. (You should anyway "Omit trace actions", from the settings, when publishing swfs)

Focus Kills

I haven't tried it, but, I doubt that it can be recreated with AS3 on the VM2, it's the VM1 that we have to carry along for backward compatibility that causes all this trouble. I tested it on some different machines with different Flash players and so far it crushed them all, here is the list:

Ver: WIN 8,0,22,0 | Debug: true | OS: Windows XP
Ver: WIN 9,0,16,0 | Debug: true | OS: Windows XP
Ver: WIN 9,0,28,0 | Debug: false | OS: Windows XP
Ver: WIN 9,0,45,0 | Debug: false | OS: Windows XP
Ver: WIN 9,0,45,0 | Debug: false | OS: Windows (Server 2003)
Ver: WIN 9,0,45,0 | Debug: true | OS: Windows Vista
Ver: WIN 9,0,45,0 | Debug: false | OS: Windows Vista
Ver: WIN 9,0,47,0 | Debug: false | OS: Windows Vista
Ver: MAC 9,0,28,0 | Debug: false | OS: Mac OS 10.4.9

Copy this code into an empty FLA first frame, or download the source below to see how it goes.

Actionscript:
  1. var mc:MovieClip = this.createEmptyMovieClip("mc", 0);
  2.  
  3. var tf:TextField = this.createTextField("tf", 1, 20, 20, 300, 100);
  4. tf.type = "input";
  5. tf.border = true;
  6. tf.text = "Flash Player Varsion: " + System.capabilities.version + "\nDebug Player: " + System.capabilities.isDebugger + "\nOperating System: " + System.capabilities.os + "\n\nClick here or press the TAB key to kill Flash";
  7.  
  8. tf.onSetFocus = mx.utils.Delegate.create(this, glow);
  9.  
  10. Selection.addListener(this);
  11.  
  12. function onSetFocus(oldf:Object, newf:Object):Void{
  13. Selection.setFocus(oldf);
  14. }
  15.  
  16. function glow(){
  17. mc.filters = [new flash.filters.BevelFilter()]; // any filter except BitmapFilter()
  18. trace(mc.filters);
  19. }

Download source files.

Try it (Warnning!!!, it may crash your browser)

Shape Hints - Have you forgotten how good they taste ?

Saturday, April 14th, 2007

These days it's easy to forget that Flash is an amazing classic animation tool. Ever since the arrival of the fine Macromedia Tween Class and the amazing Fuse Kit (a new version was just released) and great books like Foundation Actionscript Animation, by: keith peters, new version for Actionscript 3.0 is on the way (not affiliat), it seems that we want to script our animation no matter what! Now, don't get me wrong, I also think that scripted animation is very powerful and I use it all the time. But, I sometimes find myself over using it in places where I should have used a simple tweening instead.With the 8th version of Flash we received a nice improvement to the tweening capabilities, it is now possible to achieve a relatively complex tweening animation with only two key frames. Check out this tutorial: Achieving Amazing Easing Effects in Flash, by: Rafiq R. Elmansy.

And what about the new kid animation abilities?! With what I've seen so far in the main WPF interactive editor CTP (beta) vesions, it fall short of Flash, it has an interesting concept of having the animation of an object as just another property of that object. But, it lake of satisfactorily key-frames controll and things like shape tween are not existent. These things might be improved in the final version, but it seems to me that Microsoft is still donesn't pay atantion to creativity as it should have, and is mainly thinking about GUI creation.

I just hope that Adobe wont forget the origins of Flash and one of the main reasons it is such a terrific tool, and is planing a tons more of animation and creativity features in the next Flash IDE release.

Note: I've written this post some time back, before the announcement of the new Flash CS 3 (Flash 9) feature list. It seems that we'll get some animation improvements, the two most interesting improvements looks like, Custom easing control and Copy and paste animations. The first will "provides independent control of position, rotation, scale, color, and filters", it will give us much finer control over every keyframe in our animation similar to high-end animation software. The second will let us copy timeline animations as fully editable Actionscript 3.0 XML objects for easy duplication and modification. It looks like even complex tweening that uses a motion guide can be copied and edited, no clarity about the coping of a shape tweens though. I guess no one at adobe have the nerve to dive into the Flash core and update something as the Shape Hints or even the Timeline itself, but overall, it seems like a nice update in terms of the animation abilities of Flash.

Flash CS3 will be released in April 20th.

Behind The Curtains - Shape Hints Animation Tutorial

Hover above this box:

I was amazed when I first saw shape animation in flash, create two different shapes on two different frames and easily get a morphing animation between them...

Few years back I was asked to make a flash banner for Habima Theater. I came with the, somewhat cheesy, idea of a animating a red curtain, and inside it, to fade images from few of the theater best shows.

Creating a curtain animation in Flash shouldn't be a problem, I thought, I'll create the start and finish frames and my beloved Flash will do the rest. The start frame of a simple curtain animation is simply a box and the end frame is an open curtain...

1. Create a new Flash Document, resize it to 320 x 240 and set the Frame rate to 30.

Document Properties

2. Create a red rectangle (R) anywhere on the stage no matter what size, select the rectangle and set it's properties (Show/Hide Properties Ctrl+F3): width and height to 160 and 240 respectively, x and y both to 0.

3. With the rectangle still selected press F8 to turn it into a Movie clip, and name it curtain.

Convert to Movie clip

4. Inside the properties panel name the instance of the curtain on stage to leftCurtain.

properties

5. Double click on leftCurtain to step inside it. On the Timeline (Show/Hide the Timeline Ctrl+Alt+T) name Layer 1 to curtain. Right click on the 30th frame and select Insert Keyframe (F6).

Insert Keyframe

6. The first frame of our animation, the closed state of our curtain is already done on frame 1, we'll now create the opened frame on frame 30. Deselect the red rectangle by clicking anywhere outside it on the stage. Point your mouse to the bottom right corner of the rectangle until the mouse cursor turns into a right angle shape, this indicates that you can grab the corner. With the Shift Key pressed click and drag the rect corner to the left and to about 45px from the left edge.

Drag Corner

7. In order to achieve an open curtain look we'll split it near the bottom. Point the cursor near the edge of the now diagonal line to about 50px from the bottom. When the cursor changes its shape to a small round line, press Ctrl and click to drag the new point to left to about 30px from the edge. Pressing on the Ctrl key while dragging a line breaks it and creates a new point where the break is.

Drag Middle

8. Similar to the previous step, hover with the mouse near the right edge of the rectangle, when the cursor change it's shape click and drag (without pressing Ctrl) the edge until it gets a nice belly, do the same for the small right edge.

Drag Belly

9. We done the entire 2 frames of our animation, now it's time to animate it. In the Timeline Select frame 1 and in the properties panel set Tween to Shape, also set Ease to 70, it will make the animation nicer by easing it near the end.

Tween

10. It looks like we got ourselves an opening curtain animation, but testing the movie (Ctrl+Enter) reveals that though we got an animation it's nothing like a believable curtain. This is because Flash can't know what exactly we're animating and how we like the morphing to be done. Flash simply guess, and this time its guess is very wrong. This is where Shape Hints come to our aid.

11. Select frame 1 and click on Modify -> Shape -> Add Shape Hint (Ctrl+Shift+H) 5 times. This will create 5 Shape Hints identified by characters from a to e. Arrange the Hints in the 4 corners and 1 where the break is, look at the image. Go to frame 30 and arrange the Hints respectively to the 1th frame. Every Hint character in frame 1 must correspond to the Hint character in frame 30.

Shape Hints

Tip: you can lock the layer and still be able to edit the Shape Hints.

Tip: Show/Hide all the Shape Hints Ctrl+Alt+H

12. Now lets test our movie (Ctrl+Enter) to see our curtain animate to its open state as it should.

13. To create the closing animation the simplest way is to duplicate the frames and then reverse it. Select all the frames in the curtain layer by clicking on its name and Right click -> Copy frame then Right click on frame 31 and select Paste frames. This will copy the opening animation, Shape Hints included. Click on frame 31 and while the Shift key is pressed click on frame 60 to select all of this frames range. Right click on the selected frames and click Reverse frames, it'll reverse the animation but sadly it'll also break the Shape Hints of this section, you'll have to create it again for frame 31 and 60, similar to the previous step.

14. Select frame 31 and in the properties panel set the Ease to -50, this will create an ease-in effect so the closing animation will start a bit slower and then accelerate as it goes.

15. Test the movie to see the (half) curtain open and close. Thats it, we're done our curtain animation it's time to duplicate the half into a full curtain and put some interactivity into it.

16. Before you go back to the main stage add another Layer inside the curtain Movie clip and name it actions. Click on Window -> Actions (F9), while the first frame selected enter the code stop(); inside the Action panel. Create a new key frame on frame 30 of the actions layer and put a stop(); in there as well. This will prevent the curtain from animating on its own and we'll control it with Actionscript.

Stop Action

17. Go back up to Scene 1 by double clicking on an empty area of the stage. Copy the leftCurtain Movie clip, paste it any where, set its x to 160, its y to 0 and its name to rightCurtain.

18. With the rightCurtain selected click on Modify -> Transform -> Flip Horizontal.

19. On the main Timeline in Scene 1 create another layer and name it actions open the actions panel (F9) and enter the following script:

function openCurtain():Void{
leftCurtain.gotoAndPlay(1);
rightCurtain.gotoAndPlay(1);
}

function closeCurtain():Void{
leftCurtain.gotoAndPlay(31);
rightCurtain.gotoAndPlay(31);
}

20. We can call these functions to open and close the curtain as we like, in this example we'll open the curtain when the mouse roll over it and close it when it roll out.

21. Create another layer beneath the actions layer but above the curtain layer and name it hitArea. Draw a green rectangle and set it's alpha to 0%, the color doesn't really matter since this rect will be invisible, also set it's width to 320, height to 240 and x, y to 0. Click F8 to turn this rectangle to a Movie clip and name it hitArea. in the properties panel name the hitArea instance on the stage to hit.

22. Add this code to the actions layer:

hit.onRollOver = openCurtain;
hit.onRollOut = closeCurtain;

Now every time we roll over the invisible hit Movie clip that is above the curtain the function openCurtain will be called and when we'll roll out from it the closeCurtain will be called.

23. Test the movie to see that we now got our interactive animated curtain, roll over it and it opens, roll out and it closes. But, if you'll play with it a little you'll see that it's not always act as it should. For example, when you roll out while the curtain is opening it jumps to beginning of the closing sequence instead of closing from the current position. To fix that we'll add a simple calculation to find the right frame we need to jump to in order for the animation to look seamless.

24. Replace the code in the action frame with this:

hit.onRollOver = openCurtain;
hit.onRollOut = closeCurtain;

var nTotalFrames:Number = leftCurtain._totalframes;

function openCurtain():Void{
var nFrame:Number;
if(leftCurtain._currentframe > nTotalFrames / 2){
nFrame = leftCurtain._totalframes - leftCurtain._currentframe + 2;
}else{
nFrame = leftCurtain._currentframe;
}
leftCurtain.gotoAndPlay(nFrame);
rightCurtain.gotoAndPlay(nFrame);
}

function closeCurtain():Void{
var nFrame:Number = leftCurtain._totalframes - leftCurtain._currentframe;
leftCurtain.gotoAndPlay(nFrame);
rightCurtain.gotoAndPlay(nFrame);
}

We just changed the open and close functions to be a bit more smart ones, function that knows to which frame to gotoAndPlay, it does it according to the current frame and not just jump blindly to the beginning of each sequence.

Test the movie and behold, our interactive curtain is ready.

Tip: you can add this code, hit.useHandCursor = false; so the cusror won't change into a hand when you hover the curtain.

Download Curtain Animation source files

Script# - C# compiled into Javascript

Thursday, December 14th, 2006

This might sound familiar to you, the idea of writing an Object Oriented code, that allow compile-time checking, and good code design, that is then compiled into a script code was introduced by Macromedia at 2003 with Flash 7 and it's shiny new Actionscript 2.0, but, AS2, with all the respect is not as complete as C#.

Script# does the same for Javascript, it lets you leverage the power of C# with it's Object Oriented abilities and compile it into a clean and readable Javascript.
The new Script# version 0.2.0.0 now have added support for WPF/E.

Learn more about it...

There is a similar OS tool named Google Web Toolkit that appearntly does similar things for Java and Javascript.

Careful with these decompilers

Thursday, September 14th, 2006

I was playing with the last Sothink SWF Decompiler (SSD) on my own swfs, just to see how it looks like and to check if it can re-fla it. It was long since I played with such and then it was before the re-fla generetion of decompilers. The decompiler did a fine job revealing all the assets and code inside the swf, just like it used to do in the older versions. The code revealed is AS1 but that's, as you probably know, is how the code is compiled-to from AS2, so it isn't the decompiler fault. Now, I went to check how well it can export the swf into an fla. SSD automaticaly suggested to save the exported FLA with the same filename as the SWF, only prefixed with ~ and in the same directory. I've nonchalantly clicked OK, anyhow this FLA is insignificant, all the code is in the classes... as it suddenly came to me, what about my classes. I immediately went to check on my classes, only to find out my fear was justified. SSD has overwritten my AS2 classes with his exported AS1. All were laying there deformed into inferior form, all in the same classpaths, and all without ASKING for confirmation you impudent brat (I meant to SSD, not you ;)). Ok, you gotta to relax, I told to myself, it isn't much of a problem right now with the pushy deadline, as long as the classes will continue to function properly, I'll worry about esthetics later, I just need it to work properly right now. But it didn't, work.. that is, actually it did work about 90% percent ok, but there were definitely some issues. And to start looking for these issues with the disorder it made out of my code when even the few comments I have in there are gone and all of my local variables are now named _loc1, loc2, etc'. Luckily for me, relatively luckily, the swf I recompiled was just a small test file that has incorporated only a few classes, so I managed to restore most of it from backups and reorganize/rewrite the rest. Anyhow it was a painfull ordeal.
Next time I'll be much more carefull with these kind of tools and I'll keep it away from my original files.

Best way to get address variables into Flash

Friday, July 21st, 2006

I've seen too many wrong or old soulotions for sending query string variables into Flash (page.html?var1=Jon&var2=Smith... etc.). In fact, if you'll google it you'll find this old Macromedia article from the year 2000 and about Flash 4, while most of it still applies it's definitely old. These days, we're using swfobject, if you don't use it then you should, swfobject comes with a "global" javascript function called getQueryParamValue and you can use it for setting query/address string variables into FlashVars as follows:

JavaScript:
  1. var so = new SWFObject("movie.swf", "flashMovie", "250", "150", "8", "#FFFFFF");
  2. so.addVariable("var1", getQueryParamValue("var1"));
  3. so.addVariable("var2", getQueryParamValue("var2"));

These variables will be availble as _root.var1, _root.var2, etc. For complete explanation go here. The best thing about FlashVars is that they are available for use as soon as the Flash movie starts, and before everything else, so you can refer, for example, to the variable _root.var1 in the first line of code, as opposed to another old method setVariable, where we had to wait for the variable availability using somthing like watch.

Though the advantage of FlashVars, personly, I don't like _root variables, it seems unclean, especially when it's a long query string that'll make tons of them floating in my _root. Since Flash 8 we can use ExternalInterface to call to getQueryParamValue and get an immediate and synchronous response from within Flash, that way we can have a neater control over owr address variables, for example:

Actionscript:
  1. var sVar1:Object = ExternalInterface.call("getQueryParamValue", "var1");

Play with the example, try different variables.

If you don't use swfobject, I guess you can easily write your own javascript method for getting address variables, but why bother, I don't think you can easily improve on that one. I also don't think that Geoff Stearns, the author of swfobject, will care if you'll copy this function:

JavaScript:
  1. function getQueryParamValue(param){
  2. var q = document.location.search || document.location.hash; if(q){
  3. var startIndex = q.indexOf(param +"=");
  4. var endIndex = (q.indexOf("&", startIndex)> -1) ? q.indexOf("&", startIndex) : q.length;
  5. if (q.length> 1 && startIndex> -1) {
  6. return q.substring(q.indexOf("=", startIndex)+1, endIndex);
  7. }
  8. }
  9. return "";
  10. }

It's great for non flash websites as well.

Get example files

Get swfobject

Understanding Flash’s ExternalInterface.

Monday, June 19th, 2006

It occurs to me that too many people are not aware of the Flash 8 new and shiny ExternalInterface and are still using fscommand and setVariable or getURL for flash-javascript communication.
In this post I'll describe the advantages of ExternalInterface over the previous solutions, how to use it, a short tutorial about it, and also about the future of Flash-to-Javascript symbiosis with FABridge. Bear in mind that the ExternalInterface Class can be used to communicate from a flash-swf file to any kind of a supported container, in this text I will focus on a webpage container and we'll connect to its Javascript functionality. We could, for example, use it in a similar way to communicate between Flash hosted inside an executable and its C# functionality.


Why should I care ?!

There are many reason to use Flash-Javascript communication, the more general ones are: using functionality that doesn't yet implement naturally into Flash like XPath, REgEx, etc'. Controlling other webpage elements, active-x or plugin, from Flash. For example: Window Media Active-x. Using Flash with AJAX, and much more.
Check Step by step tutorials at the bottom of this text.


ExternalInterface minimum requirements

The ExternalInterface Class is only available from Flash 8 and above and will work only in Flash Player 8 and above. Also, there is a minimum browser requirement, the supported are:

Windows Internet Explorer 5.0 and above
Firefox 1.0 and above
Mozilla 1.7.5 and above
Netscape 8.0 and above
Safari 1.3 and above.
Opera 9 and above.
And any browser that supports the NPRuntime API.

The static Boolean property ExternalInterface.available will indicate whether the requirements are meet. Check it from within your targeted container / browser.
Click on the button, if it's 'false' then your browser is probably not supported, if it's 'undefined' then your player is probably less then version 8, if it's 'true' you're ready to go!


If you're targeting a not supported browsers or an older Flash players, then you may consider: Flash / JavaScript Integration Kit


Main improvements:

Easier to setup:
Well, that's an understatement, in order to make your flash ready for javascript communication you need to do..., nothing. But, because of the new Flash 8 Player security you can't test your files locally. Meaning that, the files will only run properly on a web server. If you want to test your files locally, all you have to do is make sure that the "allowScriptAccess" is set to "always" inside your html Flash <object> tag, like this:
<param name="allowScriptAccess" value="always" /> to support firefox and alike change also the <embed> tag: allowScriptAccess="sameDomain" to "always".
If you're using swfobject your script will look something like this:
so.addParam("allowScriptAccess", "always");. This also won't guaranty that your files will work locally in all cases, though. You might also need to go to the Flash Player Setting Menager and add the swf files or folder as trusted. Here is a video demo on how to do that.
In Flash 6, 7 some Javascript and Vbscript functions had to be written in order to catch the fscommand calls from Flash. Flash 7 and above can insert these function automatically for you if you choose: Publish Settings... -> HTML -> Template->'Flash with FSCommand'. But it's still ugly.

Synchronous:
Which mean you can return a value from a Javascript function into flash and vice versa. If you ever used flash-to-javascript communication before flash 8, you'll understand how useful this is. On previous versions of Flash this couldn't be done. In order to receive data from javascript, we had to call a javascript setVariable, and that only worked on Object's/MovieClip's dynamic properties, and then we had to watch / wait for the data that was written into the MovieClip's property to arrive to Flash. As opposed to now, communication was asynchronous, the data just wasn't available instantly, and since the Object.watch sux so much in Flash 7. onEnterFrame or intervals had to be used. (I'll admit that the Object.watch can be suitable in simple cases, though)

Calling Actionscript functions from Javascript:
Again, an amazing improvement. Now, any declared Flash function can be called directly from javascript with a simple script like flashMovie.someFunction(); and if this function returns a value it can be synchronously received by the browser's Javascript. Before Flash 8, if we wanted something done inside flash and do it from javascript, calling a flash function for example, we had to set up a flag and go through a similar process as described above, of waiting/watching for that flag/data to arrive into Flash. Then according to that flag call the desired function.

Multiple Variables:
ExternalInterface enable us to send or receive as many arguments as we want or send none. With the old fscommand only 1 and at least 1 string could have been sent to a javascript function.

Multiple Data types:
ExternalInterface supports, sending and receiving, arguments of type: Boolean, String, Number, Array, Object (user defined classes are not supported). Sorry to be dramatic again but this has almost brought tears of joy to my eyes. All this time we had to use nothing more then one lousy String.


How to use the ExternalInterface Class

Calling is easy, Use the static ExternalInterface.call() function.

import flash.external.ExternalInterface;

ExternalInterface.call("alert", "called from flash");

This will call the javascript's 'alert' function with the value of "called from flash"

alert_called_from_flash.jpg

For me, this is the most important improvement: Synchronous. If the Javascript function return a value you can simply retrieve it as follows (in this example it's a Number but it can be any of the supported types):

var nValue:Object = ExternalInterface.call("someJSFunction");

To declare a Flash function as callable from Javascript you simply use the static ExternalInterface.addCallback() function.

The addCallback static method accepts 3 arguments. The first is a string representing the name, the Actionscript function should be called at, from Javascript. The second is an object reference for the Actionscript function, it's where the scope of "this" inside the Flash function will be. The third is a reference to the Flash function. It is recommended to name the Javascript function the same as the real Flash function for sake of clarity.

ExternalInterface.addCallback("someFlashFunction", this, someFlashFunction);

Use this Javascript code to get a reference to your Flash movie.

"flashMovieID" is the ID of the Flash movie object inside the HTML.

JavaScript:
  1. <script><!--
  2. flashMovie = thisMovie("flashMovieID");
  3.  
  4. function thisMovie(movieName) {
  5. &nbsp;var isIE = navigator.appName.indexOf("Microsoft") != -1;
  6. &nbsp;return (isIE) ? window[movieName] : document[movieName];
  7. }
  8. //call the Flash function
  9. flashMovie.someFlashFunction();
  10. // --></script>

If the Flash function returns a value you can retrieve it as follows, as you might guessed:
var oValue = flashMovie.someFlashFunction();


Step by Step Tutorials for ExternalInterface

I will publish some step by step tutorials with in-depth explanation, source code and images in the next posts. I want to keep this post more concise. (or maybe I'm just too lazy right now... ;))

Among the tutorials will be:

Best way to get browser's address variables into Flash.
Controlling another Active-X control - creating flash buttons for Windows Media Player or Apple Quicktime.
Putting Javascript power in Flash's use - RegEx and XPath.
Catching Javascript Exceptions in Flash.
Creating, a, dynamic Flash website with AJAX.


Examples

Download ExternalInterface availability check

The Flash 8 IDE Installation will install two examples of using the ExternalInterface including the fla sources. But, it doesn't work locally because they forgot to update the html <object> "allowScriptAccess" to "always". If you want to check these examples locally simply change the word "sameDomain" wherever it appear (change it twice: one for the object param and one for the embed param) to "always" from within the html files. If it's still doesn't work go to the Flash Player Setting Menager and add the swf files or folder as trusted. As described above under Easier to setup:

Find the examples here:
In Windows, browse to boot drive\Program Files\Macromedia\Flash 8\Samples and Tutorials\Samples\ActionScript\ExternalAPI.
• On the Macintosh, browse to Macintosh HD/Applications/Macromedia Flash 8/Samples and Tutorials/Samples/ActionScript/ExternalAPI.


The future of Flash-Javascript symiosis with FABridge

Adobe wants to make Flash an IDE independent platform. Which means we'll be able to create Flash RIA websites and application without the need of Adobe Flex Builder, Using the free Flex SDK, free Flex Data Services and any other third party software. Adobe relized that in order to make Flash the dominant force behind the rich web they have to free it from the restraints of any Flash/Flex IDE. And to leave it solely in the hand of the Flash/Flex developer. Adobe wants to make the Flash Platform as standard as HTML is.

With FABridge and alike, after the Flex Builder IDE was removed from the equation, the aim is to reduce the need for the Flex developer. With the insertion of the FABridge library into your Flex project you are completely exposing all the Actionscript 3.0 capabilities to Javascript. Basically you can code complete Flex apps using nothing but Javascript. This will appeal to Javascript developers who are comfortable with it and don't want to develop simultaneously in both Flex and Javascript environments. FABridge will enable us to take full AJAX websites and Frameworks and easily update it to a full Flex websites or Frameworks to harness all the Flash platform capabilities.

FABridge is availble in pre-alpha since march 2006, so there is already some info about it circling around:
Last Friday I saw the online Adobe event "Flex and Ajax - Better Together" with James Ward. While it was mostly about how much superior Flex is from AJAX, he did showed a few integration / FABridge examples.
A similar presentation by Christophe Coenraets is availble here, with some more FABridge examples.

Go here to download FABridge and get some more info about it. Also check this impressive example that only scratch the surface. (require Flash Player 9).

Watch me bleed - Fatal error in Flash 7.0 / 7.2

Sunday, May 21st, 2006

I've stumbled across an interesting error today:

Using the Object.watch can result in a crush of the Flash 7.0 / 7.2 IDE, the Flash 7 stand alone player, and the browser. Apparently this will happen when trying to delete all the properties of an object after one of its properties was assigned to an Object.watch method.

watch_error.jpg

watch_error_player.jpg

I have tried the script below, at my work, on six different Flash 7.2 machines and two 7.0 machines, all gave the same result of crushing the IDE. If you'll be able to compile a SWF out of it, it'll also crush Flash player 7. I have'nt managed to reproduce the error in Flash 8 though, IDE and Player. And sometimes even on Flash 7 it ran as expected without crushing, but, most of the time it'll crush.

This code will probably crush you'r Flash mx 2004 IDE:

var o = new Object();
o.val = 123;
o.watch("val", callFunc);
o.val = 555;

function callFunc(prop, oldVal, newVal){
 trace("watched");
 //o.unwatch(prop);
 clearObject();
 return newVal;
}

function clearObject(){
 for(var i in o){
  trace("o: " + o[i]);
  delete o[i];
 }
}

Download example.

Click on the ball to crush it...
If you first can't get a crush out of it, open and close it a few times.

The end of the decompiling bonanza !

Thursday, May 11th, 2006

DeCompilers software makers excuse their doing by saying: "if you'll ever lose your fla ...." Yeah right, the people who used it to retrieve their lost fla can be counted on one hand. I bat you were wondering what will be the future of these decompilers under the new AS3 and VM2. This guy has asked the question and got an encouraging answer from Adobe. While AS3 wont be bulletproof, it'll definitely be harder to decompile.

 

Flash player inaccuracy clarified

Monday, May 8th, 2006

I was ranting about the Flash inteval inaccuracy in some older post. Finaly, there is an article by Tinic Uro that clarifies why intervals and frame rates accuracy in the flash player is so nasty.

The article

Check your Interval

Tuesday, March 14th, 2006

I was amazed by the inaccuracy of intervals in flash. At least on my system a 1000 millisecond is about 1056 milliseconds. I'm using flash player 8.5 alpha 3 and the swf was compiled with flash 7. On some other systems I've checked this the 1000 ms was acurate but other values were not. On my system some starnge values I've tried, like 546, 682, etc' came out accurate. What gives !?!

Check your interval:

intervalinaccuracy.zip

setTimeout in flash 7

Thursday, March 9th, 2006

As you might know Flash 8 was reinforced with the setTimeout functionality. You can now tell flash 8 player to run a function once after a given milliseconds/interval:

setTimeout(trace, 1000, "string to trace");

will trace the string "string to trace" after 1 second.

But what if you're like me, and still need to use flash 7 or even 6, and you also want to enjoy the simplicity of setTimeout. Well I was using my own implementation of setTimeout since flash 6, first with a function and when AS2 came out, I've rewriten it into a simple class you can download here.
To use it unzip the 'net' folder into your flash classpath if you don't sure about the classpath just search for it in the flash help or put it in the same directory as your fla. Now you can use it in your flash 7 or above as follows:

import net.guya.Timeout;

Timeout.set(trace, 1000, "string to trace");

this will do the same as the above function and willl trace the string "string to trace" after 1 second. As with the flash 8 'setTimeout' in the flash 7 'Timeout.set' you can send as many variables as you like after the interval. The trace function only expects one string variable so thats what she gets.

Here is another example:

You can also pass an object reference to Timeout.set

Timeout.set(this, someFunction, 1000, variabl1, varible2, ...variableN);

for example:

import net.guya.Timeout;

var nX:Number = 100;
var nY:Number = 50;
Timeout.set(this, drawLine, 500, nX, nY);

function drawLine(x:Number, y:Number){
   this.lineStyle (2, 0x000000, 100);
   this.moveTo (0, 0);
   this.lineTo (x, y)
}

This program, after 0.5 second will draw a line from the top left to point(100, 50). Here you must send a reference to the object you want the 'this' inside the drawLine function to refer to. In this case it's the MovieClip where the line will be drawn. If no object reference is sent in this case the 'this' inside the drawLine will refer to the Timeout object and so no line will be drawn.

A Timeout can be deleted before its function was called with the 'clear' method:

var nTimeout1:Number = Timeout.set(trace, 2000, "I will never show");

Timeout.clear(nTimeout1);

Nothing will be tarced because the Timeout is deleted before it has a chance to run the trace function.

Download the Timeout Class.

< update >

setTimeout in flash 6

After some feedback I realized I should have written this function also, you only need to copy and paste it in your flash 6 files:

_global.setTimeout = function (o, func, ms){
   var a = new Array();
   for(var i = 3; i < arguments.length; i++) a.push(arguments[i]);
   var n = setInterval(function(){func.apply(o, a); clearInterval(n);}, ms)
   return n;
}

and use it like this:

setTimeout(this, trace, 1000 , "string to trace");

Download the setTimeout for Flash 6 function.

< /update >