Prechádzať zdrojové kódy

threejs点击测试

guarantee-lsq 1 rok pred
rodič
commit
7cc4783c31

+ 10 - 0
src/api/store/instoredetail.js

@@ -125,3 +125,13 @@ export function exportInStoreDetail (parameter) {
     responseType: 'blob'
   })
 }
+
+export function getThreeTest (parameter) {
+  return axios({
+    url: '/store/in-store-details/three/' + parameter.id,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}

+ 65 - 1
src/views/threejs/factory/FactoryOne.vue

@@ -13,6 +13,8 @@
 import * as THREE from 'three'
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
 import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
+import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js'
+import { getThreeTest } from '@/api/store/instoredetail'
 export default {
   name: 'FactoryOne',
   components: {
@@ -24,7 +26,12 @@ export default {
       camera: null,
       scene: null,
       renderer: null,
-      controls: null
+      controls: null,
+      css2DRenderer: null,
+      canvasWidth: 1000,
+      canvasHeight: 800,
+      group: null,
+      objName: null
     }
   },
   mounted () {
@@ -39,7 +46,15 @@ export default {
       this.createCamera() // 创建相机
       this.createRender() // 创建渲染器
       this.createControls() // 创建控件对象
+      this.css2DRenderer = new CSS2DRenderer()
+      this.css2DRenderer.setSize(this.canvasWidth, this.canvasHeight)
+      this.css2DRenderer.render(this.scene, this.camera)
+      this.css2DRenderer.domElement.style.position = 'absolute'
+      this.css2DRenderer.domElement.style.top = 0
+      this.css2DRenderer.domElement.style.pointerEvents = 'none'
+      window.document.getElementById('container').appendChild(this.css2DRenderer.domElement)
       this.render() // 渲染
+      this.rayCasterFn()
     },
     // 创建场景
     createScene () {
@@ -51,6 +66,7 @@ export default {
       loader.load('/models/gltf/厂区1.gltf', model => {
         // model.scene.children[0].scale.set(50, 50, 50)
         console.log('model', model)
+        this.group = model.scene
         this.scene.add(model.scene)
       })
     },
@@ -102,11 +118,59 @@ export default {
         this.mesh.rotation.z += 0.006
       } */
       this.renderer.render(this.scene, this.camera)
+      this.css2DRenderer.render(this.scene, this.camera)
       requestAnimationFrame(this.render)
     },
     // 创建控件对象
     createControls () {
       this.controls = new OrbitControls(this.camera, this.renderer.domElement)
+    },
+    rayCasterFn () {
+      // 画布添加事件监听
+      document.getElementById('container').addEventListener('click', e => {
+        this.scene.traverse(one => {
+          if (one.isCSS2DObject) {
+            this.scene.remove(one)
+          }
+        })
+        // 坐标转换
+        const pX = e.offsetX
+        const pY = e.offsetY
+        const x = (pX / window.innerWidth) * 2 - 1
+        const y = -(pY / window.innerHeight) * 2 + 1
+        // 创建射线拾取器对象
+        const raycaster = new THREE.Raycaster()
+        // 射线计算
+        raycaster.setFromCamera(new THREE.Vector2(x, y), this.camera)
+        // 射线交叉计算
+        console.log('this.group.children', this.group.children)
+        const intersects = raycaster.intersectObjects(this.group.children)
+        if (intersects.length > 0) {
+          const obj = intersects[0].object
+          console.log('obj', obj)
+          const that = this
+          getThreeTest({ id: obj.name }).then(res => {
+            that.objName = res.data
+          })
+          const dom = this.createDiv(this.objName)
+          const css2Obj = new CSS2DObject(dom)
+          const wp = new THREE.Vector3()
+          obj.getWorldPosition(wp)
+          css2Obj.position.set(wp.x, wp.y, wp.z)
+          this.scene.add(css2Obj)
+          this.render()
+        }
+      })
+    },
+    createDiv (name) {
+      const dom = document.createElement('div')
+      dom.style.padding = '5px 10px'
+      dom.style.border = '1px solid skyblue'
+      dom.style.color = 'red'
+      dom.style.background = '#2FF885'
+      dom.style.borderRadius = '15px'
+      dom.innerHTML = name
+      return dom
     }
   }
 }