通过Flash+JavaScript+API来解析fla文件.docx
《通过Flash+JavaScript+API来解析fla文件.docx》由会员分享,可在线阅读,更多相关《通过Flash+JavaScript+API来解析fla文件.docx(15页珍藏版)》请在冰豆网上搜索。
通过Flash+JavaScript+API来解析fla文件
通过Flash+JavaScript+API来解析fla文件
1引言
在flash教学中,有时需要对学生的媒体创作做一些量化
的统计,以检验学生的学习程度。
在这个过程中,需要设定一
磐知识点(比如对Flash作品中淡入淡出效果的检测),然后学
生根据这些知识点完成对作品的创作并提交。
对于学生提交上
来的大量作品(fla文件),检验手段成了一个困难的问题。
如
果依靠教师的手工批阅,这将是一件十分繁重的任务,所以自
动分析fla文件成了一个非常迫切的要求。
虽然Macromedia公
司不提供fla文件格式说明,但提供FlashJavaScriptAPl支持,
使得可以从另外一个角度去分析fla文件。
2FlashJavaScriptAPI
根据nash提供的帮助文档,可以知道:
FlashJavascript
API即nashJavascript应用程序编程接口,是一个辅助编程工
具。
该工具可用来创建在创作环境中运行的脚本。
同时,作为
扩展Flash的主要部分,FlashJavaScriptAPI提供了在F/ash创
作环境中(即用户保持Flash程序打开期间)执行多个动作的
脚本的功能,这有助于简化创作过程。
这意味着,既可以利用
其来创作E1.够h动画,也可以利用其来读取fla文件中各种对
的属性。
3Flash文档对象模型(DOM)
要做到这一点,还需要了解一下Flash文档对象模型
fDOM).因为n聃hJavaScriptAPI基于文档对象模型(DOM),
该模型允许使用JavaScript对象访问Flash文档(即fla文档)。
在nash帮助文档中,提供了对于DOM结构包括各个对
象的方法和属性的详细描述。
但根据实际情况,一般只需了解
其中主要的对象和属性。
图l中描述了对有用的简化的Flash文档对象模型。
用于flashJavaScriptAFI的flash文档对象模型(DOM)
包含一组顶级函数和两个顶级对象(FLfile对象和Flash对象
(Ⅱ))。
一切就从这两个顶级对象开始。
(1)启动flash8,选择新建“FlashJavaScript文件”命令,
在编辑器中输入以下代码:
varstrlis:
newArray();定义(字符串)数组
vartimeLines=newArray();
f1.openDocument(‘file:
///C:
/check.fIa"}:
//打开被检文件
vardoc:
fl.getDocumentDOM0;得到文档对象模型接口timeLines=doc.timelines;得到Flash时间轴(场景)。
。
。
。
;trIiS.Dush(doc.height);得到文档宽度、高度、背景色、帧率、
,/场景数,并追加到strlis数组中
strlis.push(doc.width);
strlis.push(doc.backgroundColor);
strlis.push(doc.frameRate);
strlis.push(timeLines.length);
FLfilewrite(file:
///C:
/fltesttXt".strtis);,/将strlis数组的值写入.//fltest.txt
//关闭被检文件.closeDocument("file:
l//C:
lcheck-fla',false);,,天即傲伍x‘阡
(2)将文件保存,如“test.jsfl”。
将待检测的fla文件复制到c盘,并命名为”check.fla“的一些文件属性的截图。
(3)双击“test.jsfl”文件运行。
这时会自动肩动Fish
(如果Flash没有肩动).并执行jsn中FlashJava.Script代码,
将结果写人“c:
LOtestixt”文件。
(4)打开fltest.txt,观察得到的执行结果(各属性值以“,”
分隔).如图3所示。
通过上面的例子,可以初步了解RashJavaScript运行机制
以及如何输出结果至外部文件。
5外部程序调用FlashJavaScript(jsfl)
在实际应用中.需要南自己的应用程序去调用Flash
JavaScfipt代码。
不过需要指出的是,外部应用程序必须通过
Flash来达到这个目的(机器上必须安装有nd·Mx及以上完
整版)。
实现此目的的方法很简单,即可以利用sheⅡExecute函
数。
以Delphi为例,调用代码如下:
ShellExecutelApplicationHandle,"open’,’flash.exe’,’c:
\test
js矿nmSW—SHOW);
综上所述.应用原理如图4所示
6应用举例(解析fIa文件)
6.1(Delphi7.0)应用程序界面和运行结果
如图5所示.在主表单L置人一个Button和一个TreeView
控什。
在这个应用中.利用jsn得到解析结果。
为了方便观察
和下一步自动批阅功能.最终解析结果在TreeView控件中以
树状结构显示。
该应J}j完整地呈现了如何读取fla文件中的主
要对象属性值的过程和方法。
6.2外部应用程序代码
uses
ShellAPI;//引用函数ShellExecute所需单元
procedureTFormlButconlClick(Sender:
TObject);#Buttonl
Il点击事件
Var
fList:
TStringList;
b:
beolean;
proceduresplit(vartarlist:
TStringlist;s:
string;c:
widechar);
,,i亥子过程根据特殊字符分割字符串(在本应用中,以”.”字符分
,膈字符串)
var
i:
integer;tempstr:
string;se:
widestring;
begin
tempstr:
=”:
tarlistClear;
ifs<>“then
begin
se:
=widestring(s);
fori:
=1tolength(seldo
begin
ifse[i]=cthen
begin
tarlist.Add(tempstr);
tempstr:
=“:
end
else
tempstr:
=tempstr+seli];
end;
tarlistAdd(tempstr);
end;
end;//split子过程结束
begin//ButtonlClick主程序.解析伯文件井以树形结构显示
||舟析结果
b:
=true;
fList:
=TStnngList.Create;
DeleteFile(’c:
\fTreetxt’):
DeleteFile(’c:
\fltesttxt7):
ShellExecute(Handle."open’,’flashexe’."c:
\fltestjsfl’,州,
SW_SHOW):
whilebdo//等待flashexe执行js制完毕并释放txt控制
,Arv
fList.LoadFromFile(’c坩Iteat.txtl;,,导人结果文件(txt)
b:
=false;
exceDt
continue;
end;
split(fList.Utf8ToAnsi(fList.Strings[0]),’,,):
//以“,”为分隔符分
蒯字符串。
形成一棵树fList.SaveToFile(’c:
\fTree.txt,).
TreeViewl.LoadFromFile(’c:
\fTree.txt,).
fList.Free;
end;
6.3jsfl文件中的FlashJavaScript代码
该代码显示了对fla文档中各个主要对象(如场景、图层、
关键帧、实例、元件等)及其属性的读取方法。
为了更好地观
察代码。
简化了对fla文档中对象属性的读取,即减少了同一
个对象的属性读取代码行,一般读取2个属性。
更多的属性可
以参看Flash中的帮助文件。
源代码如下:
varLevel=0;//{模拟栈指针
varstrlis=newArray();//定义(字符串)数组
Marstr=newString();
f1.openDocument(。
file:
///C:
/check.fla。
):
getTabStr(i)胳到前缀符Tab串,用来构建树的
//层次
{
varS=‘。
:
while(i>0)
{s+=‘。
:
/tab键
i--:
}
returnS:
l
functionstrlisPush(i,S)//替换字符串中的某些特殊符号并
∥追加到strlis数组中
{
str=String(s);
str=str.replace(Ar/g.”):
str=str.replace(An/g,");
str=str.replace(/./g.”):
//去掉“,”
str=str.replace(//9,“}:
//去掉Tab符
str=str.reptace(/('、s’)I舾’$)/g,“)∥去掉首尾空格
strlis.push(getTabStr(i)+str);
l
vardoc=f1.getDocumentDOM0;//文档对象模型
tl=new朋寸间轴对象数组
varlib=doc.1ibrary;//flash元件库对象
varitemArray=newArray();//元件对象数组
varlayerGroup=newArray();//图层对象数组
varframeGroup=newArray();//帧对象数组
varelementGroup-newArray();//元素数组
varfillitem=newArray();,/填充对象数组
varstrokeltem=newArray();II笔触对象数组
varfilterGroup=newArray();//滤镜对象数组
vartimeLines=newArray();,/H寸间轴对象数组
itemArray=lib.items;
timeLines=doc.timelines;
i=O:
j-0:
t=0:
strlisPush(LeveI,"doc。
):
Level++;
str|isPush(LeveI,"height’):
str|isPush(LeveI+1,doc.height);
str|isPush(LeveI,"width。
):
strlisPush(LeveI+1,doc.width);
strIisPush(LeveI,。
backgroundCoIor。
):
st—isPush(LeveI+1,doc.backgroundCoIor);
strIisPush(Level,"frameRate。
):
strlisPush(LeveI+1。
doc.frameRate);
str|isPush(LeveI,"sceneCount。
):
str|isPush(Level+1.timeLines.1ength);
functiongetArray(xarray)
‘
vars=“;vark=0:
for《k=O;k{s=s+xarray【k】+‘:
。
}
re“jmS:
}
functionpushFill(Level.fillitem)//填充对象属性读取函数
{
strlisPush(Level+l,。
color');
strIisPushILeveI+2,fillitem.color);
strIisPushILeveI+1.。
style。
):
strIisPush《LeveI+2.fillitem.styIe):
,,…更多属性略,下同
}
functionpushStroke(Level,strokeltem)//笔触对象属性
,厂读取函数
{
strIisPushILeveI+1,。
color。
}:
strlisPush《Level+2,strokeltem.color);
strlisPush(LeveI+1,。
style。
):
strIisPush(LeveI+2,strokeltem.style);
||‘一
}
functionpushElementFS(Level,k,singleElement)//元素的
肭氧充和笔触属性读取函数
{
doc.seIectNone《):
t1.currentFrame=k;
singleElement.selected=true;
doc.selection[0]=singleElement;
strIisPush《LeveI+1,。
fi¨‘):
fillitem=doc.getCustomFill(。
selection。
):
DushF川lLeveI+1,fillitem);
str|isPush{Level+1,。
stroke”):
strokeltem=doc.getCustomStroke(‘selection。
):
pushStroke(Level+1,strokeltem);
}
functionpushFilter(Level,filterltem),,滤镜对象属性读取函数
{
str|isPushILeveI.filterltem.name);
str|IsPush《LeveI+1.。
name。
):
s订IisPush(LeveI+2.filterltem.name);
str|isPush(LeveI+1.。
angle。
):
strlisPush(Level+2.Math.round(filterltem.angle));
//…
、
functionpushElement(flag.Level.singleElement.k)//元素
,/属性读取函数
{
vars=“:
s=singleElement.elementType;
jfIsingleElement.elementType==。
text。
)//文本
{s=s+。
【_+singleElement.getTe×tStrlng()+。
】-:
)
ifIsingleElement.elementType==。
instance。
)//元件实例,
{s=s+。
l_+singleElement.1ibraryltem.name+。
】。
:
)
strIisPush《LeveI.s):
st¨isPush(LeveI+1,。
name。
):
strlisPush(Level+2.singleElement.name);
strlisPush(Level+l,。
elementType。
):
strlisPush(Level+2,singleElement.elementType);
if(singleElement.elementType==。
shape。
)//形状
f
str|isPush(LeveI+1,。
isGroup’):
str|isPush(LeveI+2,singleElement.isGroup);
strlisPush(Level+1,‘isDrawingObject。
):
strIisPush(LeveI+2.singleElement.isDrawingObject);
if(flag)//形状如果存在于元件库中的元件的图层
,,中,需要进入剪辑元件模式获得填充、笔触等值
{
lib.editltem(itemArray[i].name);
pushElementFS(Level.k.singleElement);
doc.exitEditMode;
)LeVel
else
{
pushElementFS(Levet,k,singleElement);
1
}pushFilter(Level,
if(singleElement.elementType=
{
strlisPush(Level+1,。
textTy
strIisPush(Level+2.singleElement.textType);
strIIsPush(LeveI+1,。
TextString。
):
strlisPush(Level+2.singleElement.getTextStrin90);
//…
if(singleElement.textType==。
static。
)
{
str|isPush《Levei+1.。
orientation。
):
strIisPush(LeveI+2,singleElement.orientation);
}
ifIsingleElement.textType==。
dynamicԬ
singleElement.textType==。
input。
)
{
strIisPush《LeveI+1,。
embeddedCharacters。
):
strIisPush《LeveI+2,singleElement.embeddedCharacters);
str|isPush(LeveI+1,’embedRanges。
):
strIisPush(LeveI+2,singleElement.embedRanges);
}|..·
)
strlisPush(Level+l,。
face。
):
strlisPush(LeveI+2,singleElement.getTextAttr(。
face。
)):
strlisPush(Level+1,。
size。
):
strlisPush(Level+2。
singleElement.getTextAttr(。
size。
)l:
//…
}
if(singleElement.elementType==。
instance。
)
{
str|isPush{Level+1,。
instanceType。
):
strlisPush《LeveI+2,singleElement.instanceType):
strlisPush(Level+l,。
libraryltemName。
);
strlisPush(Level+2,singleElement.1ibraryltem.name):
if{singleElement.instanceType==。
symbol。
)
{
str|isPush(Level+1,。
symbolType。
):
strIisPush《LeveI+2,singleElement.symbolType):
strIisPush{Level+1,。
actionScript。
):
strIisPush(Level+2,singleElement.actionScript);
//…
}
}
filterGroup=singleElement.filters;
if(filterGroup!
=undefined)
{
++:
strlisPush(Level,'filters。
):
forIk=O:
k(LeVef++:
,filterGroup[k]);
。
text。
)Level一一;
}
e。
):
Level一一:
}
}
functionpushFrames(flag,k,Level,singleFrames)//关键帧
腑象属性读取函数{
var.-0:
strIisPush(LeveI,k+1):
strIisPush(LeveI+1,。
name。
):
strlisPush(Level+2,singleFrames.name);
strltsPush(Levej+1,‘soundName‘):
strlisPush(Level+2.singleFrames.soundName);
||.··
if(singleFrames.tweenType!
='none。
)腑h间类型
{
strlisPush(Level+1.。
motionTweenOrientToPath‘):
st州sPush《LeveI+2,singleFrames.motionTweenOrientToPath);
strIisPush(LeveI+1.”motionTweenRotate‘):
strIisPush(LeveI+2,singleFrames.motionTweenRotate);
l|I‘·
)
elementGroup=singleFrames.elements;
strIisPush(LeveI+1,。
elementCount‘):
strIisPush(Level+2.elementGroup.1ength);
Level++;
strlisPush(Level,"elementGroup。
):
whileI(.多元素检测导致程序变慢
{
Level++;
pushElement(flag.Level,elementGroup[i],k):
Level一一:
i++:
}
}
functionpushLayer(flag.Level,singleLayer)//图层对象属性读取函数
{
vark=0:
strlisPush(Level,singleLayer.name);
strIisPush(Level+1,。
layerType。
);
strlisPush(Level+2.singleLayer.1ayerType);
strIisPush(Level+1,。
color。
):
strIisPush{Level+2,singleLayer.colod;
frameGroup=singleLayer.frames;
Level++;
strlisPush(Level,'frameSeries。
):
while(k{
Level++;
pushFrames(flag,k,Level,frameGroup[k]);
k=k+frameGroup[k].duration;
Level--;
l
l
//主程序,获取场景
strlisPush(Level,'scenes‘):
for(t=0;t{
Level++;
tl=timeLines[t];
dec.editScene(t)
strlisPush(Level,t1.name);
Level++;
strlisPush(Level,"frameCount');
strIisPush《Level+1,t1.frameCount);
strlisPushlLeveI,'layerCount。
):
strlisPush(Level+l,t1.1ayerCount);
layerGroup=t1.1ayers;
strlisPush(Level,"layers’):
for(j=0;j{
Level++;
pushLayer(false,L