循序渐进(14)- keep属性是krpano代码的最大陷阱

终于要谈到keep的问题了。keep是元素的属性,它是layer元素hotspot元素以及events元素的自带属性。

keep的英文意思就是保留。对应到krpano就是当载入新全景时,该layer/plugin元素是保留或移除。也就是场景之间的转换时,layer元素、hotspot元素以及events元素是否保留。那么这就涉及到什么是场景的转换,场景的概念是什么?

我们以普通的360全景作为场景,当然像普通的flat平面或者全景视频也是一种场景。简单说来,当有遇到loadscene或者loadpano的动作时,就是场景之间的切换。也就是说,并不是说从scene_A到scene_B的scene之间的切换才是场景的切换,从scene之外scene内也是一种场景的切换。

最明显的例子,就是默认的tour.xml是如何确定启动的第一个场景呢?实际上就是在所有scene元素之外的krpano元素的onstart之中,有一个startup的动作,其中有loadscene的动作。因此可认为是scene之外的代码其实跟每一个scene之内的代码并无太多区别。无非就是为了方便管理而已。

因此,我们平常实际上每个项目开始时都是先从scene之外scene内,所以一开始就有场景的切换。因此说,你写在scene外面的layer元素、hotspot元素以及event元素,你应该设置一个keep=”true”,才能够让场景切换时这些元素或事件不会移除。

打开vtourskin.xml可以看到皮肤的元素skin_control_bar以及skin_scroll_window都是含有keep=”true”的。然后这两个layer作为其它元素的父元素,各个子元素自动继承了keep=”true”。所以这些子元素在代码中是没有写keep=”true”。但实际上呢,它们的keep属性都是true。也就是说,如果它们的父元素的keep属性是false,那么这些子元素的keep属性就是false。

如果一个元素本身不属于其它元素的子元素,它的静态代码中没有对keep属性的书写。那么keep属性默认就是false。也就是如果你不写keep的话,它还是有数值的,就是false,也就是场景转换时它就没了,就被移除了。那一个没有keep=”true”或者没写keep属性的静态元素,放在scene外面或scene里面会出现什么情况呢?scene外面代码通常不写image元素,因此可认为scene外面是个空场景,我们能感受到的就是一开始就是某个有全景的实际场景,在这个从空场景切换到实际场景的过程中,位于空场景(scene代码之外)的没有keep=”true”或者没写keep属性的静态元素就会被移除。如果把这段静态代码放到某个scene里面,那么当场景切换到该scene时,我们就可以看到该静态元素,而切换到其它场景时,该元素就会被移除,当重新回到该场景时,该元素又会出现。如果在某个scene里面写了一个keep属性为true的元素,那么从第一次进入这个scene之后的所有时间里,不管在哪个场景中我们都会看到这个元素。

那对于events元素而言,具体的用法如下:

有两种类型的事件:

  • 全局krpano事件
    一个不具有name属性的<events>元素定义的事件都是全局事件。通常只有一个全局事件。当有另一个 <events>标签定义相同的事件时,之前定义的同一事件就会被覆写。注意 – 当载入另一个xml文件或其他场景时,所有全局事件将保留,它们不会发生改变,除非在新的xml文件或场景中被再次定义。 
  • 独立局部krpano事件
    一个具有name属性的<events>元素中定义的事件都是独立事件。
    它可以包含所有类型的事件,但它们不会覆写全局事件,它们是额外作出调用。
    这些被“命名”的<events>元素同样具有keep属性(默认值为false)。这意味着没有keep=”true”的<events>元素在新全景载入时将会被自动移除。提示 – 命名的事件能够在不影响其他插件或xml代码的基础下在独立的插件和代码中发生作用。

如果是动态设置的话,会怎样呢?当我们动态新建一个元素时,如果我们没有设置其keep属性,那么它就是为false,即使你设置这个元素的父元素是keep为true,那也不会从父元素继承到keep。也就是父子关系的keep属性继承只存在于静态元素中,在动态设置时是不能自动继承的。

发表评论