I have been trying to put together a proof of concept of JavaScript talking to Flash. I am using JQuery and Flash CS5, ActionScript 3.
I am not a Flash developer so apologies for the code, if I can prove this works the Flash will be given to someone who knows what they are doing.
The Actionscript is on a layer in the timeline in the first frame, with a couple of elements in the root movie:
output = new TextField();
output.y = -200;
output.x = -200;
output.width = 450;
output.height = 325;
output.multiline = true;
output.wordWrap = true;
output.border = true;
output.text = "Initializing...\n";
root.bgClip.addChild(output);
try{
Security.allowDomain("*");
flash.external.ExternalInterface.marshallExceptions = true;
output.appendText("External Interface Available? " + ExternalInterface.available + "\n");
output.appendText("External Interface ObjectId: " + ExternalInterface.objectID + "\n");
flash.external.ExternalInterface.addCallback("getMenuItems", returnMenuItems);
flash.external.ExternalInterface.addCallback("changeText", changeText);
flash.external.ExternalInterface.addCallback("changeBgColour", changeBgColour);
flash.external.ExternalInterface.call("populateMenu", returnMenuItems());
} catch (error:SecurityError) {
output.appendText("Security Error: " + error.message + "\n");
} catch (error:Error) {
output.appendText("Error: " + error.message + "\n");
}
function returnMenuItems():String{
return "[{\"menu option\": \"javascript:callFlash('changeBgColour','4CB9E4')\"}]";
}
function changeText(t:String){
root.textClip.text = t;
}
function changeBgColour(colour:String) {
var c:ColorTransform = root.bgClip.transform.colorTransform;
c.color = uint(colour);
root.bgClip.transform.colorTransform = c;
}
The JavaScript and HTML are:
function populateMenu(message){
$("#options").changeType("Options", $.parseJSON(message));
$("#options").addMenuActions();
}
function callFlash(methodToCall, param){
alert("method: " + methodToCall + ", param: " + param);
if(param == undefined){
$("#AJC")[methodToCall]();
}else{
$("#AJC")[methodToCall](param);
}
}
var flashvars = {};
var params = {allowScriptAccess: "always"};
var attributes = {name: "AJC"};
swfobject.embedSWF("http://192.168.184.128/ActionscriptJavascriptCommunication.swf", "AJC", "600", "400", "9", "", flashvars, params, attributes);
and
<body>
<div id="wrapper">
<div id="topBar" class="top-bar"></div>
<div id="flashContainer">
<div id="AJC">Loading Flash...</div>
</div>
<ul class="dropdown" id="games"></ul>
<ul class="dropdown" id="options"></ul>
</div>
</body>
Now I know the ActionScript is awful, the reason it looks like it does is because I have read a lot of threads about possible issues to do with contacting Flash from JavaScript (hence the allow security domain * and adding a debug text box etc).
The JavaScript I am using is within a script tag in the head. The changeType and addMenuActions are just JQuery methods I have added. These are just JavaScript methods that have been tested independently but do work.
You'll notice that the last line of my try catch in the ActionScript is:
flash.external.ExternalInterface.call("populateMenu", returnMenuItems());
This does work, it populate my menu with the text sent from Flash. The only thing that doesn't work is trying to call the methods exposed using the addCallback function.
I get the alert which says:
method: changeBgColour, param: 4CB9E4
but an error saying:
Error: $("#AJC")[methodToCall] is not a function
Source File: http://192.168.184.128/test.html#
Line: 88
I set up a local VM to run Apache, which relates to the 192.168.184.128, I wondering if this was the issue, I have seen a couple of threads mention that trying to communicate with flash locally won't work, which is why I set up the VM with apache?
Any ideas? I know people have got this working, it is very frustrating.
Thanks.