首页 > 代码库 > 进阶教程(8)- 制作载入进度条
进阶教程(8)- 制作载入进度条
载入进度动画条与启动画面一样,有着安抚用户急不可耐的小心脏的重要作用。如果没有一个百分比或者进度条的显示,遇到网络比较慢的情况,可能用户会马上关闭了这个全景链接。尤其是在这个讲求快感的时代,让用户知道还有多久能够看到清晰的全景,你就能多留住更多的客户。
默认的cofu皮肤只有一个“loading”的文字提示,当载入一个新的场景时,只出现一个文字提示是不够的。在官方的安装包的路径 examples\xml-usage\progress
如果直接双击html文件,就能看到下图的进度条动画,一共有三种形态,一个是自转的动画,一个是百分比数字,一个是进度条。
然后我们来看example.xml,实际上起作用的就是那三段include代码。
<includeurl="progress_loadinganimation.xml"/>
<includeurl="progress_loadingpercent.xml"/>
<includeurl="progress_loadingbar.xml"/>
既然这样,我们可以把这三个xml文件以及loadinganimation.png拷贝到我们自己的项目文件夹。然后将上面这三段include的代码复制到tour.xml里。用DW打开这三个xml文件。
先看第一个progress_loadinganimation.xml,这是控制那个png图片序列进行不断自转表示正在载入的代码。
<krpano>
<!-- loading animation text -->
<!-- loading animation events -->
<eventsname="loadinganimation"keep="true"
onxmlcomplete="loadinganimation_startloading();"
onloadcomplete="delayedcall(0.25, loadinganimation_stoploading() );"
/>
<!-- loading animation graphic -->
<layername="loadinganimation"
keep="true"
visible="false"
url="loadinganimation.png"
crop="0|0|64|64"
align="top"y="25%"
frame="0"frames="8"
/>
<!-- loading percent actions -->
<actionname="loadinganimation_startloading">
set(loadinganimation_isloading, true);
set(layer[loadinganimation].visible, true);
loadinganimation_animate();
</action>
<actionname="loadinganimation_stoploading">
set(loadinganimation_isloading, false);
set(layer[loadinganimation].visible, false);
</action>
<actionname="loadinganimation_animate">
mul(xcrop, layer[loadinganimation].frame, 64);
txtadd(layer[loadinganimation].crop, get(xcrop), ‘|0|64|64‘);
if(loadinganimation_isloading,
inc(layer[loadinganimation].frame);
if(layer[loadinganimation].frame GE layer[loadinganimation].frames, set(layer[loadinganimation].frame,0));
delayedcall(0.05, loadinganimation_animate() );
);
</action>
</krpano>
其实上面这段代码的核心和动画热点(也就是png图片序列是一样的)下面是动画热点的核心代码
<!-- hotspot animation action -->
<actionname="hotspot_animate">
inc(frame,1,get(lastframe),0); mul(ypos,frame,frameheight); txtadd(crop,‘0|‘,get(ypos),‘|‘,get(framewidth),‘|‘,get(frameheight)); delayedcall(0.03, if(loaded, hotspot_animate() ) );
</action>
我们直接来看进度动画的每一段代码的意思
<eventsname="loadinganimation"keep="true"
onxmlcomplete="loadinganimation_startloading();"
onloadcomplete="delayedcall(0.25, loadinganimation_stoploading() );"
/>
进度动画需要显示的时间间歇是在onxmlcomplete和onloadcomplete之间,因此在onxmlcomplete响应(xml文件代码解析完毕)时则开始执行loadinganimation_startloading,也就是进度动画开始,当onloadcomplete(全景图片加载完成后,也就是百分百加载结束后)就得结束进度动画,即loadinganimation_stoploading。
<actionname="loadinganimation_startloading">
set(loadinganimation_isloading, true);
set(layer[loadinganimation].visible, true);
loadinganimation_animate();
</action>
<actionname="loadinganimation_stoploading">
set(loadinganimation_isloading, false);
set(layer[loadinganimation].visible, false);
</action>
loadinganimation_startloading首先是让一个参数loadinganimation_isloading为true,然后设置png图片这个图层可见,并执行loadinganimation_animate(图片序列动起来的代码)。loadinganimation_stoploading则是一个简单的逆向设定,把true该为false。
<actionname="loadinganimation_animate">
mul(xcrop, layer[loadinganimation].frame, 64);
txtadd(layer[loadinganimation].crop, get(xcrop), ‘|0|64|64‘);
if(loadinganimation_isloading,
inc(layer[loadinganimation].frame);
if(layer[loadinganimation].frame GE layer[loadinganimation].frames, set(layer[loadinganimation].frame,0));
delayedcall(0.05, loadinganimation_animate() );
);
</action>
png图片序列的核心,就是你要知道每个小图标在图片的位置,因此这时候crop就起到非常重要的作用,crop可以把图片的某个区域单独显示,也就是我们一直在改变着crop的参数,使得显示的区域不断地变化,这样就做成了动画效果。你也可以看看这张png图片,它就是由八个有差异的小图组成的一个图片,每次我们需要将crop里面第一个X坐标增加64,也就是从当前的小图标向右挪到下一个图标,然后这样的一个过程仅需要0.05秒,人眼自然看不到改变的细节,就会将将这个过程视作动画。
mul是一个数学方法,实现的是乘法,也就是让64与frame包含的数值相乘,frame是layer[loadinganimation]的一个自定义属性,它最初是0,因此crop出来的第一个就是0|0|64|64,具体是通过txtadd来实现的。然后判断是否还在载入当中,如果是的话,就让frame增加1,也就是下一个crop肯定是1乘以64,即是64|0|64|64,以此类推。那么当这个frame等于8的时候,也就是等于我们定义的小图标的个数时,就得重新将frame设为0,这样才能不断循环。直到loadinganimation_isloading为false,循环才会结束。
因此如果你要移花接木的话,基本上就是自己p一张png图片,如果你的小图标不只8个或少于8个,那么对应的layer的自定义的属性frames就要相应的进行修改,也就是除了url和frames两个属性以外,其他基本不用动。
接下来的百分比和进度条都要涉及到对与元素progress的应用。首先是进度条progress_loadingbar.xml
<krpano>
<!-- loading progress bar -->
<!-- loading bar events -->
<eventsname="loadingbar"keep="true"
onxmlcomplete="loadingbar_startloading();"
onloadcomplete="delayedcall(0.25, loadingbar_stoploading() );"
/>
<!-- loading bar graphics -->
<layername="loadingbar_bg"keep="true"type="container"bgcolor="0x000000"bgalpha="0.5"align="bottom"y="25%"width="33%"height="20"enabled="false"visible="false">
<layername="loadingbar_space"type="container"align="left"x="4"width="-8"height="12">
<layername="loadingbar_fill"type="container"bgcolor="0xFFFFFF"bgalpha="1.0"align="lefttop"width="0"height="100%"/>
</layer>
</layer>
<!-- loading bar actions -->
<actionname="loadingbar_startloading">
set(loadingbar_isloading, true);
set(layer[loadingbar_bg].visible, true);
asyncloop(loadingbar_isloading,
mul(pv, progress.progress, 100);
txtadd(pv, ‘%‘);
copy(layer[loadingbar_fill].width, pv);
);
</action>
<actionname="loadingbar_stoploading">
set(loadingbar_isloading, false);
set(layer[loadingbar_bg].visible, false);
</action>
</krpano>
events的部分是相似的,进度条用的是三个container,主要就是一个底图,一个是已经载入的进度以及一个还没载入的空白。这里值得注意的是一个asyncloop的action以及对progress.progress的使用,asyncloop的条件成立时会每一帧执行一次循环事件,而progress.progress则是当前进度的一个小于1大于0的数值,因此pv会是一个大于0小于100的数值。将pv赋值到对应载入条layer的宽度width中,这样这个layer的宽度就会一直变化。
类似的是百分比的progress_loadingpercent.xml
<krpano>
<!-- loading percent text -->
<!-- loading percent events -->
<eventsname="loadingpercent"keep="true"
onxmlcomplete="loadingpercent_startloading();"
onloadcomplete="delayedcall(0.25, loadingpercent_stoploading() );"
/>
<!-- loading percent graphics/text -->
<layername="loadingpercent_text"keep="true"
url="%SWFPATH%/plugins/textfield.swf"
align="center"
background="false"
border="false"
autoheight="true"
css="text-align:center; color:#FFFFFF; font-family:Arial; font-weight:bold; font-size:22px; font-style:italic;"textshadow="2"
html=""
/>
<!-- loading percent actions -->
<actionname="loadingpercent_startloading">
set(loadingpercent_isloading, true);
set(layer[loadingpercent_text].visible, true);
asyncloop(loadingpercent_isloading,
mul(pv, progress.progress, 100);
roundval(pv,0);
txtadd(layer[loadingpercent_text].html, ‘Loading ‘, get(pv), ‘%‘);
);
</action>
<actionname="loadingpercent_stoploading">
set(loadingpercent_isloading, false);
set(layer[loadingpercent_text].visible, false);
</action>
像进度条我们可以简单地改变进度条的颜色,百分百也可以改成我们熟悉的中文。
进阶教程(8)- 制作载入进度条