242 lines
5.5 KiB
Vue
242 lines
5.5 KiB
Vue
<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>
|