与浏览器交互

闪归提供了两种与浏览器交互的方式:
一种是使用 flash.external.ExternalInterface 类,这种方式提供了最好的与 Flash 的兼容性,有 Flash 开发经验的开发人员可直接上手。
一种是“闪归”提供的直接调用方式,您可在 Flash 中使用 AS3语言 来操作浏览器提供的各种API, 转换为 HTML5 应用后就如同您直接使用 Javascript 一样。

使用ExternalInterface类

Flash 调用 Javascript 函数

  • 一、在包含转换结果的 html 页面写一个 javascript 函数:
    <script type="text/javascript">
          function helloJS() {
                 alert('hello javascript');                        
          }
    </script>
    
  • 二、在 Flash 调用这个 javascript 函数:
    flash.external.ExternalInterface.call("helloJS");
    
  • 三、执行结果:

Javascript 调用 Flash 函数

  • 一、在 Flash 中注册一个函数,注册名为 "helloAS":
    flash.external.ExternalInterface.addCallback("helloAS",function():void{
        trace("Hello ActionScript");
     });
    
  • 二、在 Javascript 中调用注册的函数:
    • 在包含转换结果的html页中,找到如下元素,并记下其 id,在此示例中,其id为"esContent" :
         <div id="esContent" data-es_url="fireanyway2.js" data-es_base64="false" data-es_render_mode="1" 
         style="border:1px solid #666666;width:940px;height:640px"></div>
                         
    • 调用注册的函数:
      <input type="button" value="调用Flash函数" onclick="javascript:callAS();" />
      <script type="text/javascript">
            function callAS() {
                  //找到 esContent 元素,然后执行注册的 "helloAS" 函数
                  document.getElementById("esContent").helloAS();
            }
      </script>
                         
  • 三、执行结果:

AS3直接操作浏览器API

我们使用 ExternalInterface 类与 Javascript 交互的目的是为了调用浏览器提供的各种功能API, 现在您可以直接用 AS3语言 来操作这些 API了! 转换为HTML5应用后就如同您直接使用 Javascript 操作一样。

准备:

下载并安装 1.0.3 及以上版本的 闪归Flash转HTML5插件

小试牛刀:

  • 打开 Flash 编辑器,并选择菜单:文件>新建>Actionscript 3.0
  • 按 F9 打开动作编辑器窗口
  • 输入如下代码:
    import frToolkit.inJS;
    import frToolkit.js.alert;
    
    if (frToolkit.inJS){
    	trace("在浏览器中");
    	frToolkit.js.alert('你好,浏览器!');
    }else{
    	trace("在flash player中");
    }
    
    代码说明:
    • if (frToolkit.inJS)
      这个语句用来判断当前是处于浏览器环境还是Flash Player环境。
      如果您点击转换插件的"启动转换",将 Flash 转换为 Html5 应用,则此值为 true,表示在浏览器环境运行。
      如果您按下 "Ctrl+回车" 运行这个Flash,则此值为 false,表示是在Flash Player环境运行。
      由于我们将要操作浏览器提供的 API,所以只能在转换为 Html5 后方可使用。

    • frToolkit.js.alert("你好,浏览器!");
      调用浏览器提供的名为 alert 的 javascript 函数,执行后可弹出一个对话框。
  • 运行结果
    • "Ctrl+回车" 直接运行:
    • 转换后在浏览器中:

厉害一点:

下面的代码将调用浏览器提供的 HTMLCanvasElement 并绘制图形和文字后,转换为一个 BitmapData 对象添加到显示列表中。

  • 打开 Flash 编辑器,并选择菜单:文件>新建>Actionscript 3.0
  • 按 F9 打开动作编辑器窗口
  • 输入如下代码:
    import frToolkit.js.HTMLCanvasElement;
    import frToolkit.js.document;
    import frToolkit.js.CanvasRenderingContext2D;
    import frToolkit.inJS;
    import frToolkit.JSTools;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    
    //仅在浏览器环境下执行,因为 Flash Player 并没有 HTMLCanvasElement 这些对象,只有浏览器环境下有。
    if (frToolkit.inJS){
    	
    	//创建一个 HTMLCanvasElement 对象
    	var canvas:HTMLCanvasElement = frToolkit.js.document.createElement("canvas") as HTMLCanvasElement;
    	//设置高宽
    	canvas.width=550;
    	canvas.height=400;
    	//获取 canvas2D 上下文
    	var ctx:CanvasRenderingContext2D = canvas.getContext("2d") as CanvasRenderingContext2D;
    	
    	//画一个圆形
    	ctx.fillStyle = "rgba(46,129,206,1)";
    	ctx.strokeStyle = "red";
    	ctx.beginPath();
    	ctx.arc(250, 60, 50, 0, 2 * Math.PI, true);
    	ctx.closePath();
    	ctx.fill();
    	ctx.stroke();
    	
    	//文字
    	ctx.font="26px 微软雅黑";
    	ctx.fillText("我是用 CanvasRenderingContext2D 创建的",20,160);
    	ctx.strokeText("我是用 CanvasRenderingContext2D 创建的",20,160);
    		
    	//将 HTMLCanvasElement 转换为 BitmapData 对象实例
    	var bmpData:BitmapData = frToolkit.JSTools.imageSourceToBitmapData( canvas );
    	//添加到显示列表中显示
    	this.addChild( new Bitmap( bmpData ));
    }
    
  • 运行结果
    • 转换后在浏览器中:

通过直接操作浏览器提供的API,使得你可以在 Flash 中使用 AS3 语言来直接做以前必须额外调用 Javascript 才能完成的事情!这给您提供了无限的可能!

常见问题

自定义Loading加载条

有时候您希望能创建自己的 loading 加载动画,为此我们提供了3个事件帮助您完成此操作。

  • 事件 esAppInfoInit ,当应用数据初始化完成,准备开始加载前触发。
  • 事件 esLoadProgress ,每次加载进度改变时触发,触发时会向监听函数传递一个对象,访问这个 对象.detail.progress 可获得当前的进度,取值0-100,可能有小数,且不保证一定会到100,所以不要依靠此值判断是否已经加载完成。
  • 事件 esLoadComplete ,加载完成后触发,应监听此事件来确定加载完成,而不应在esLoadProgress中判断进度为100时确定。

如何注册上述事件的监听

  • 在包含转换结果的html页中,找到如下元素,并记下其 id,在此示例中,其id为"esContent" :
    <div id="esContent" data-es_url="fireanyway2.js" data-es_base64="false" data-es_render_mode="1" 
    style="border:1px solid #666666;width:940px;height:640px"></div>
                       
  • 注册事件监听函数:
    在包含转换结果的html页中写入如下 javascript 代码:
    <script type="text/javascript">
    var target = document.getElementById("esContent");
    //注册 esAppInfoInit 事件
    target.addEventListener("esAppInfoInit",function(e){
      console.log("初始化完成,准备开始加载。", e);
    });
    
    //注册 esLoadProgress 事件
    target.addEventListener("esLoadProgress",function(e){
      console.log("加载中,当前进度:", e.detail.progress);
    });
    
    //注册 esLoadComplete 事件
    target.addEventListener("esLoadComplete",function(e){
      console.log("加载完成。", e);
    });
    
    </script>
                       

一个较完整的替换加载动画的示例

在包含转换结果的html页中写入如下 javascript 代码:
<script type="text/javascript">
//找到目标容器
var target = document.getElementById("esContent");
//新的加载条
var newLoadingElement = document.createElement("div");

//注册 esAppInfoInit 事件,在这个事件中移除默认的加载条并替换为新的加载条
target.addEventListener("esAppInfoInit",function(e){
	var appInfoSource = e.detail.appInfoSource;
	var loadingElement = appInfoSource.loadingElement;
	//移除默认的加载条并替换新的加载条
	if (loadingElement.parentElement){

		//移除默认加载条
		loadingElement.parentElement.removeChild(loadingElement);
		//应用新的加载条
		target.appendChild(newLoadingElement);
		//将新的加载条居中显示
		var rect = target.getBoundingClientRect();
		var w = rect.width;
		var h = rect.height;
		var marginTop = ((h-30)/2>>0);
		if (marginTop<0)marginTop = 0;
		var marginLeft =((w-60)/2>>0) ;
		if (marginLeft<0)marginLeft= 0;        
		newLoadingElement.style.margin = marginTop +"px "+ marginLeft +"px" ;
	}
});

//注册 esLoadProgress 事件,每当进度改变就将进度数字在新加载条中显示。
target.addEventListener("esLoadProgress",function(e){	
	var progress = e.detail.progress >>0;//当前的进度数值,有可能带小数,">>0" 可转换为整数。
	newLoadingElement.innerText= progress;
});

//注册 esLoadComplete 事件,在加载完成后移除加载条
target.addEventListener("esLoadComplete",function(e){
	//加载完成后移除加载条
	if (newLoadingElement.parentElement)
		newLoadingElement.parentElement.removeChild(newLoadingElement);
});
</script>
                   

加载外部文件/swf动画

加载外部文件(图片、音频、其它文件)

加载外部文件与在 Flash 中并无不同,您可以直接使用如下类进行外部文件的加载:
  • 使用 flash.display.Loader 类 对图片进行加载
  • 使用 flash.media.Sound 类 对音频进行加载
  • 使用 flash.net.URLLoader 类对其它文件进行加载
在多数情况下,与Flash表现一致。但要注意的是,如果是跨域加载外部文件,则需要目标服务器支持跨域请求。 具体可参考:MDN HTTP访问控制(CORS)

加载外部swf文件

如您要加载名为 a1.swf 的Flash文件
  1. 将 a1.swf 转换为HTML5格式,可以获得一个名为 a1.js 的文件。
  2. 在主文件中写如下代码加载 a1.swf:
    //注意这里是加载 a1.swf ,当转换为 HTML5 版本后,系统会判断如果加载的是 .swf 文件则自动加载同名的 .js 文件
    //如这里在转换后会加载 a1.js 文件。此时您只需要将第一步获得的 a1.js 文件放到同目录下即可。
    var request:URLRequest = new URLRequest("a1.swf"); 
    var loader:Loader = new Loader() 
    loader.load(request); 
    addChild(loader);
                       
可以看到,加载 swf 文件在代码上无需做任何改动。您只需要把被加载的 .swf 文件转换为html5版本,并将获得的 .js 文件放到原路径下即可。