This commit is contained in:
2025-12-26 16:45:58 +08:00
commit 1a20560753
190 changed files with 37841 additions and 0 deletions

241
src/components/Pano.vue Normal file
View File

@ -0,0 +1,241 @@
<template>
<div class="app-pano">
<div id="web-pano"></div>
</div>
</template>
<script setup lang="ts">
import { userCarStore, userSellingPointStore } from '@/stores/zguiy'
import { storeToRefs } from 'pinia'
import { ref, onMounted, onUnmounted, defineExpose, watch } from 'vue'
const krpano = ref<any>(null)
const isLoaded = ref(false)
const scriptId = 'panoscript'
const baseUrl = `${import.meta.env.VITE_PUBLIC_URL}`
const hotspotImage = `${import.meta.env.VITE_PUBLIC_URL}`
const sllingPointStore = userSellingPointStore()
const carStore = userCarStore();
const { isInterior } = storeToRefs(carStore);
const scale = ref(0.1)
const hotspots = ref<any>([ {
name: 'spot0',
image: `${baseUrl}resources/btn_热点.png`,
ath: 35.465,
atv: 17.311,
style: 'skin_hotspotstyle',
title: '悬浮大屏',
scale:scale.value,
content: '10.1寸悬浮大屏,显示清晰,触感灵敏,操作流畅,科技感拉满。标配电动空调,响应迅速,冷暖随心。'
},
{
name: 'spot1',
image: `${baseUrl}resources/btn_热点.png`,
ath: 19.434,
atv: 29.863,
style: 'skin_hotspotstyle',
title: '换挡模块',
scale:scale.value,
content: '业内首款怀挡设计纯电小卡,极大节省空间,更便捷的换挡操作,提高了驾驶的舒适性,更安全的驾驶行车'
},
{
name: 'spot1',
image: `${baseUrl}resources/btn_热点.png`,
ath: 55.045,
atv: 20.812,
style: 'skin_hotspotstyle',
title: '储物空间',
scale:scale.value,
content: '副驾、副仪表板储物空间,可满足不同情形下的储物需求。方便拿取物品'
},
{
name: 'spot1683588860',
image: `${baseUrl}resources/btn_热点.png`,
ath: -29.437,
atv: 31.364,
style: 'skin_hotspotstyle',
title: '方向盘模块',
scale:scale.value,
content: '多功能方向盘+定速巡航,满足客户长途驾车需求。'
},
{
name: 'spot1683589018',
image: `${baseUrl}resources/btn_热点.png`,
ath: -0.279,
atv: 22.188,
style: 'skin_hotspotstyle',
title: '液晶仪表模块',
scale:scale.value,
content: '全系标配4.3寸液晶仪表。信息丰富,助力安全驾驶。'
},
{
name: 'spot1683589206',
image: `${baseUrl}resources/btn_热点.png`,
ath: 89.822,
atv: 37.924,
style: 'skin_hotspotstyle',
title: '座椅模块',
scale:scale.value,
content: '手刹放平设计,满足驾驶员平躺休息的需求。'
},
])
//是否进入内室 暂停3D渲染
watch(isInterior, (newVal) => {
if(newVal){
rotateAndZoom()
}
else{
//直接设置视角为初始
if (krpano.value) {
krpano.value.set("view.hlookat", -90.203);
krpano.value.set("view.vlookat", 30.058);
krpano.value.set("view.fov", 120.000);
}
}
})
const createKrpano = () => {
if (isLoaded.value) return
// 避免重复添加脚本
if (document.getElementById(scriptId)) {
embedViewer()
return
}
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = `${baseUrl}pano/tour.js`
script.id = scriptId
script.onload = embedViewer
document.head.appendChild(script)
}
const embedViewer = () => {
embedpano({
swf: `${baseUrl}pano/tour.swf`,
xml: `${baseUrl}pano/tour.xml`,
target: 'web-pano',
html5: 'auto',
mobilescale: 1.0,
passQueryParameters: true,
onready: krpanoOnReady
})
}
const hotspotClickHandler = (name: string) => {
console.log(name);
}
// 新增:旋转和推进视角的函数
const rotateAndZoom = () => {
if (!krpano.value) return;
// 获取当前视角
const currentHlookat = krpano.value.get("view.hlookat");
const currentFov = krpano.value.get("view.fov");
// 旋转90度
krpano.value.call(`tween(view.hlookat, ${currentHlookat + 90}, 1.5, easeInOutQuad)`);
}
const krpanoOnReady = (interfaceInstance: any) => {
krpano.value = interfaceInstance
isLoaded.value = true
setTimeout(() => {
initHotspot()
}, 2000);
}
const initHotspot = () => {
addHotspots(hotspots.value)
}
// 添加热点函数
const addHotspots = (hotspots: Array<{
name: string,
image: string,
ath: number,
atv: number,
style?: string,
title?: string,
content?: string
}>) => {
if (!krpano.value || !isLoaded.value) return
for(let i=0;i<hotspots.length;i++){
let hs = krpano.value.addhotspot();
const hotspot=hotspots[i]
hs.url = hotspot.image;
hs.ath = hotspot.ath;
hs.atv = hotspot.atv;
hs.style = hotspot.style;
hs.alpha = 0;
hs.scale=scale.value
hs.onloaded = ()=> { krpano.value.tween(hs, { scale: 0.2, alpha: 1 }); };
hs.onclick = (hs) => {
showFeatureInfo(hotspot)
};
}
}
const showFeatureInfo = (hotspot: any) => {
console.log(hotspot);
// if (sllingPointStore.isOpen) return;
sllingPointStore.setTitle(hotspot.title)
sllingPointStore.setContent(hotspot.content)
sllingPointStore.setIsOpen(true)
}
onMounted(() => {
console.log(1111);
createKrpano();
})
onUnmounted(() => {
// 清理 krpano 脚本和实例(可选)
const script = document.getElementById(scriptId)
if (script) {
script.remove()
}
isLoaded.value = false
krpano.value = null
})
defineExpose({
})
</script>
<style scoped>
.app-pano {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
#web-pano {
width: 100%;
height: 100%;
outline: none;
}
</style>