negush blog

Flash, ActionScript and stuff…

February-9-10

ExternalInterface.call not working with IE

posted by admin

While working on a few PhotoSnack albums a few days ago, I’ve tested some features with several browsers but noticed that with Internet Explorer the albums were not working as supposed to. Specifically, the ExternalInterface.call() function wasn’t calling the target JavaScript functions at all.

After testing the JavaScript and ActionScript functions separately, it seemed they all worked without any problems. Anyway, the JavaScript functions were being called with no problems on all the other browsers I tested, except on Internet Explorer. After searching the problem on the Internet I came upon a comment on the ActionScript 3 documention posted on Adobe’s livedocs for the ExternalInterface class (thanks gerdy).

It looks like for the ExternalInterface.call() function to work in IE, the embedded Flash object MUST have the id attribute specified. Otherwise you won’t be able to display not even a JavaScript alert message from Flash. As soon as the id attribute was set for the flash objects in PhotoSnack, the albums worked just fine with Internet Explorer too.

So, as a best practice, I recommend always setting the id attribute of your Flash objects embedded in HTML pages.

February-1-10

Google, can you hear us ?

posted by admin

We’ve just launched a petition on Facebook: we would really like for Google to allow ActionScript 3 .swf files for AdWords. If we scream loud enough, maybe Google will hear us. So please, those of you who have a Facebook account, sign our petition. If Google will allow AS3 .swf file for its AdWords system, we will all benefit.

Thanks to all of you.

July-2-09

FlashEff2 officially launched

posted by admin

Today JumpeyeComponents has officially launched the next version of the popular Flash animation tool – FlashEff. Now it has a redesigned workflow that makes life even easier and comes with a solution to lower the file size of your Flash clips: the FlashEff2 component has a lower size than the predecessor and it comes with another set of components – FlashEff2 Light.

The FlashEff2 Light pack contains separate animation components, each one specialized to do one of the main component’s jobs: show/hide animations for symbols, show/hide animations for texts, applying filters, creating buttons and executing commands. So you can use only that one feature you really need for your project without having to import all the FlashEff2 features into your Flash clip. This way you can lower the file size of the final animation even more.

Here are some other features for FlashEff2:

  • a large number presets that you can choose from (3000+ presets)
  • the possibility to tweak those presets or to make your own settings
  • create and save your own custom effects which you can reuse any time you want
  • a completely new button mode

Here you can find more information on the component’s features and watch some nice video tutorials that will help you get started with FlashEff2. There’s even a nice video on the home page based on the comments users left on this JumpeyeComponents blog post.

I’m testing the Red5 server to see how to use it for audio and video streaming but right after testing the connection to the server, I get the following error message in my Output Panel (though the connection to the server has been established correctly):

Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetConnection 
was unable to invoke callback onBWDone. error=ReferenceError: Error #1069: Property 
onBWDone not found on flash.net.NetConnection and there is no default value.

After digging around it seems that I didn’t specify the client for the NetConnection object:

netConnection.client = this;

After setting the client property, all was well. So don’t do the same mistake as I did.

There are situations when you need to create a web application that is part Flash, part HTML, like some handy widget that must reside in an HTML page and that would also have to communicate with it. The next example presents a simple color setting widget made with Flash, which communicates with the web page it is integrated in. Basically the Flash widget contains three slides to set the RGB color value and the composed color is displayed in the HTML page, in a text input control. The user also has the possibility to enter a hexadecimal value of a color in that text input which will set the sliders in the Flash widget to the corresponding values. Flash – HTML communication (actually ActionScript – JavaScript communication) is possible by using the ExternalInterface class within the flash.external package.

The ExternalInterface class was created to replace the older fscommand() function and can be used to call JavaScript functions from ActionScript or call ActionScript functions from JavaScript. It is also able to transmit a return value from the function being called to the code (ActionScript or JavaScript) calling the external function. It is much more flexible than fscommand() since it allows calling any JavaScript function defined in the HTML file with any number of arguments (of various data types), while fscommand() allowed calling a limited number of functions with a single String as argument. Also allows receiving a return value from the JavaScript function call to ActionScript and vice versa.

Calling a JavaScript function from ActionScript is quite easy. All you have to do is call the static call function of the ExternalInterface class:

ExternalInterface.call("myJSFunction");

You can even specify function parameters and receive the return value, like this:

import flash.external.ExternalInterface;
var value:String = ExternalInterface call("myJSFunction", param1, param2, param3);

Of course this means that in the HTML file containing your Flash clip there has to be a JavaScript function defined with the name of “myJSFunction”. In the above example, we presume that the type of the return value of the JavaScript function is a String, but the ExternalInterface class allows receiving other types of values too.

Calling an ActionScript, from within your HTML document using JavaScript is equally easy. All you have to do is get a reference to the Flash object embedded into the HTML document and then call the ActionScript function directly on this object. Of course, this requires that the ActionScript function is defined as a callback function for the JavaScript code, in the main timeline of the Flash clip:

ActionScript code:

ExternalInterface.addCallBack("myASFunction", someASFunction);

JavaScript code:

var flashMovie = window.document.MyFlashWidget;
flashMovie.myASFunction(value);

In this case, the name and id attributes of the Flash object must be set to “MyFlashWidget”. Another requirement for the HTML document is to set the allowScriptAccess attribute of the Flash object to “always”.

“myASFunction” is the function name that the external JavaScript code must call, but the actual name of the ActionScript function is “someASFunction”. This way, external JavaScript code can only have access to the ActionScript code that the developer allows to. Also, in this case, if the ActionScript code must change and the “someASFunction” function is removed, there could be another function passed to the addCallBack method. Thus, it is ensured that “myASFunction” always gets called by JavaScript and that Javascript can actually be oblivious to the changes of the ActionScript code.

One more thing worth mentioning is that it is a good practice to check if the JavaScript code is available for calling, before actually making any calls to it. This way possible errors or malfunctions are avoided in the application:

if (ExternalInterface.available) {
	try {
		ExternalInterface.addCallback("myASFunction ", someASFunction);			}
	catch(e:Error) {
		// Callback function could not be added for various reson.
		// You could treat this situation here.
	}
}

You can download the full example from here. I hope it will help out some of you.

Update: For Internet Explorer you should make sure that you specify your embedded Flash object the id attribute, as mentioned in this post: ExternalInterface.call not working with IE.

April-23-09

ActionScript 3.0 and Flex optimization

posted by admin

I’ve just found an article on InsideRIA that is actually a list of techniques and best practices for optimizing ActionScript 3.0 code and Flex applications. This is a must know for AS3 / Flex developers. The article has a list of references – information on which the article was based. I really recommend you reading through those articles and also through the comments to the article. You’ll find there a few more links to optimization articles and some extra notes on the information in the article.

Update: Grant Skinner has also published an AS3 performance tester. You might want to check it out. Oh, and I had another post about an interesting AS3 performance tester application. There’s a wiki page too, created by Joa Ebert, listing some AS3 optimization tips.

April-9-09

Import assets from Library

posted by admin

In ActionScript 2.0 it is quite easy to import movie clips from Library via the MovieClip.attachMovie() function. In ActionScript 3.0 it’s a little bit different. The movie clips (or assets in the Library) don’t have a linkage id anymore. Instead they have class names.

So the way to import a movie clip (or another asset) is to first get a reference to that class specified as class name. This is done using the flash.utils.getDefinitionByName() function. Then instantiate the class and finally add the object to the display list.

Here is a simple example:

1
2
3
4
5
6
7
8
9
import flash.utils.getDefinitionByName;
 
var className:String = "TestClip";
var ClassReference:Class = getDefinitionByName(className) as Class;
var clip:MovieClip = new ClassReference();
 
addChild(clip);
clip.x = 100;
clip.y = 100;

April-6-09

Skinning applications using a single image

posted by admin

A few days ago one of my colleagues showed me this interesting tutorial on how to use a single image as a sprite map to skin an entire application. The idea isn’t new at all, desktop applications use it a lot to change their appearances.

Basically, you have a single large image that contains graphical elements used by the controls of the application. You read the image and extract those graphical elements (bitmap images). This Flash tutorial shows you just how you could do it in Flash: http://flash.tutsplus.com/tutorials/effects/build-a-smart-flash-decalsheet-system/. This is quite interesting and worth going through.

March-29-09

Listing the properties of an object

posted by admin

This is easy for AS2 – you just use a for() statement to go through all the properties the object has:

for (var i in obj) trace(i+" = "+obj[i]);

There would be the property names listed in the Output panel along with their values.

But for AS3, it seems that this is not always working. You would use that for() statement but not all the properties would be listed. It happened to me quite a few times. So, how can you display all the properties of an object ? Well, ActionSscript 3.0 has a useful function called describeType(). It is located in the flash.utils package. It must receive the target object (or even a class name) as argument and it returns a XML object containing the properties and methods of that object/class. Pretty neat, huh ?

Now, I’ve played around with it a little and it seems that there’s a catch to it. If your target object is an instance of a dynamic class (it allows you to add new properties dynamically), the describeType() function will only display the properties and methods listed in the class, without the extra properties you might have added. So, practically the final solution might be the use of both the for() loop and the describeType() function, especially if you want to make sure that all of the properties are listed and you’re not sure whether the object is an instance of a dynamic class or not. Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
import flash.utils.describeType;
 
var obj:Object = new Object();
obj.param1 = "param1";
obj.param2 = 23.3;
obj.param3 = 29;
obj.param4 = false;
 
for (var i:* in obj) trace(i+" :: "+obj[i]);
trace("---------");
var description:XML = describeType(obj);
trace(description);

Displays

param1 :: param1
param2 :: 23.3
param3 :: 29
param4 :: false
---------
<type name="Object" isDynamic="true" isFinal="false" isStatic="false">
  <method name="hasOwnProperty" declaredBy="Object" returnType="Boolean" uri="http://adobe.com/AS3/2006/builtin">
    <parameter index="1" type="*" optional="true"/>
  </method>
  <method name="isPrototypeOf" declaredBy="Object" returnType="Boolean" uri="http://adobe.com/AS3/2006/builtin">
    <parameter index="1" type="*" optional="true"/>
  </method>
  <method name="propertyIsEnumerable" declaredBy="Object" returnType="Boolean" uri="http://adobe.com/AS3/2006/builtin">
    <parameter index="1" type="*" optional="true"/>
  </method>
</type>

If you want to list the properties and methods separately, using the describeType() function, here’s how to do it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import flash.utils.describeType;
import flash.media.Camera;
 
var obj:Camera = new Camera();
var description:XML = describeType(obj);
 
trace("Properties:\n------------------");
for each (var a:XML in description.accessor) trace(a.@name+" : "+a.@type);
 
trace("\n\nMethods:\n------------------");
for each (var m:XML in description.method) {
	trace(m.@name+" : "+m.@returnType);
	if (m.parameter != undefined) {
		trace("     arguments");
		for each (var p:XML in m.parameter) trace("               - "+p.@type);
	}
}

Displays

Properties:
------------------
motionTimeout : int
activityLevel : Number
loopback : Boolean
fps : Number
height : int
width : int
motionLevel : int
bandwidth : int
muted : Boolean
name : String
index : int
keyFrameInterval : int
currentFPS : Number
quality : int
 
 
Methods:
------------------
setKeyFrameInterval : void
     arguments
               - int
setLoopback : void
     arguments
               - Boolean
setQuality : void
     arguments
               - int
               - int
setCursor : void
     arguments
               - Boolean
setMotionLevel : void
     arguments
               - int
               - int
setMode : void
     arguments
               - int
               - int
               - Number
               - Boolean
hasEventListener : Boolean
     arguments
               - String
dispatchEvent : Boolean
     arguments
               - flash.events::Event
removeEventListener : void
     arguments
               - String
               - Function
               - Boolean
willTrigger : Boolean
     arguments
               - String
addEventListener : void
     arguments
               - String
               - Function
               - Boolean
               - int
               - Boolean
toString : String

Please note that the function will not return any static properties the object might have. If you want to get the list of static properties too, you need to provide the class name as argument of the function and not an instance of the class:

1
2
3
4
import flash.utils.describeType;
 
var description:XML = describeType(Event);
trace(description);

Displays

<type name="flash.events::Event" base="Class" isDynamic="true" isFinal="true" isStatic="true">
  <extendsClass type="Class"/>
  <extendsClass type="Object"/>
  <constant name="COMPLETE" type="String"/>
  <constant name="FULLSCREEN" type="String"/>
  <constant name="UNLOAD" type="String"/>
  <constant name="CONNECT" type="String"/>
  <constant name="CLOSE" type="String"/>
  <constant name="SCROLL" type="String"/>
  <constant name="DEACTIVATE" type="String"/>
  <constant name="ENTER_FRAME" type="String"/>
  <constant name="ID3" type="String"/>
  <constant name="SELECT" type="String"/>
  <constant name="SOUND_COMPLETE" type="String"/>
  <constant name="TAB_CHILDREN_CHANGE" type="String"/>
  <constant name="INIT" type="String"/>
  <constant name="TAB_ENABLED_CHANGE" type="String"/>
  <constant name="MOUSE_LEAVE" type="String"/>
  <constant name="ADDED_TO_STAGE" type="String"/>
  <constant name="OPEN" type="String"/>
  <constant name="CANCEL" type="String"/>
  <constant name="REMOVED" type="String"/>
  <constant name="REMOVED_FROM_STAGE" type="String"/>
  <constant name="ADDED" type="String"/>
  <constant name="RENDER" type="String"/>
  <constant name="TAB_INDEX_CHANGE" type="String"/>
  <constant name="CHANGE" type="String"/>
  <constant name="RESIZE" type="String"/>
  <constant name="ACTIVATE" type="String"/>
  <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
  <factory type="flash.events::Event">
    <extendsClass type="Object"/>
    <constructor>
      <parameter index="1" type="*" optional="false"/>
      <parameter index="2" type="*" optional="true"/>
      <parameter index="3" type="*" optional="true"/>
    </constructor>
    <method name="stopImmediatePropagation" declaredBy="flash.events::Event" returnType="void"/>
    <accessor name="type" access="readonly" type="String" declaredBy="flash.events::Event"/>
    <method name="preventDefault" declaredBy="flash.events::Event" returnType="void"/>
    <accessor name="currentTarget" access="readonly" type="Object" declaredBy="flash.events::Event"/>
    <method name="toString" declaredBy="flash.events::Event" returnType="String"/>
    <accessor name="target" access="readonly" type="Object" declaredBy="flash.events::Event"/>
    <accessor name="bubbles" access="readonly" type="Boolean" declaredBy="flash.events::Event"/>
    <accessor name="cancelable" access="readonly" type="Boolean" declaredBy="flash.events::Event"/>
    <method name="clone" declaredBy="flash.events::Event" returnType="flash.events::Event"/>
    <method name="formatToString" declaredBy="flash.events::Event" returnType="String">
      <parameter index="1" type="String" optional="false"/>
    </method>
    <accessor name="eventPhase" access="readonly" type="uint" declaredBy="flash.events::Event"/>
    <method name="stopPropagation" declaredBy="flash.events::Event" returnType="void"/>
    <method name="isDefaultPrevented" declaredBy="flash.events::Event" returnType="Boolean"/>
  </factory>
</type>

In this case the constants are all listed as sub-nodes of the main node and the properties and events are actually found in a sub-node called <factory> so the way to get the list of properties and methods will be relative to the <type><factory> node. Also, the isStatic attribute of the base <type> node will tell you that the target object is static or not.

March-26-09

A Boolean value occupies 4 bytes ???

posted by admin

I had a little time today to go through some of the blogs I read and Lee Brimelow wrote on The Flash Blog that a Boolean takes up 4 bytes (confirmed by the Flash player team). Initially, in his article he wrote about one byte being occupied by a Boolean but he updated it later on.

While I understand having a Boolean occupy 1 byte (guess that would be a minimum size for objects), I think having 4 bytes for a Boolean is a little too much. Especially since a Boolean value can only have two values (true/false – 0/1) so it would only need a single bit. In this case, 10 Booleans would take up to 40 bytes. Now, for the great majority of Flash apps this isn’t really a problem but for those who need to keep their apps to a VERY VERY minimal, that space could count, or in case when high speed is needed.

The conclusion: don’t use too many Booleans if you don’t have to or use Lee’s method of to handle more Boolean values (a good one I might add), by using ByteArrays.