载入进度动画条与启动画面一样,有着安抚用户急不可耐的小心脏的重要作用。如果没有一个百分比或者进度条的显示,遇到网络比较慢的情况,可能用户会马上关闭了这个全景链接。尤其是在这个讲求快感的时代,让用户知道还有多久能够看到清晰的全景,你就能多留住更多的客户。
默认的cofu皮肤只有一个“loading”的文字提示,当载入一个新的场景时,只出现一个文字提示是不够的。在官方的安装包的路径 examples\xml-usage\progress
如果直接双击html文件,就能看到下图的进度条动画,一共有三种形态,一个是自转的动画,一个是百分比数字,一个是进度条。
然后我们来看example.xml,实际上起作用的就是那三段include代码。
- <include
url="progress_loadinganimation.xml"
/> - <include
url="progress_loadingpercent.xml"
/> - <include
url="progress_loadingbar.xml"
/>
既然这样,我们可以把这三个xml文件以及loadinganimation.png拷贝到我们自己的项目文件夹。然后将上面这三段include的代码复制到tour.xml里。用DW打开这三个xml文件。
先看第一个progress_loadinganimation.xml,这是控制那个png图片序列进行不断自转表示正在载入的代码。
- <krpano>
- <!--
loading animation text --> - <!--
loading animation events --> - <events
name="loadinganimation"
keep="true" - onxmlcomplete="loadinganimation_startloading();"
- onloadcomplete="delayedcall(0.25,
loadinganimation_stoploading() );" - />
- <!--
loading animation graphic --> - <layer
name="loadinganimation" - keep="true"
- visible="false"
- url="loadinganimation.png"
- crop="0|0|64|64"
- align="top"
y="25%" - frame="0"
frames="8" - />
- <!--
loading percent actions --> - <action
name="loadinganimation_startloading"> - set(loadinganimation_isloading, true);
- set(layer[loadinganimation].visible, true);
- loadinganimation_animate();
- </action>
- <action
name="loadinganimation_stoploading"> - set(loadinganimation_isloading, false);
- set(layer[loadinganimation].visible, false);
- </action>
- <action
name="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 --> - <action
name="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>
我们直接来看进度动画的每一段代码的意思
- <events
name="loadinganimation"
keep="true" - onxmlcomplete="loadinganimation_startloading();"
- onloadcomplete="delayedcall(0.25,
loadinganimation_stoploading() );" - />
进度动画需要显示的时间间歇是在onxmlcomplete和onloadcomplete之间,因此在onxmlcomplete响应(xml文件代码解析完毕)时则开始执行loadinganimation_startloading,也就是进度动画开始,当onloadcomplete(全景图片加载完成后,也就是百分百加载结束后)就得结束进度动画,即loadinganimation_stoploading。
- <action
name="loadinganimation_startloading"> - set(loadinganimation_isloading, true);
- set(layer[loadinganimation].visible, true);
- loadinganimation_animate();
- </action>
- <action
name="loadinganimation_stoploading"> - set(loadinganimation_isloading, false);
- set(layer[loadinganimation].visible, false);
- </action>
loadinganimation_startloading首先是让一个参数loadinganimation_isloading为true,然后设置png图片这个图层可见,并执行loadinganimation_animate(图片序列动起来的代码)。loadinganimation_stoploading则是一个简单的逆向设定,把true该为false。
- <action
name="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 --> - <events
name="loadingbar"
keep="true" - onxmlcomplete="loadingbar_startloading();"
- onloadcomplete="delayedcall(0.25,
loadingbar_stoploading() );" - />
- <!--
loading bar graphics --> - <layer
name="loadingbar_bg"
keep="true"
type="container"
bgcolor="0x000000"
bgalpha="0.5"
align="bottom"
y="25%"
width="33%"
height="20"
enabled="false"
visible="false"> - <layer
name="loadingbar_space"
type="container"
align="left"
x="4"
width="-8"
height="12"> - <layer
name="loadingbar_fill"
type="container"
bgcolor="0xFFFFFF"
bgalpha="1.0"
align="lefttop"
width="0"
height="100%"
/> - </layer>
- </layer>
- <!--
loading bar actions --> - <action
name="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>
- <action
name="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 --> - <events
name="loadingpercent"
keep="true" - onxmlcomplete="loadingpercent_startloading();"
- onloadcomplete="delayedcall(0.25,
loadingpercent_stoploading() );" - />
- <!--
loading percent graphics/text --> - <layer
name="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 --> - <action
name="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>
- <action
name="loadingpercent_stoploading"> - set(loadingpercent_isloading, false);
- set(layer[loadingpercent_text].visible, false);
- </action>
像进度条我们可以简单地改变进度条的颜色,百分百也可以改成我们熟悉的中文。