|
|
@@ -9,6 +9,12 @@
|
|
|
:percentage="percentage"
|
|
|
:fill-border-radius="0"
|
|
|
/>
|
|
|
+ <RightClick
|
|
|
+ v-model="rightClickD.show"
|
|
|
+ :x="rightClickD.x"
|
|
|
+ :y="rightClickD.y"
|
|
|
+ :intersection="rightClickD.intersection"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -21,12 +27,20 @@
|
|
|
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
|
|
|
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
|
|
|
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'
|
|
|
- import { onMounted, onUnmounted } from 'vue'
|
|
|
+ import { onMounted, onUnmounted, provide, ref } from 'vue'
|
|
|
import { useOutsideHomeStore } from '@/stores/modules/home'
|
|
|
import { useOutsideSystemStore } from '@/stores/modules/system'
|
|
|
+ import { getCorrectMousePosition } from '@/utils'
|
|
|
import storage from '@/utils/storage'
|
|
|
+ import RightClick from './components/rightClick.vue'
|
|
|
|
|
|
const emits = defineEmits(['onGetData'])
|
|
|
+ const rightClickD = reactive({
|
|
|
+ show: false,
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ intersection: null
|
|
|
+ })
|
|
|
|
|
|
const { API_MR_CAMERA_GET, API_MR_VIDEO_LIST_GET } = useRequest()
|
|
|
const useHomeStore = useOutsideHomeStore()
|
|
|
@@ -79,15 +93,18 @@
|
|
|
}
|
|
|
sprite.position.set(x, y, z)
|
|
|
sprite.scale.set(0.4, 0.45, 0.5)
|
|
|
+ // 设置精灵的锚点为底部中央
|
|
|
+ sprite.center.set(0.5, 0)
|
|
|
scene.add(sprite)
|
|
|
sprites.push(sprite)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- const addEvent = (dom = window) => {
|
|
|
- const raycaster = new THREE.Raycaster()
|
|
|
- const pointer = new THREE.Vector2()
|
|
|
+ provide('addSprite', addSprite)
|
|
|
|
|
|
+ const raycaster = new THREE.Raycaster()
|
|
|
+ const pointer = new THREE.Vector2()
|
|
|
+ const addEvent = (dom = window) => {
|
|
|
dom.addEventListener('click', (event) => {
|
|
|
if (useHomeStore.temp === 'video') return
|
|
|
pointer.x = (event.clientX / window.innerWidth) * 2 - 1
|
|
|
@@ -108,7 +125,46 @@
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
+
|
|
|
+ dom.addEventListener('contextmenu', onRightClick)
|
|
|
+ }
|
|
|
+ function onRightClick(event) {
|
|
|
+ event.preventDefault()
|
|
|
+
|
|
|
+ // 隐藏之前的菜单
|
|
|
+ // document.getElementById('context-menu').style.display = 'none'
|
|
|
+
|
|
|
+ // 计算鼠标位置
|
|
|
+ pointer.x = (event.clientX / window.innerWidth) * 2 - 1
|
|
|
+ pointer.y = -(event.clientY / window.innerHeight) * 2 + 1
|
|
|
+
|
|
|
+ // 更新射线投射
|
|
|
+ raycaster.setFromCamera(pointer, camera)
|
|
|
+
|
|
|
+ // 检测与模型的交点
|
|
|
+ const intersects = raycaster.intersectObjects(scene.children, true)
|
|
|
+
|
|
|
+ if (intersects.length > 0) {
|
|
|
+ if (intersects[0].object.type === 'Sprite') return
|
|
|
+ // 显示右键菜单
|
|
|
+ const scale = document.body.style.transform.split('(')[2].split(')')[0]
|
|
|
+
|
|
|
+ rightClickD.show = true
|
|
|
+ rightClickD.x = event.clientX / scale
|
|
|
+ rightClickD.y = event.clientY / scale
|
|
|
+
|
|
|
+ // 存储交点信息
|
|
|
+ rightClickD.intersection = intersects[0].point
|
|
|
+ } else {
|
|
|
+ // 如果没有点击到物体,隐藏菜单
|
|
|
+ rightClickD.show = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const destroyedMenu = () => {
|
|
|
+ rightClickD.show = false
|
|
|
}
|
|
|
+ document.addEventListener('click', destroyedMenu)
|
|
|
|
|
|
// 创建场景
|
|
|
const scene = new THREE.Scene()
|
|
|
@@ -253,6 +309,7 @@
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
window.removeEventListener('resize', resize)
|
|
|
+ document.removeEventListener('click', destroyedMenu)
|
|
|
cleanupThreeJS()
|
|
|
})
|
|
|
</script>
|