vue中使用krpano创建实景场景效果

43 阅读4分钟

Krapno创建全景图


官网下载krpano程序krpano.com - Download

krapno Tools的使用

  • image-20251203133125009.png将这个文件解压到当前目录下(任意文件夹下都可以)
  • 打开krpano-1.22.4文件夹,并双击运行Krpano Tools.exe image-20251203133333906.png
  • 初次会进入这个界面image-20251203133500278.png
  • 这个界面是用来加载预览和实景三维基本设置的页面,初次进去需要点击左上角的Make VTour选项
  • 进入这个界面后不需要做任何修改,需要点击Open Images 这里的图片必须是全景图,平面图不行。image-20251203135743755.png
  • 选择素材/resource/下的jpg图片,最好是连贯的图片,这样可以使各个场景串联起来。假如我选了四个并打开image-20251203140108613.png
  • krpano加载完毕所有图片之后,此时全景图已经生成完成了,可以看到素材文件夹下多了一个vtour的文件夹,里面就是全景图,可以直接在项目中使用的。但此时的全景图是没有任何交互效果的,接下来就需要使用工具做一些简单的交互功能。回到krpano Tools,接下来需要点击Edit Tourimage-20251203140605082.png
  • 此时会跳转到VTour Editor选项,并且会自动打开刚才选择的素材生成的全景图。一般情况下第一张图是起始点,也就是最开始的地方,但是在编辑页面可以设置起始视角Set as startup view。如果默认进入的场景视角不是预期中的视角,可以将视角调整到预期视角,然后点击Set as startup view设置为起始视角。在编辑界面需要用到的功能基本上就是Add hotspotEdit hotspots添加和编辑热点(可以理解为传送门),用来进入下一个场景的门户。image-20251203141513063.png
  • 点击Add hotspot,将出现在场景中的箭头拖拽到合适的为止,然后点击箭头,会出现一个Edit Hotspot的窗口,在这里可以设置下一个场景,如果图片是按顺序导入的,就直接点击Save就好,但是如果不是,就需要去选择合适的场景,这样才能使两个场景过度的流畅些。保存完成后点击箭头(传送门),就会发现跳转到第二个场景了,如此循环往复就可以将所有场景进行串联起来。
  • 将所有的基本功能完成之后一定要点击上方的Save tour.xml按钮,这样才会将你做的操作进行保存下来,并且还会生成一份新的tour.xml文件(在素材文件夹下)。
  • image-20251203142544067.png
  • tour.xml是第一次选择素材时生成的原始文件,包括整个vtour文件夹都是,后面每次更新就会生成一个tour.xml - backup...的文件。

导入到项目中

可以将vtour作为独立页面运行在服务器上(本质上vtour是一个静态页面),也可以放在项目文件夹下。

这里以放在项目文件夹下引入演示:

  • 环境:vue3 + vite

vtour放到项目public文件夹下,当然可以给vtour改名,例如城东小学的vtour改名为cdxx

-- node_module
-- public
  -- krpano
    -- cdxx
  -- vite.svg
-- src
-- index.html
-- vite.config.js
-- package.json

如此就可以创建一个ShowVtour.vue的组件进行引入展示实景三维了

<script setup>
// 导入配置
import { ref, onMounted, onBeforeMount } from "vue";
import { loadScript } from "@/utils/tools"; //手动加载js文件工具类
// 实景三维数据配置
/* 
 导入实景三维配置
 {
    "城东小学":{
    "path":"krpano/cdxx/",
    "name":"cdxx",
    "title":"城东小学"
    }
 }
*/
import VtourData from "@/components/vtour-config";
// import.meta.env.BASE_URL 开发或生产环境服务的公共基础路径
​
// 声明变量 /////////////////////////////////////////////////////////
const publicPath = ref(import.meta.env.BASE_URL); // 使用全局变量的相对路径地址,一般情况下都是"/"
let VtourLayers = ref([]);
let currentVtour = ref({});
let krpanoId = ref();
let isShowKrpano = ref(Boolean);
​
// 事件方法 ////////////////////////////////////////////////////////
const openNewVtour = (title) => {
  // 获取当前实景三维信息
  let vtourInfo = VtourData[title];
  if (vtourInfo) {
    isShowKrpano.value = true;
    // 存在时
    currentVtour.value = vtourInfo;
    // 销毁容器
    destroyKrpano();
    // 更新容器id
    updateKrpanoId();
    updateVtour();
    console.log(vtourInfo);
  } else {
    // 不存在时
    isShowKrpano.value = false;
  }
};
​
// 销毁容器内部标签
const destroyKrpano = (id) => {
  // 获取div元素
  var div = document.getElementsByClassName("krpano");
  // 清空div内部所有内容
  div[0].innerHTML = "";
};
​
// 更新容器Id
const updateKrpanoId = () => {
  krpanoId.value = "krpano_" + new Date().getTime();
  return krpanoId.value;
};
// 更新实景三维
const updateVtour = () => {
  const id = krpanoId.value;
  loadScript(
    `${publicPath.value}${currentVtour.value.path}tour.js`,
    "embedpano"
  ).then((res) => {
    let swf = `${publicPath.value}${currentVtour.value.path}tour.swf`;
    let xml = `${publicPath.value}${currentVtour.value.path}tour.xml`;
    embedpano({
      swf: swf,
      xml: xml,
      target: id,
      html5: "prefer",
      mobilescale: 1.0,
      passQueryParameters: true,
    });
  });
};
​
onBeforeMount(() => {
  let arr = [];
  for (const key in VtourData) {
    arr.push(VtourData[key]);
  }
  VtourLayers.value = arr;
});
onMounted(() => {
  // 
  const initVtour = VtourLayers.value[0].title;
  openNewVtour(initVtour);
});
</script>
​
<template>
  <div id="wrapper">
    <div class="btn-warpper">
      <div
        v-for="vtour in VtourLayers"
        :key="vtour.name"
        class="btn"
        @click="openNewVtour(vtour.title)"
      >
        {{ vtour.title }}
      </div>
    </div>
    <div :id="krpanoId" class="krpano" v-if="isShowKrpano"></div>
  </div>
</template>
​
<style scoped>
#wrapper {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
.krpano {
  width: 100%;
  height: calc(100% - 40px);
}
.btn-warpper {
  height: 40px;
  line-height: 40px;
  display: flex;
  gap: 20px;
}
.btn {
  cursor: pointer;
}
</style>
​

补充:

// /utils/tools
export function loadScript(src, obj) {
  if (typeof window[obj] === 'function') {
    return Promise.resolve()
  }
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = src
    script.async = true
    script.addEventListener('load', () => {
      resolve()
    })
    script.addEventListener('error', (error) => {
      reject(error)
    })
    document.head.appendChild(script)
  })
}
  • vue3环境变量配置
  • image-20251203153801906.png
  • image-20251203153922955.png

如此就实现将创建的实景三维添加到项目中了


vtour其他配置

具体参考KRPano官方文档中文版文档手册

具体实现其他功能:

  • 小行星环绕开场动画
  • 延时自动播放
  • 箭头动画效果