文章目录
更新于 2024.4.19 krpano 1.21.2
官方下载包路径
你电脑的路径\krpano-1.21.2\viewer\examples\animated-hotspots\
提示:如果不了解何谓下载包路径,请查看 循序渐进(3)- krpano下载包的使用说明
动态热点在线演示
VIP会员请登录查看代码运行器
动态热点或图层的原理
让krpano热点(hotspot)或layer图层产生动态效果,例如不断变化的箭头大小或一直变幻颜色的图片,这样更容易引起浏览者的注意,效果也比较酷炫。当提到动态时,会想到使用flash文件或是gif图片,但在krpano中不推荐使用。因为只有Flash内核下才支持swf文件。虽然HTML5内核下支持gif动画,但在很多浏览器下表现不如png图片序列,krpano官方不推荐使用gif动画图片。我们需要使用png图片序列或jpg图片序列(雪碧图,sprite-sheets),配合简单的动态代码,让这些图片动起来。
把图片序列做在一张图(透明png)上。例如下图,我们实际上只是在切换这张图的不同区域从而产生动态效果:
将多张png图片合并成一个png序列图的小工具PngMergeHelper。
同时提供将多个jpg图片合并在一个jpg序列的小工具JPGCombine
下载地址:http://pan.baidu.com/s/1pKxgFpx 密码:36qr
提供一个将gif分离成多个png的小工具GIF分离器
下载地址:http://pan.baidu.com/s/1minnTtm 密码:m3js
可以选择自己制作png动态图,也可以用已有的gif动态图,先分离成多个png,然后合并为一个png序列图(需要在ps中进行背景透明处理)。
注意,因为手机浏览器和硬件性能有限,应该避免png图片或jpg图片的最长边过大,建议不要大于4096×4096像素(低于2000像素为佳,有时候krpano会将大于4096像素的图下缩到更小的尺寸,但会导致需要更多的内存,因此好的解决办法还是直接使用较小尺寸的图片)。例如是9帧的序列图,做成3×3正方形能最大程度减少最长边的长度,即尽可能让序列图拼接后接近正方形。例如官方案例中有一张7*7的序列图。
也就是说要做动态热点或动态图的话,必须有类似上面的一张序列图,如果你只使用一个箭头的单帧图片,然后在hotspot代码或layer代码的url属性写这个箭头的路径,是不会有任何的动态效果的。实际上用PngMergeHelper还可以创造环物全景所需的照片序列png。为什么要把多个图片做成png序列。好处就是切换不同图片时不用重新加载,如果重新加载新图时,也就是更改url属性,速度再快,都会有一个明显的卡顿甚至有个黑块的闪烁(除非是多个热点已经放置在相同位置),使用图片序列的话,我们只是在一开始载入了一张图片,只是通过切换图片的不同区域来制造动画效果的话,这样就避免了在动态热点演示过程中出现卡顿的情况,这同样是环物制作中需要用到png图片序列的原因。而且使用一个png图片也相对比多个png图片减少了文件的总体积。
更多不同样式的热点序列图(推荐下载):
链接:https://pan.baidu.com/s/1wxqZLoKIZ4xKwdbhhfoUbA?pwd=bikp
提取码:bikp–来自百度网盘超级会员V7的分享链接:http://pan.baidu.com/s/1i396ukH 密码:xwaa 收集于720云
收集于www.krpano.tech 发布者:聂云风情
海量动态图素材:
链接:http://pan.baidu.com/s/1hs2lP5M 密码:lezl
技巧 上面的热点部分是黑白素材,可以将整个图放在ps里,做个颜色叠加后,这样就能根据自己的ui颜色改变热点的颜色。
代码
1.19 pr4之后的官方版本优化了对png序列图的处理,你可以使用多横多纵的序列图。如下图是7横x7列的序列图(分辨率为700*700.每一帧为100*100)。
或者是下面的单排序列图(可以是横排或者纵排)。
krpano 1.19 pr4之后案例的png序列图如果是多横多纵的话,其动画顺序是(先横的一排,然后往下到下一排)从左至右,从上至下。
当要使用动态热点或动态layer时,务必要在主xml(tour.xml)空白处的scene标签的外面,放入以下动作代码do_crop_animation
1.19 pr13及之后的版本使用以下代码,作用是一样的(但运行速度更快,因为krpano对不使用%N占位符的action会启用缓存机制)
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<!-- do_crop_animation(framewidth, frameheight, framerate) - 通过改变图像的crop来实现动画效果 - 参数: - framewidth - 以像素为单位的每一帧图像的宽度 - frameheight - 以像素为单位的每一帧图像的高度 - framerate - 帧速率 - 图像可以是垂直的或者是水平的,也可以两者兼有的图像条或者雪碧图 - 动作将按照自左到右、从上到下自动循环所有帧。 --> <action name="do_crop_animation" scope="local" args="framewidth, frameheight, framerate"> <!-- 定义局部变量 --> calc(local.xframes, (caller.imagewidth /framewidth) BOR 0); calc(local.frames, xframes * ((caller.imageheight / frameheight) BOR 0)); def(local.frame, integer, 0); <!-- 设置第一帧 --> calc(caller.crop, '0|0|' + framewidth + '|' + frameheight); <!-- 动画部分 --> setinterval(calc('crop_anim_' + caller.name), calc(1.0 / framerate), if(caller.loaded, inc(frame); if(frame GE frames, if(caller.onlastframe !== null, callwith(caller, onlastframe() ) ); set(frame,0); ); mod(xpos, frame, xframes); div(ypos, frame, xframes); Math.floor(ypos); mul(xpos, framewidth); mul(ypos, frameheight); calc(caller.crop, xpos + '|' + ypos + '|' + framewidth + '|' + frameheight); , <!-- 当热点移除时停止动画 --> clearinterval(calc('crop_anim_' + caller.name)); ); ); </action> |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<action name="do_crop_animation"> <!-- 为热点注册属性 --> registerattribute(xframes, calc((imagewidth / %1) BOR 0)); registerattribute(yframes, calc((imageheight / %2) BOR 0)); registerattribute(frames, calc(xframes * yframes)); registerattribute(frame, 0); set(crop, '0|0|%1|%2'); setinterval(calc('crop_anim_' + name), calc(1.0 / %3), if(loaded, inc(frame); if(frame GE frames, if(onlastframe !== null, onlastframe() ); set(frame,0); ); mod(xpos, frame, xframes); div(ypos, frame, xframes); Math.floor(ypos); mul(xpos, %1); mul(ypos, %2); calc(crop, xpos + '|' + ypos + '|%1|%2'); , clearinterval(calc('crop_anim_' + name)); ); ); </action> |
如果你正确地调用了png序列图,那么你需要知道的就是该序列图上每一帧的宽度和高度,例如第一张爆炸动态图explosion.png,我们知道它是一张700×700的序列图,每一排每一列都是7个小图,可以计算得出每一个小图也就是每一帧是100×100像素。同时我们确定其帧速率为60fps。因为只需要在该动态的热点箭头hotspot的静态代码或layer中使用url和onloaded就可以了。也就是
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
url="explosion.png" onloaded="do_crop_animation(100,100, 60)" |
do_crop_animation()是在png图加载完开始执行,不然的话就会闪烁。
第一个参数代表的是序列图每一个小图的宽度,第二个参数是小图的高度,第三个参数是动画的帧速率,数值越大,动态速率越明显。在本案例中分别是100、100和60。
这种用法对于layer也是适用的。url是我们的序列图的路径,然后只要在layer代码的onloaded事件加上do_crop_animation。
案例中其它热点的代码也是类似的。这里有个好玩的地方,是爆炸这个动态图用了随机坐标。也就是有个onlastframe的自定义属性。
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 |
<hotspot name="spot1" url="animatedhotspot_white.png" onloaded="do_crop_animation(64,64, 60);" ath="-15" atv="-12" onclick="looktohotspot(get(name),65)" /> <hotspot name="spot2" url="animatedhotspot_black.png" onloaded="do_crop_animation(64,64, 60);" ath="+15" atv="+12" onclick="looktohotspot(get(name),65)" /> <hotspot name="spot3" url="explosion.png" onloaded="do_crop_animation(100,100, 60)" ath="calc:random*90- 45" atv="calc:random*60 - 30" zoom="true" enabled="false" onlastframe="calc(ath, random*90-45);calc(atv, random*60-30);" /> <hotspot name="spot4" url="circle.png" onloaded="do_crop_animation(102,102, 60)" ath="0" atv="0" enabled="false" /> <hotspot name="spot5" url="target.png" onloaded="do_crop_animation(128,128, 60);" ath="+15" atv="-12" onclick="looktohotspot(get(name),65)" scale="0.40" zoom="true" /> <hotspot name="spot6" url="waves.png" onloaded="do_crop_animation(128,128, 15);" ath="0" atv="-12" onclick="looktohotspot(get(name),65)" scale="0.25" zoom="true" /> <hotspot name="spot7" url="arrow.png" onloaded="do_crop_animation(64,64, 60);" ath="-15" atv="+12" onclick="looktohotspot(get(name),65)" /> |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
ath="calc:random*90- 45" atv="calc:random*60 - 30" |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
if(frame GE frames, if(onlastframe !== null, onlastframe() ); set(frame,0); ); |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
calc(ath, random*90-45);calc(atv, random*60-30); |
动态热点上添加始终显示的文字(支持VR模式)
注意,本方法仅适用于1.19 pr9之后的版本。文字显示为单行,如果需要折行,请在text中加[br]
第一步
显示所链接场景scene的title
如果文字为所链接场景的title值,在该hotpsot的静态属性中添加自定义属性linkedscene,写对应链接的scene的name。如:
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
<hotspot name="spot1" url="animatedhotspot_white.png" onloaded="do_crop_animation(64,64, 60);" ath="-15" atv="-12" onclick="loadscene(get(linkedscene))" linkedscene="scene_01"/> |
显示自定义文字
如果是自定义文字,在该hotpsot的静态属性中添加text,写对应文字。如:
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
<hotspot name="spot1" url="animatedhotspot_white.png" onloaded="do_crop_animation(64,64, 60);" ath="-15" atv="-12" onclick="loadscene(get(linkedscene))" text="自定义文字"/> |
第二步
在热点的onloaded事件中加上add_all_the_time_tooltip_for_VR()
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
onloaded="do_crop_animation(64,64, 60);add_all_the_time_tooltip_for_VR()" |
第三步
空白处加上action
如果是1.19 pr14-pr15 版本
在scene标签之外添加
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<action name="add_all_the_time_tooltip_for_VR"> txtadd(tooltipname, 'vrtooltip_', get(name)); addhotspot(get(tooltipname)); set(hotspot[get(tooltipname)], type=text, edge=get(hotspot[get(name)].edge), distorted=get(hotspot[get(name)].distorted), ath=get(hotspot[get(name)].ath), atv=get(hotspot[get(name)].atv), oy=-50, ox=0, vcenter=true, padding=10, mipmapping=true, oversampling=2, bg=true, bgcolor=0x000000, bgroundedge=5, bgalpha=0.65, bgborder=0, bgshadow='0 0 0 0x000000 0', css=calc(device.mobile ? 'text-align:center; color:#FFFFFF; font-family:MicrosoftYahei; font-weight:bold; font-size:24px;':'text-align:left; color:#FFFFFF; font-family:MicrosoftYahei; font-size:24px;'), txtshadow='0 0 0 0x000000 0'; enabled=true, ); txtadd(hotspot[get(tooltipname)].onclick,'callwith(hotspot[',get(name),'],onclick)'); if(text == '' OR text === null, copy(hotspot[get(tooltipname)].html,scene[get(linkedscene)].title), copy(hotspot[get(tooltipname)].html,text); ); if(lp_running == false, set(hotspot[get(tooltipname)].visible,true); , if(!webvr.isenabled, if(lp_running == true, set(hotspot[get(tooltipname)].visible,false); set(hotspot[get(tooltipname)].mark2,true); ); ); ); if(hotspot[get(name)].normal == false, set(hotspot[get(tooltipname)].normal,false); set(hotspot[get(tooltipname)].onloaded, if(webvr.isenabled, set(visible,false); , if(lp_running == false OR lp_running == null OR lp_running === null, set(visible,true); ); ); ); ); </action> |
在scene标签之外添加
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<action name="add_all_the_time_tooltip_for_VR"> txtadd(tooltipname, 'vrtooltip_', get(name)); addhotspot(get(tooltipname)); set(hotspot[get(tooltipname)].type,text); copy(hotspot[get(tooltipname)].edge,hotspot[get(name)].edge); copy(hotspot[get(tooltipname)].distorted,hotspot[get(name)].distorted); copy(hotspot[get(tooltipname)].ath,hotspot[get(name)].ath); copy(hotspot[get(tooltipname)].atv,hotspot[get(name)].atv); set(hotspot[get(tooltipname)].oy,-50); set(hotspot[get(tooltipname)].ox,0); set(hotspot[get(tooltipname)].vcenter,true); set(hotspot[get(tooltipname)].padding,10); set(hotspot[get(tooltipname)].mipmapping,true); set(hotspot[get(tooltipname)].oversampling,2); set(hotspot[get(tooltipname)].bg,true); set(hotspot[get(tooltipname)].bgcolor,0x000000); set(hotspot[get(tooltipname)].bgroundedge,5); set(hotspot[get(tooltipname)].bgalpha,0.65); set(hotspot[get(tooltipname)].bgborder,0); set(hotspot[get(tooltipname)].bgshadow,'0 0 0 0x000000 0'); set(hotspot[get(tooltipname)].css,'text-align:left; color:#FFFFFF; font-family:MicrosoftYahei; font-size:24px;'); if(device.mobile,set(hotspot[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-family:MicrosoftYahei; font-weight:bold; font-size:24px;'); ); set(hotspot[get(tooltipname)].txtshadow,'0 0 0 0x000000 0'); if(text == '' OR text === null, copy(hotspot[get(tooltipname)].html,scene[get(linkedscene)].title), copy(hotspot[get(tooltipname)].html,text); ); set(hotspot[get(tooltipname)].enabled,false); if(lp_running == false, set(hotspot[get(tooltipname)].visible,true); , if(!webvr.isenabled, if(lp_running == true, set(hotspot[get(tooltipname)].visible,false); set(hotspot[get(tooltipname)].mark2,true); ); ); ); if(hotspot[get(name)].normal == false, set(hotspot[get(tooltipname)].normal,false); set(hotspot[get(tooltipname)].onloaded, if(webvr.isenabled, set(visible,false); , if(lp_running == false OR lp_running == null OR lp_running === null, set(visible,true); ); ); ); ); </action> |
通过修改ox、oy的数值可以控制热点文字相对于热点图片的位置。
通过修改css可以控制文字在手机端(device.mobile)和非手机端的文字样式,
如果涉及到小行星开场,请结合移花接木(16)- krpano 1.19实现小行星开场的代码。
1.19 pr1 – pr8动态热点上添加始终显示的文字(不支持VR)
如果是1.19 pr9之前的版本,可使用该代码。
第一步 显示所链接场景scene的title
如果是链接到场景的title,在该hotpsot的静态属性中添加自定义属性linkedscene,写对应链接的scene的name。如:
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
<hotspot name="spot1" url="animatedhotspot_white.png" onloaded="do_crop_animation(64,64, 60);" ath="-15" atv="-12" onclick="loadscene(get(linkedscene))" linkedscene="scene_01"/> |
显示自定义文字
如果是自定义文字,在该hotpsot的静态属性中添加text,写对应文字。如:
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
<hotspot name="spot1" url="animatedhotspot_white.png" onloaded="do_crop_animation(64,64, 60);" ath="-15" atv="-12" onclick="loadscene(get(linkedscene))" text="自定义文字"/> |
第二步 在热点的onloaded事件中加上add_all_the_time_tooltip()
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
onloaded="do_crop_animation(64,64, 60);add_all_the_time_tooltip()" |
第三步 空白处加上action
在scene标签外添加
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<action name="add_all_the_time_tooltip"> txtadd(tooltipname, 'tooltip_', get(name)); addplugin(get(tooltipname)); txtadd(plugin[get(tooltipname)].parent, 'hotspot[', get(name), ']'); set(plugin[get(tooltipname)].url,'%SWFPATH%/plugins/textfield.swf'); set(plugin[get(tooltipname)].align,top); set(plugin[get(tooltipname)].edge,bottom); set(plugin[get(tooltipname)].x,0); set(plugin[get(tooltipname)].y,0); set(plugin[get(tooltipname)].autowidth,true); set(plugin[get(tooltipname)].autoheight,true); set(plugin[get(tooltipname)].vcenter,true); set(plugin[get(tooltipname)].background,true); set(plugin[get(tooltipname)].backgroundcolor,0x000000); set(plugin[get(tooltipname)].roundedge,5); set(plugin[get(tooltipname)].backgroundalpha,0.65); set(plugin[get(tooltipname)].padding,5); set(plugin[get(tooltipname)].border,false); set(plugin[get(tooltipname)].glow,0); set(plugin[get(tooltipname)].glowcolor,0xFFFFFF); set(plugin[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-family:MicrosoftYahei; font-size:24px;'); if(device.mobile,set(plugin[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-family:MicrosoftYahei; font-weight:bold; font-size:24px;'); ); set(plugin[get(tooltipname)].textshadow,0); set(plugin[get(tooltipname)].textshadowrange,6.0); set(plugin[get(tooltipname)].textshadowangle,90); if(text == '' OR text === null, copy(plugin[get(tooltipname)].html,scene[get(linkedscene)].title), copy(plugin[get(tooltipname)].html,text) ); set(plugin[get(tooltipname)].enabled,false); </action> |
通过修改align、edge、x、y的数值可以控制文字相对于热点图片的位置。
通过修改两个css可以控制文字在手机端(device.mobile)和非手机端的文字样式,
热点或图层在鼠标点击或鼠标悬停时进入动态模式
还有一种变化即该热点或图层不是一开始就是动态中,而是需要鼠标点击或者悬停时才进入到动态模式中,而在鼠标再次点击或移出时,热点或图层则恢复到静止状态。这样的话,我们需要有两个action,如下一个是do_crop_animation_onclick,一个是do_crop_animation_register。
在热点的onloaded事件中写do_crop_animation_register,在onclick或onover和onout中写do_crop_animation_onclick。注意不能同时用onclick或者onover。
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<action name="do_crop_animation_onclick"> if(hotspot[get(name)].animated === null OR hotspot[get(name)].animated == false, set(hotspot[get(name)].animated,true); setinterval(calc('crop_anim_' + name), calc(1.0 / %3), inc(frame); if(frame GE frames, if(onlastframe !== null, onlastframe() ); set(frame,0); ); mod(xpos, frame, xframes); div(ypos, frame, xframes); Math.floor(ypos); mul(xpos, %1); mul(ypos, %2); calc(crop, xpos + '|' + ypos + '|%1|%2'); ); , set(hotspot[get(name)].animated,false); clearinterval(calc('crop_anim_' + name)); set(crop, '0|0|%1|%2'); ); </action> <action name="do_crop_animation_register"> registerattribute(xframes, calc((imagewidth / %1) BOR 0)); registerattribute(yframes, calc((imageheight / %2) BOR 0)); registerattribute(frames, calc(xframes * yframes)); registerattribute(frame, 0); set(crop, '0|0|%1|%2'); </action> <!-- example hotspots --> <hotspot name="spot1" url="animatedhotspot_white.png" onover="do_crop_animation_onclick(64,64,60)" onout="do_crop_animation_onclick(64,64,60)" ath="-15" atv="-12" onloaded="do_crop_animation_register(64,64)" /> <hotspot name="spot1" url="animatedhotspot_white.png" onclick="do_crop_animation_onclick(64,64,60)" ath="-15" atv="-12" onloaded="do_crop_animation_register(64,64)" /> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<action name="do_crop_animation_onclick"> if(hotspot[get(name)].animated === null OR hotspot[get(name)].animated == false, set(hotspot[get(name)].animated,true); setinterval(calc('crop_anim_' + name), calc(1.0 / %3), inc(frame); if(frame GE frames, if(onlastframe !== null, onlastframe() ); add(frame,frames,-1); ); mod(xpos, frame, xframes); div(ypos, frame, xframes); Math.floor(ypos); mul(xpos, %1); mul(ypos, %2); calc(crop, xpos + '|' + ypos + '|%1|%2'); ); , set(hotspot[get(name)].animated,false); clearinterval(calc('crop_anim_' + name)); ); </action> |
1.18官方下载包路径
你电脑的路径\krpano-1.18.6\examples\xml-usage\animated-hotspots
提示:如果不明白下载包路径是什么,请查看 循序渐进(3)- krpano下载包的使用说明
1.18在线演示
1.18方法说明
- 我们用crop这个属性持续改变着需要显示的区域,从而实现动画的效果。我们直接用官方案例的这两个png图片。我们把这两个图片hotspot_ani_black_64x64x20.png以及hotspot_ani_white_64x64x20.png复制到项目文件夹。打开刚才路径中的anihotspots.xml文件,将以下代码复制到自己的tour.xml,记住放在scene标签的外面。
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!-- 定义热点风格 - 黑色热点的style 因为需要用到crop来进行动画,所以列出了png图片宽度、高度、第一帧开始位置也就是0,以及最后一帧也就是19,onloaded也就是载入后执行一个动画的action--> <style name="hotspot_ani_black" url="hotspot_ani_black_64x64x20.png" crop="0|0|64|64" framewidth="64" frameheight="64" frame="0" lastframe="19" onloaded="hotspot_animate();" /> <!-- 定义热点风格 - 白色热点 --> <style name="hotspot_ani_white" url="hotspot_ani_white_64x64x20.png" crop="0|0|64|64" framewidth="64" frameheight="64" frame="0" lastframe="19" onloaded="hotspot_animate();" /> <!-- 热点动画action,每隔0.03秒改变crop的内容,从而实现动画效果,inc是一个每次递增指定数值的方法,这里是让frame这个变量每次增加1,当到达19时,则从0又开始递增。mul是乘法运算,将高度乘以当前帧序号,得到crop中y的位置。txtadd对crop的内容进行了设定。因为每一次ypos的值都会发生变化,所以crop中所显示的内容也发生变化。最后是0.03秒后再次执行自身。 --> <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> |
- 下一个步骤在scene标签里加入hotspot代码,你可以运用tour_editor.html来获取热点的坐标,也就是ath,atv。但记住style属性一定要与上一个代码中的style的name一致,也就是hotspot_ani_black或者hotspot_ani_white,至于onclick的内容,我这里留空,你可以添加任意的action,例如打开一张图片或者进入另一个场景等等。
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 |
<hotspot name="spot1" style="hotspot_ani_black" ath="-25" atv="-10" onclick="" /> <hotspot name="spot2" style="hotspot_ani_black" ath="-15" atv="+10" onclick="" /> <hotspot name="spot3" style="hotspot_ani_white" ath="+15" atv="-10" onclick="" /> <hotspot name="spot4" style="hotspot_ani_white" ath="+25" atv="+10" onclick="" /> |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 |
crop="0|0|128|128" framewidth="128" frameheight="128" frame="0" lastframe="24" |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 |
crop="0|0|128|128" framewidth="128" frameheight="128" frame="0" lastframe="9" |
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 |
<style name="hotspot_ani_white" url="hotspot_ani_white_64x64x20.png" crop="0|0|64|64" framewidth="64" frameheight="64" frame="0" lastframe="19" onloaded="hotspot_animate();" /> |
1.18动态热点上添加始终显示的文字
在默认热点上始终显示场景的title,我们有一个教程:在默认热点上方始终显示文字
现在我们要做的是如何在动态热点上添加始终显示文字,首先我们用tour_editor添加热点,教程如下:循序渐进(8)- 加入中文信息、设置起始视角和热点
我们会看到在tour.xml的scene标签里多了热点的代码,如下:
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
<hotspot name="spot1" style="skin_hotspotstyle" ath="-153.861" atv="19.998" linkedscene="scene_2" /> |
我们如果有多个热点,可以全部添加完,然后用ctrl+H替换style的数值
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
<hotspot name="spot1" style="hotspot_ani_white" ath="-153.861" atv="19.998" linkedscene="scene_2" /> |
然后我们找到动态热点的style
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 |
<style name="hotspot_ani_white" url="hotspot_ani_white_64x64x20.png" crop="0|0|64|64" framewidth="64" frameheight="64" frame="0" lastframe="19" onloaded="hotspot_animate();" /> |
将onloaded的部分改为:
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 |
onloaded="hotspot_animate();add_all_the_time_tooltip();" |
同时,不要忘了在xml的空白位置添加对应的add_all_the_time_tooltip动作。
点击代码窗口最右侧按钮,在新窗口打开后复制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<action name="add_all_the_time_tooltip"> txtadd(tooltipname, 'tooltip_', get(name)); addplugin(get(tooltipname)); txtadd(plugin[get(tooltipname)].parent, 'hotspot[', get(name), ']'); set(plugin[get(tooltipname)].url,'%SWFPATH%/plugins/textfield.swf'); set(plugin[get(tooltipname)].align,top); set(plugin[get(tooltipname)].edge,bottom); set(plugin[get(tooltipname)].x,0); set(plugin[get(tooltipname)].y,0); set(plugin[get(tooltipname)].autowidth,true); set(plugin[get(tooltipname)].autowidth,true); set(plugin[get(tooltipname)].background,true); set(plugin[get(tooltipname)].backgroundcolor,0x000000); set(plugin[get(tooltipname)].roundedge,5); set(plugin[get(tooltipname)].backgroundalpha,0.65); set(plugin[get(tooltipname)].padding,5); set(plugin[get(tooltipname)].border,false); set(plugin[get(tooltipname)].glow,0); set(plugin[get(tooltipname)].glowcolor,0xFFFFFF); set(plugin[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-family:MicrosoftYahei; font-size:14px;'); if(device.mobile,set(plugin[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-family:MicrosoftYahei; font-weight:bold; font-size:22px;'); set(plugin[get(tooltipname)].y,0);); set(plugin[get(tooltipname)].textshadow,0); set(plugin[get(tooltipname)].textshadowrange,6.0); set(plugin[get(tooltipname)].textshadowangle,90); copy(plugin[get(tooltipname)].html,scene[get(linkedscene)].title); set(plugin[get(tooltipname)].enabled,false); </action> |
crop属性的用法
不管是1.19还是1.18的方法,都是对png图片序列进行crop数值的切换,因为我们需要了解crop。下面是一个普通的png图片。通过crop的设置,我们将图片的不同区域提取出来。
crop原意为切割,通常是这样的:
1 2 3 4 5 6 |
<plugin name="button1" url="crop-example-buttons.png" align="center" edge="center" x="-25%" crop ="10| 45|200|100" onovercrop="10|145|200|100" ondowncrop="10|245|200|100" /> |
我们如果没用crop属性的话,那就是会如上图显示的形式。当我们用了crop以后,krpano就会根据crop的数值对这个图片开始进行切割。那怎么确定切割那一块呢?首先是动刀子的起始坐标,也就是前面的两个数字,它们分别是开始切割的x和y的数值。图的原点在左上角为(0,0)。往右就是x坐标值增大,往下y坐标值增大。因此(10,45)在下面黑点处。
找到下刀的地方,接下来就是切割出一个矩形,我们只需要知道这个矩形的宽度和高度。也就是200和100。
这样我们就得到我们想要的按钮。
下面说明一下如果在photoshop中获取crop的四个数值。
- 首先在窗口菜单中打开信息窗口。
- 在信息窗口中点击+号,选择单位为像素。
- 鼠标放在蓝点中位置,看到信息窗口中X和Y分别显示为10和45。
- 使用矩形选择工具,拉出一个矩形框,看到右侧W和H分别显示200和100。
1crop="10|45|200|100"
除了crop以外,还有onovercrop以及ondowncrop两种属性,也就是实现了在鼠标悬停和按下时的crop属性设置。其值的设置是相同的。
在 “移花接木(1)- 添加动态热点或动态图层” 上有 2 条评论