问题其实很简单,就是我们如何知道查看全景时,我们所看到的位置正处于某个热点附近,也就是这个热点已经很接近画面的中央。
要解决这个问题,我们就要理解热点坐标ath、atv以及观看位置view.hlookat、view.vlookat。
ath和atv是hotspot元素本身的属性,它们定义了热点元素在球形全景中的位置,ath是定义水平方向的位置,数值在-180到180之间,atv是定义垂直方向的位置,数值在-90到90之间。
当我们把球形全景按照特定的立方体展开后,我们所看到的屏幕的中央点位置就是view.hlookat、view.vlookat,它们的数值范围和刚才的热点坐标是一致的。
热点坐标如果不动态更改的话,通常是固定的。也就是ath和atv就固定了,但因为我们的全景是要旋转的,因此画面中央的view.hlookat、view.vlookat肯定是动态变化的,因此当这四个数值,也就是view.hlookat与ath相同,view.vlookat与atv相同时,热点就处于画面中央了。
因此这样就回到我们的问题,如何检查当前位置是否接近热点。krpano提供了一个相关的action。
1 |
getlooktodistance(result, toH, toV, fromH*, fromV*) |
获取球面全景中两个坐标之间的距离。
参数:
- result
将两个坐标之间的距离记录的变量 - toH
要到达的水平坐标值,可以是数值或变量名 - toV
要到达的垂直坐标值,可以是数值或变量名 - fromH (可选)
出发坐标的水平坐标值。如果没有定义,则使用view.hlookat。 - fromV (o可选
出发坐标的垂直坐标值。如果没有定义,则使用view.vlookat。
123456789101112131415161718192021222324 <events name="testshotspots" keep="true" onviewchanged="testhotspots();" /><action name="testhotspots">for(set(i,0), i LT hotspot.count, inc(i),getlooktodistance(d, hotspot[get(i)].ath, hotspot[get(i)].atv);if(d LT 7,highlight_hotspot(get(i), get(hotspot[get(i)].linkedscene));,background_hotspot(get(i), 0.5, 0.5);););</action><action name="highlight_hotspot">if(hotspot[%1].ishighlighted != true,set(hotspot[%1].ishighlighted, true);tween(hotspot[%1].scale, 2.0, 2.0, default, if(side == left, js( js_hotspot_onclick(%1, get(hotspot[%1].linkedscene) )) ); ););</action><action name="background_hotspot">set(hotspot[%1].ishighlighted, false);tween(hotspot[%1].scale, 0.5, 0.5);</action>
我们可以看到通过onviewchanged事件是一个在视域发生变化后进行的事件,因此可以用于视角变化类的动作。
在testhotspots这个action里,我们用
1 |
getlooktodistance |
来检查当前观看位置与每个热点的相对距离,如果距离少于7,则激发其它action。