前言废话
为什么要做相册?
(1)相册,老生常谈,但搜索相关教程和源代码,基本都是分祯手动摆放loader,并在对应祯上分配图片路径再配合this这个特殊变量指待自身制作而成,感觉不大好,因为我不大会写代码,所以讨厌那种祯上和MC到处是代码的东西,烦琐且不易查看和改写,尤其是哪些问题需要注意,没有说明,不人性。
(2)以杂家愚见,图片是一个包括处理(PS)和展示(FLASH)的统一体,再美的图片如果不能展示,枉然,所以,用flash展示图片的能力很重要,当然,你有权反驳你可以把图片传到博客,那说明我们不是同一路人。
为什么今天才写?
(1)要我做一个东西,我得首先想有没有个清晰的思路,没有,不做,直到想到为止;其次实现方法是否简单,太复杂了,不做,因为我怕出错了没那心思找错。基于以上两点,我从来没亲自写过一个相册。
(2)几天前,我在贵宝地发现了这个帖子,地址:
http://bbs.blueidea.com/thread-2669734-1-7.html,思路很好,所以决定试着做一个,做着做着,有内化了些自己的东西和感想,感言不吐无快,故写下一篇教程,算是做个纪念。
正文
声明:这些代码肯定会有些问题存在或有更简单更优化的方式,希望互帮互助,指点一下我们共同的江山。
我曰:看了以上我给出的帖子地址,下他的源文件,下了吗?
你应:下了并看懂了他的代码
好,接下来我得首先指出他源代码中的一点bug,在他对页面数量进行判断的时候,他采用的方式是pageno=Math.floor(nums/pagesize)+1;//判断总页数,我改写为pageno=(nums%pagesize==0)?nums/pagesize:Math.floor(nums/pagesize)+1;//判断总页数,比较一下,可以发现他忽略了一种情况,当nums%pagesize==0时会产生一个空白页。
导读:为了增加代码可读性,我将分为两部分,从基础到复杂逐步叙述;
对于这个相册由于代码基础差,在写的过程中会到了许多问题,这可能也是一种经验或财富,所以我也就不怕丢人现眼,把一些我曾犯过的错误写在后面的标注里面。
第一部分:基本的图片载入技巧,从基础开始,反璞归真;
第二部分:解读相册基本构成及实现方法,原形毕露,显现真正意义上的相册,外加一些必要特效;
第三部分:加入动态元素,显示当前图片信息;
第四部分:整合代码交给你自己,按前面的步骤写好代码,检查是否完整,测试吧。
要实现下面几个部分效果,你需要构造一些基本的部件:
一个链接名为loadmc的MC,里面包含背景(bg_mc),模拟加载中的小动画loading_mc,一个装载图片的空MC(loadpic_mc),按钮btn_mc。
第一部分
目标:载入图片成缩略图形式+分类功能
首先看一段trace语句,以下我将做个简单概括,以便能首先理解他的大概流程和思路,这对些代码很重要,如下:
xml loaded
mc shumu=20
loader0
loader1
loader2
loader3
loader4
loader5
loader6
loader7
loader8
loader9
loader10
loader11
loader12
loader13
loader14
loader15
loader16
loader17
loader18
loader19
complete
当前id为1
complete
当前id为2
complete
当前id为3
complete
当前id为4
complete
当前id为5
complete
当前id为6
complete
当前id为7
complete
当前id为8
complete
当前id为9
complete
当前id为10
complete
当前id为11
complete
当前id为12
complete
当前id为13
complete
当前id为14
complete
当前id为15
complete
当前id为16
complete
当前id为17
complete
当前id为18
complete
当前id为19
complete
当前id为20
可以看出,这个相册的执行流程大概为:
载入XML————————————————要显示资料(即图片),首先必须要有资料
构造装载图片的容器——————————loader0~loader19就是通过计算出来的当前页容器数用attachmovie 动态构造的容器。
载入图片到容器————————————这有一个思想要掌握:载入图片我采用的是xml+moviecliploader 方法,这种方法载入图片的方式是:取得当前页面第一个容器对应图片在XML中实际编号,并载入到第一个容器即loader0中,一待载完,就会触发myobj.oncomplete事件(如上,我用trace(” complete")来观察事件状态),同时id++,从而不断重复,直到条件为假。
细节——————————————————变量初值定义,自定义函数,增加监听,再就是最重要的书写要仔细,错误往往在出细节方面,后面我将提到我写这个代码时由于不仔细导致的一些错误。
源代码如下:
时间轴部分:var id=0;
var pagesize=20;
var pageno=1;
var myML=new MovieClipLoader();
var myobj=new Object();
myML.addListener(myobj);
myobj.onLoadComplete=function(){
trace("complete");
if(id<cnums+pagesize*(pageno-1)){
id++;
trace("当前id为"+id)
loadpic(id);
}//if(id<cnums+pagesize*(pageno-1))在该语句上,起初我把pageno-1写成了pageNo-1,而上一个trace语句能执行,我发现是该条件没通过,后来才检查到是写错了,所以说写代码要仔细
}
myobj.onLoadInit=function(tar){
tar._width=85;
tar._height=53;
tid=id-1;
cid=tid-pagesize*(pageno-1);
_root["loader"+cid].loading_mc._visible=false;
_root["loader"+cid].bg_mc._visible=false;
//_root["loader"+cid].btn_mc.pid=tid;
_root["loader"+cid].btn_mc.onRelease=function(){
//ttid=this.pid;
//url=mylist[ttid].firstChild;
//getURL(url);如果你想有”单击小图转到地址“效果,曲调这个函数体内的//即可
}
}
var myxml=new XML()
myxml.ignoreWhite=true;
myxml.onLoad=function(suc){
trace("xml loaded");
if(suc){
mylist=myxml.firstChild.childNodes;
nums=mylist.length;
loadmc();
loadfirstpic();
}
}
var lei=1;
myxml.load("list"+lei+".xml");
for(var i=1;i<=3;i++){
_root["lei"+i].lei=i;}
function loadmc(){
if(pagesize*pageno>nums){
cnums=nums%pagesize;}
else{
cnums=pagesize}
trace("mc shumu="+cnums)
for(var j=0;j<pagesize;j++){
removeMovieClip(_root["loader"+j])
}//你也可以不要这前面的,从头到尾用这几个容器,上面两句起到重载作用,祛除旧容器,根据当前页容器变量值重新装载容器,避免了一些空白容器的产生
for(var i=0;i<cnums;i++){
_root.attachMovie("loadmc","loader"+i,100+i);
trace(_root["loader"+i]._name)
_root["loader"+i]._x=90*(i%5);//(i%5)中的括号千万不能省略,否则坐标的错误会导致一些MC显示不出来
_root["loader"+i]._y=60*Math.floor(i/5);
}
}
function loadfirstpic(){
imgurl=mylist[id].attributes.path;
myML.loadClip(imgurl,_root.loader0.loadpic_mc)
}
function loadpic(id){
imgurl=mylist[id].attributes.path;
lid=id-pagesize*(pageno-1);
myML.loadClip(imgurl,_root["loader"+lid].loadpic_mc)
}
fir_btn.onRelease=function(){
id=0;
pageno=1;
loadmc();
imgurl=mylist[id].attributes.path;
myML.loadClip(imgurl,_root["loader0"].loadpic_mc)
}
last_btn.onRelease=function(){
trace("last");
id=pagesize*(pageno-1);
pageno=(nums%pagesize==0)?nums/pagesize:Math.floor(nums/pagesize)+1;//判断总页数,注意pagesize==0千万不要写成pagesize=0(“=”是赋值运算符,左边必须是变量或属性)
loadmc();
imgurl=mylist[id].attributes.path;
myML.loadClip(imgurl,_root["loader0"].loadpic_mc)
}
pre_btn.onRelease=function(){
pageno--;
if(pageno<=0){pageno=1
}
id=pagesize*(pageno-1);
loadmc();
imgurl=mylist[id].attributes.path;
myML.loadClip(imgurl,_root["loader0"].loadpic_mc)
}
next_btn.onRelease=function(){
trace("release next");
pageno++;
var yeshu=(nums%pagesize==0)?nums/pagesize

Math.floor(nums/pagesize)+1);
if(pageno>=yeshu){
pageno=yeshu;
}
trace("总页数="+yeshu)
id=pagesize*(pageno-1);
loadmc();
imgurl=mylist[id].attributes.path;
myML.loadClip(imgurl,_root["loader0"].loadpic_mc)
}
//2008.5.18 5:13测试完工
//分类功能测试于7:37完成 平沙
按钮部分:舞台有三个MC分别为lei1,lei2,lei3
每个MC上加同样动作:
on (release) {
_root.id=0;
_root.pageno=1;//将id,pageno归零,否则单击转入另一类图片时,他会延续原来的id,pageno载入图片
_root.myxml.load("list"+this.lei+".xml");//myxml在根时间轴,所以要引用它,前面必须加路径_root
}
以下解释希望使代码看起来更有基础:
(1)判断当前页容器数并载入if(pagesize*pageno>nums){
cnums=nums%pagesize;}
else{
cnums=pagesize}
.
.
.
.
.
(2)容器排列
排列方法有很多,此方法是在经典看到的一篇帖子提到过的,很巧妙
for(var i=0;i<cnums;i++){
_root.attachMovie("loadmc","loader"+i,100+i);
trace(_root["loader"+i]._name)
_root["loader"+i]._x=90*(i%5);//(i%5)中的括号千万不能省略,否则坐标的错误会导致一些MC显示不出来
_root["loader"+i]._y=60*Math.floor(i/5);
}
余数优势—————————————————————————— 生成X坐标
Math.floor()方法也是一个很重要的概念,“舍零取整”——————生成Y坐标
(3)图片分页
分页的本质很简单:就是根据当前页面变量值(即pageno,以下所要说到的按钮控制页数跳转就是在“通过按钮改变pageno值),载入不同编号图片文件总页数判断:这我在最先就说过了pageno=(nums%pagesize==0)?nums/pagesize:Math.floor(nums/pagesize)+1;//判断总页数
按钮控制页数跳转:我先截段代码说明
pre_btn.onRelease=function(){
pageno--;
if(pageno<=0){pageno=1
}
id=pagesize*(pageno-1);//这里的id变量就是当前页第一个容器应该载入的图片编号
loadmc();
imgurl=mylist[id].attributes.path;
myML.loadClip(imgurl,_root["loader0"].loadpic_mc)
}
按钮控制页数跳转流程:
A————算出单击后的页面数
pageno--;
if(pageno<=0){
pageno=1
}
id=pagesize*(pageno-1);
B————根据当前页面数,装载新的容器
C————在新装载的容器的第一个即loader0载入指定ID的图片,并触发myobj.onLoadComplete事件,不段循环。
(4)编号互换
把XML文件里指定编号(id)的图片加载到舞台上的容器,XML文件编号(即图片总数)大于容器编号(即自定义loader数量)时,举个例子,如要把[50]编号的图片加载到舞台,而舞台只有20个容器,这就存在个编号互换的问题。
可以用以下语句达到目的:
lid=id-pagesize*(pageno-1);
看看,是不是感觉和前面”按钮控制页数跳转“所截取代码id=pagesize*(pageno-1)有一点联系呢,的确有联系
id=pagesize*(pageno-1)—————— loader0,何解?
当前页应该载入的图片编号第一个载入loader0,那其他编号的图片要载入哪个容器呢?
很显然,用lid=id-pagesize*(pageno-1);得其容器编号最恰当不过了
不明白的可以查阅我的自定义函数 loadpic(id)
(5)调整显示_root["loader"+i]._x=90*(i%5);
_root["loader"+i]._y=60*Math.floor(i/5);
上面的代码有弹性,可以自定义页面容积(pagesize),以决定每页显示多少图片。
自定义容器整体坐标偏移,即在_x或_y的右边加上一个常数。
自定义每行显示图片数,就是上面函数中的”5“,不过上下两句自定义数必须相等,有点数学知识的一想就明白。
自定义行及列间距,结合前面两个自定义数值便可以做出各种规则排列效果,举个例子:
_root["loader"+i]._x=90*(i%10);
_root["loader"+i]._y=350+0*Math.floor(i/5);
这样一改便做出个坐标为(0,350),一行十列(行间距由60改为了0,5改为了10)
(6)分类功能
时间轴部分:
var lei=1;
myxml.load("list"+lei+".xml");
for(var i=1;i<=3;i++){
_root["lei"+i].lei=i;}
按钮部分:
on (release) {
_root.id=0;
_root.pageno=1;//将id,pageno归零,否则单击转入另一类图片时,他会延续原来的id,pageno载入图片
_root.myxml.load("list"+this.lei+".xml");//myxml在根时间轴,所以要引用它,前面必须加路径_root
}
说明:能传附件了,但由于我所用的图片太大,传不上来,只能用小图片代替了,借用我先前提到的帖子里面的图片。
该部分源码地址:
第二部分
目标:载入图片成缩略图形式+分类功能+单击缩略图在指定区域以指定大小显示大图
基本思路:载入+控制显示大小+必要特效
载入部分:
新建一个用来显示大图的空MC,命名为showimg,再用MovieClipLoader,增加监听对象实现
不过其中有一个难点和技巧,关于大图地址变量动态赋值,这里我又用了this这个特殊变量,代码如下:
在myobj.onLoadInit=function(tar)函数体内加入语句
_root["loader"+cid].btn_mc.showimg_url=id-1;//动态赋予id数。注意,这里的_root不能改为this,因为他包含在onloadinit事件中,里面的this是以myobj为基础的,可以在其中用trace(this),显示[object object]
同样在函数体内_root["loader"+cid].btn_mc.onRelease=function()事件内部加入语句:
this.show_url=mylist[this.showimg_url].attributes.path;
trace(this.show_url)//测试用
myMCL.loadClip(this.show_url,"showimg")
控制显示大小:
var myMCL=new MovieClipLoader()//本来我不想再重新定义个监听对象,第一次载入还可以,但当Press舞台上的任意一个按钮,loader容器中的图片由于会执行myobj.onloadinit事件,但他不是执行第一个,导致图片载入不正常
var myobj2=new Object()
myMCL.addListener(myobj2)
myobj2.onLoadInit=function(tar){
imgw=470
imgoldw=tar._width
imgoldh=tar._height
trace("w="+imgoldw+"h="+imgoldh)//同一图片URL,即对同一图片press之后,虽然他们是一个url,但每press一 下,其值都会累加
bili=imgoldh/imgoldw
imgneww=imgw
imgnewh=imgw*bili
_root.showimg.onEnterFrame=function(){
showimg._width+=(imgneww-showimg._width)/2
showimg._height+=(imgnewh-showimg._height)/2
//_root.onEnterFrame=function(){
//showimg._width+=(imgneww-showimg._width)/2
//showimg._height+=(imgnewh-showimg._height)/2
// }
//此种状态下,上面的宽高只能加一次,而不能缓冲到imgneww和imgnewh
}
changeshow()//不要写在_root.showimg.onEnterFrame=function()内部
}
必要特效:缓冲变动+图片全方位展示
缓冲变动很简单:
_root.showimg.onEnterFrame=function(){
showimg._width+=(imgneww-showimg._width)/2
showimg._height+=(imgnewh-showimg._height)/2
}
图片全方位展示:图片随鼠标移动而移动
加入函数changeshow()
定义函数changeshow()
function changeshow(){
showimg._x=0
showimg._y=0
_root.onEnterFrame=function(){
left=0
right=470
up=0
down=300
if(_root._xmouse>left&&_root._xmouse<right&&_root._ymouse>up&&_root._ymouse<down){
showimg._x-=(_root._xmouse-right/2)/10
showimg._y-=(_root._ymouse-down/2)/10
if(showimg._x>left){
showimg._x=left
}
if(showimg._y>up){
showimg._y=up
}
if(showimg._x<right-showimg._width){
showimg._x=right-showimg._width
}
if(showimg._y<down-showimg._height){
showimg._y=down-showimg._height
}
}
}//end enterframe
}
第三部分:页面动态显示:在舞台拉一动态文本框,变量取名为count,在时间轴myobj.onLoadComplete=function()函数体内加入以下语句即可:
pagetotal=(nums%pagesize==0)?nums/pagesize:Math.floor(nums/pagesize)+1;
_root.count="当前页数为第"+pageno+"页"+"总页数"+ pagetotal ;
[
本帖最后由 SUNXINZHE 于 2008-6-1 00:01 编辑 ]