演示
点击在新窗口中观看 http://krpano360.com/wp-content/uploads/krpano/vr/tour.html
说明
大家知道,krpano 1.19最重要的特性是对VR的全面支持。因为有WebVR插件的支持,当使用了默认皮肤在支持VR的设备打开时,皮肤中会出现如上图那样的cardboard图标,表示可以点击进入到VR模式。这个基本上不用做过多的设置。但问题是,到底是哪些代码控制了这个VR开关,与VR相关的代码又都是哪些?要是自己设计的皮肤,怎样引入VR功能呢?显而易见,VR模式涉及WebVR插件,是1.19专用的官方插件,通常已经在默认生成的项目的plugins文件夹中。显然剩下的代码都在skin文件夹的vtourskin中,于是,我们把多余的代码删除就剩下下面这个vtourskin里,当然,skin文件夹重要的vtourskin图片我们没有删除,因为VR按钮就在里面。删掉了的话就显示不了。
教程更新说明:查看第二页教程,方法更简单。第一页教程可了解在默认皮肤中对VR产生作用的代码。
代码
仅剩下VR功能的vtourskin.xml,为了显示VR按钮,给skin_btn_vr加上keep=”true”,因为它的父元素已经被删除。同时相对调整align,对齐在底部,以及调整x和y两个属性,使其对齐在屏幕底部中央,注意这里保留了鼠标悬停时出现光晕的效果,如果你不想要,只需要style=”skin_base|skin_glow”改为style=”skin_base”,同时为了保留热点,所以默认热点样式skin_hotspotstyle也予以保留,注意目前VR仅支持distorted为true的hotspot。
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
<krpano> <!-- include VR support --> <include url="../plugins/webvr.xml" devices="html5" /> <!-- overwrite some settings from the webvr.xml for the skin integration --> <plugin name="WebVR" keep="true" devices="html5" multireslock.desktop="true" multireslock.mobile.or.tablet="false" mobilevr_fake_support="true" onavailable="removelayer(webvr_enterbutton); skin_arrange_buttons(); webvr_onavailable();" onentervr="skin_showloading(false); webvr_onentervr(); webvr_setup();" onexitvr="webvr_onexitvr(); webvr_setup();" /> <!-- webvr button style (adjust to match default skin style) --> <style name="webvr_button_style" border="false" shadow="0.01" shadowrange="9.0" shadowcolor="0xFFFFFF" shadowalpha="0.5" /> <!-- show a 'rotate the device' info when the mobile device is in portrait mode in VR mode --> <layer name="webvr_rotate_to_landscape_request" keep="true" vr="true" devices="mobile" url="rotate_device.png" scale="0.5" align="top" edge="center" y="28%" autoalpha="true" alpha="0.0" enabled="false" /> <events name="webvr_events" keep="true" devices="html5" onresize.mobile="webvr_act_as_gyro_in_portrait_mode();" onviewchange="" /> <action name="webvr_setup"> if(webvr.isenabled, set(display.hotspotrenderer, webgl); copy(loadscene_flags_backup, skin_settings.loadscene_flags); set(skin_settings.loadscene_flags, MERGE|KEEPVIEW|KEEPMOVING|NOPREVIEW); webvr_act_as_gyro_in_portrait_mode(true); if(scene.count GT 1, set(hotspot[webvr_prev_scene].visible, true); set(hotspot[webvr_next_scene].visible, true); set(events[webvr_events].onviewchange, webvr_menu_following()); ); , set(display.hotspotrenderer, auto); if(loadscene_flags_backup !== null, copy(skin_settings.loadscene_flags, loadscene_flags_backup)); tween(layer[webvr_rotate_to_landscape_request].alpha, 0.0, 0.0); set(hotspot[webvr_prev_scene].visible, false); set(hotspot[webvr_next_scene].visible, false); set(events[webvr_events].onviewchange, null); ); </action> <action name="webvr_act_as_gyro_in_portrait_mode"> if(device.mobile AND webvr.isenabled, div(aspect, stagewidth, stageheight); if(aspect != lastaspect OR '%1' == 'true', copy(lastaspect, aspect); if(stagewidth GT stageheight, <!-- landscape mode - use stereo rendering and a direct/fast gyro sensor mode --> set(display.stereo, true); set(webvr.mobilevr_sensor_mode, 3); webvr.update(); tween(layer[webvr_rotate_to_landscape_request].alpha, 0.0, 0.0); , <!-- portrait mode - use normal rendering and a smoother/slower gyro sensor mode --> set(display.stereo, false); set(webvr.mobilevr_sensor_mode, 1); webvr.update(); tween(layer[webvr_rotate_to_landscape_request].alpha, 1.0); delayedcall(3.0, tween(layer[webvr_rotate_to_landscape_request].alpha, 0.0, 1.0); ); ); ); , set(lastaspect, 0); ); </action> <!-- VR scene switching hotspots --> <style name="webvr_menu_style" depth="800" scale="0.5" distorted="true" ath="0" atv="45" alpha="0.5" /> <hotspot name="webvr_prev_scene" keep="true" style="skin_base|webvr_menu_style" crop="0|64|64|64" ox="-64" onover="tween(scale,0.6);" onout="tween(scale,0.5);" vr_timeout="750" onclick="skin_nextscene_loop(-1);" visible="false" devices="html5.and.webgl" /> <hotspot name="webvr_next_scene" keep="true" style="skin_base|webvr_menu_style" crop="64|64|64|64" ox="+64" onover="tween(scale,0.6);" onout="tween(scale,0.5);" vr_timeout="750" onclick="skin_nextscene_loop(+1);" visible="false" devices="html5.and.webgl" /> <!-- floating/following VR hotspots --> <action name="webvr_menu_following" type="Javascript" devices="html5"><![CDATA[ var hs1 = krpano.get("hotspot[webvr_prev_scene]"); var hs2 = krpano.get("hotspot[webvr_next_scene]"); if(!hs1.hovering && !hs2.hovering) { var f = 0.01; // follow speed factor var h = krpano.view.hlookat; var v = krpano.view.vlookat; var hsh = hs1.ath; var hsv = hs1.atv; h = (h -(h|0)) + (((h|0) +360180)%360) - 180.0; v = (v -(v|0)) + (((v|0) +360180)%360) - 180.0; hsh = (hsh-(hsh|0)) + (((hsh|0)+360180)%360) - 180.0; var dh = h - hsh; dh += (dh > 180) ? -360 : (dh < -180) ? 360 : 0 hsh += dh*f; var a = Math.abs(v - hsv) / 90.0; a = 1.0 * Math.max(1.0 - 2.0*Math.sqrt(a), 0); v = v + 55.0 - v*1.5; hsv = hsv*(1.0 - f) + v*f; hs1.ath = hs2.ath = hsh; hs1.atv = hs2.atv = hsv; hs1.alpha = hs2.alpha = a; } ]]></action> <!-- VR support --> <!-- skin styles --> <!-- skin_base - the base skin image --> <style name="skin_base" url="vtourskin.png" /> <!-- skin_glow - button glowing (if additional ondown,onup,onout,over events are needed, this style provides ondown2,onup2,onover2,onout2 events) --> <style name="skin_glow" ondown="copy(skin_lockglow,name); skin_buttonglow(get(name)); if(ondown2, ondown2() );" onover="if(skin_lockglow === null, copy(skin_lockglow,name); skin_buttonglow(get(name),0.3) ); if(onover2, onover2() );" onout="if(skin_lockglow === name AND !pressed, skin_buttonglow(null);delete(skin_lockglow); ); if(onout2, onout2() );" onup="if(onup2, onup2()); delayedcall(0, if(hovering AND enabled, skin_buttonglow(get(name),0.3); , skin_buttonglow(null);delete(skin_lockglow); ); );" /> <!-- skin_hotspotstyle - style for the hotspots --> <style name="skin_hotspotstyle" url="vtourskin_hotspot.png" scale="0.5" edge="top" distorted="true" tooltip="" onclick="if(linkedscene, set(enabled,false); skin_hidetooltips(); tween(depth|alpha|oy|rx, 4000|0.0|-50|-60, 0.5, default, loadscene(get(linkedscene),null,get(skin_settings.loadscene_flags),get(skin_settings.loadscene_blend)); skin_updatescroll(); ); );" onover="tween(scale,0.55);" onout="tween(scale,0.5);" onloaded="if(linkedscene AND skin_settings.tooltips_hotspots, copy(tooltip,scene[get(linkedscene)].title); loadstyle(skin_tooltips); );" /> <layer name="skin_btn_vr" style="skin_base|skin_glow" crop="0|0|80|64" keep="true" align="bottom" x="0" y="50" scale="0.5" onclick="webvr.enterVR();" visible="false" /> <layer name="skin_buttonglow" keep="true" style="skin_base" crop="64|384|64|64" align="center" x="0" y="1" scale="1.0" alpha="0.0" visible="false" enabled="false" /> <!-- gyro plugin --> <plugin name="skin_gyro" keep="true" url="" html5_url="%SWFPATH%/plugins/gyro2.js" devices="html5" enabled="false" onavailable="skin_arrange_buttons();" /> <action name="skin_arrange_buttons"> calc(show_vrbutton, webvr.isavailable == true); copy(layer[skin_btn_vr].visible, show_vrbutton); </action> <action name="skin_nextscene"> add(newsceneindex, scene[get(xml.scene)].index, %1); if(newsceneindex GE 0 AND newsceneindex LT scene.count, txtadd(layer[skin_thumbborder].parent, 'skin_thumb_', get(newsceneindex)); layer[skin_thumbs].scrolltocenter(get(scene[get(newsceneindex)].thumbx), get(scene[get(newsceneindex)].thumby)); loadscene(get(scene[get(newsceneindex)].name),null,get(skin_settings.loadscene_flags),calc(%1 LT 0 ? skin_settings.loadscene_blend_prev : skin_settings.loadscene_blend_next)); ); </action> <action name="skin_nextscene_loop"> add(newsceneindex, scene[get(xml.scene)].index, %1); sub(lastsceneindex, scene.count, 1); if(newsceneindex LT 0, copy(newsceneindex,lastsceneindex)); if(newsceneindex GT lastsceneindex, set(newsceneindex,0)); layer[skin_thumbs].scrolltocenter(get(scene[get(newsceneindex)].thumbx), get(scene[get(newsceneindex)].thumby)); loadscene(get(scene[get(newsceneindex)].name),null,get(skin_settings.loadscene_flags),calc(%1 LT 0 ? skin_settings.loadscene_blend_prev : skin_settings.loadscene_blend_next)); </action> <action name="skin_buttonglow"> if('%1' !== 'null', set(strength,0.7); if(%2 != null, set(strength,%2)); set(layer[skin_buttonglow].parent, %1); set(layer[skin_buttonglow].visible, true); tween(layer[skin_buttonglow].alpha, get(strength), 0.07); , tween(layer[skin_buttonglow].alpha, 0.0, 0.1, default, set(layer[skin_buttonglow].parent, null); set(layer[skin_buttonglow].visible, false); ); ); </action> </krpano> |
如果你还是include了vtourskin.xml,同时又没有删掉对应的图片的话,你只需要调整的就是
1 |
<layer name="skin_btn_vr" style="skin_base|skin_glow" crop="0|0|80|64" keep="true" align="bottom" x="0" y="50" scale="0.5" onclick="webvr.enterVR();" visible="false" /> |
name不用改,style应保留skin_base,crop也不用改,keep的话依据你的皮肤而定,如果你的父元素已经有了keep为true,那就不用另外再加,onclick和visible都保持不变,至于对齐相关的align、edge、x、y以及尺寸相关的scale等,你自己可以完全把控。强制显示的话,注意修改visible属性。
1 |
copy(layer[skin_btn_vr].visible, show_vrbutton); |
案例下载
链接:http://pan.baidu.com/s/1dDv4br7 密码:wptt
更简单的方式
1.保留默认皮肤,也就是保留tour.xml中的
1 |
<include url="skin/vtourskin.xml"/> |
在tour.xml的skin_settings中把thumbs设置false,这样就不会生成缩略图,减少加载的时间。
2.找到默认皮肤vtourskin.xml,对默认皮肤的可视化界面进行隐藏,将
1 |
set(layer[skin_layer].visible, true); |
改为
1 |
set(layer[skin_layer].visible, false); |
然后在空白处插入以下代码:
1 2 3 |
<action name="hide_vtourskin_all" autorun="onstart"> delayedcall(0.5,skin_hideskin(instant);set(layer[skin_layer].visible,false);); </action> |
这时候在全景两侧还有两个箭头。我们可以将skin_btn_prev_fs以及skin_btn_next_fs的visible属性设置为false,进行隐藏。找到
1 2 3 4 5 6 7 |
<!-- previous/next scene buttons for the hidden skin mode --> <layer name="skin_btn_prev_fs" keep="true" type="container" align="lefttop" x="-50" width="40" height="100%" bgcapture="true" alpha="0.25" capture="false" zorder="2" onclick="skin_nextscene_loop(-1);" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();"> <layer name="skin_btn_prev_fs_icon" style="skin_base" crop="0|64|64|64" align="center" scale="0.5" enabled="false" /> </layer> <layer name="skin_btn_next_fs" keep="true" type="container" align="righttop" x="-50" width="40" height="100%" bgcapture="true" alpha="0.25" capture="false" zorder="2" onclick="skin_nextscene_loop(+1);" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();"> <layer name="skin_btn_next_fs_icon" style="skin_base" crop="64|64|64|64" align="center" scale="0.5" enabled="false" /> </layer> |
改为
1 2 3 4 5 6 7 |
<!-- previous/next scene buttons for the hidden skin mode --> <layer name="skin_btn_prev_fs" keep="true" type="container" visible="false" align="lefttop" x="-50" width="40" height="100%" bgcapture="true" alpha="0.25" capture="false" zorder="2" onclick="skin_nextscene_loop(-1);" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();"> <layer name="skin_btn_prev_fs_icon" style="skin_base" crop="0|64|64|64" align="center" scale="0.5" enabled="false" /> </layer> <layer name="skin_btn_next_fs" keep="true" type="container" visible="false" align="righttop" x="-50" width="40" height="100%" bgcapture="true" alpha="0.25" capture="false" zorder="2" onclick="skin_nextscene_loop(+1);" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();"> <layer name="skin_btn_next_fs_icon" style="skin_base" crop="64|64|64|64" align="center" scale="0.5" enabled="false" /> </layer> |
另外找到
1 2 3 |
if(scene.count GT 1, set(layer[skin_btn_prev_fs].visible, true); set(layer[skin_btn_next_fs].visible, true); |
改为
1 2 3 |
if(scene.count GT 1, set(layer[skin_btn_prev_fs].visible, false); set(layer[skin_btn_next_fs].visible, false); |
3.自定义VR按钮,即onclick=”webvr.enterVR();”
1 |
<layer name="vrbutton" width="64" keep="true" height="prop" x="8" zorder="2" y="70" url="img/vrbutton.png" align="righttop" visible="false" onclick="webvr.enterVR();"/> |
4.其它默认皮肤的代码可能会对自定义皮肤产生的影响
1 |
<krpano stagescale="calc:stagescale * 2" if="stagescale LT 1.0" devices="mobile" /> |
这一行会使得皮肤比较大,可以注释掉。