欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue使用threeJs導(dǎo)入obj模型并實(shí)現(xiàn)添加標(biāo)注

 更新時(shí)間:2024年05月23日 11:09:02   作者:看點(diǎn)博客  
這篇文章主要介紹了vue使用threeJs導(dǎo)入obj模型并實(shí)現(xiàn)添加標(biāo)注方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

效果圖

1.安裝threeJs

npm install three

2.安裝軌道控件插件

npm install three-orbit-controls

3.安裝加載.obj和.mtl文件的插件

npm i --save three-obj-mtl-loader

頁(yè)面引用:

import * as THREE from "three";  //引入three.js  
import { MTLLoader } from "three-obj-mtl-loader";   //引入加載外部模型
import { OBJLoader } from "../../public/objJs/OBJLoader.js";   //引入加載外部模型
// const OrbitControls = require("three-orbit-controls")(THREE);  //引入控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer';

在外部創(chuàng)建變量:

   場(chǎng)景    模型    相機(jī)   渲染      控制器     標(biāo)簽
let scene, scale, camera, renderer, controls, labelRenderer;

data中:

data () {
    return {
      mesh: null,
      events: {
        raycaster: new THREE.Raycaster(),
        pickedObject: null,
        pickedObjectSavedColor: 0,
        pickPosition: new THREE.Vector2(),//創(chuàng)建二維平面
      },
    }
  },

導(dǎo)入模型,在場(chǎng)景中加載

loadMTL () {
      let that = this;
      let mtlLoader = new MTLLoader();
      let objloader = new OBJLoader();
      mtlLoader.load('/file.mtl', function (materials) {
        materials.preload();
        objloader.setMaterials(materials);
        objloader.load('/file.obj', function (obj) {
          obj.position.set(0, -5, 0);//模型擺放的位置
          obj.scale.set(0.002, 0.002, 0.002);//模型放大或縮小,有的時(shí)候看不到模型,考慮是不是模型太小或太大。
          scene.add(obj);//將模型加入場(chǎng)景中
          function (xhr) {
            // console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
          },
          // called when loading has errors
          function (error) {
            console.log(error)
            console.log("An error happened");
          });
      });
    },

創(chuàng)建場(chǎng)景

initScene () {
      scene = new THREE.Scene();
      // var axesHelper = new THREE.AxesHelper(250); // 建立xyz坐標(biāo)軸,紅色代表 X 軸. 綠色代表 Y 軸. 藍(lán)色代表 Z 軸.長(zhǎng)度15

      // scene.add(axesHelper);

      // 改變外殼顏色
      var AmbientLight = new THREE.AmbientLight(0xAF8E00); // 環(huán)境光

      scene.add(AmbientLight);

      let DirectionalLight = new THREE.DirectionalLight(0xdfebff, 0.45); // 平行光

      scene.add(DirectionalLight);

    },

初始化相機(jī)

initCamera () {

      camera = new THREE.PerspectiveCamera(

        75,

        window.innerWidth / window.innerHeight,

        0.1,

        1000

      );

      camera.position.set(20, 20, 20); // 調(diào)整相機(jī)方位

      camera.lookAt(new THREE.Vector3(0, 0, 0)); // 讓相機(jī)指向原點(diǎn)
      const pointLight = new THREE.PointLight(0xffffff, 1, 100);
      pointLight.position.set(0, 0, 20100);
      scene.add(pointLight);
      scene.add(camera);
    },

初始化加載器

initRenderer () {
      renderer = new THREE.WebGLRenderer();
      let container = document.getElementById("container");
      let width = document.getElementById('container').clientWidth;
      let height = document.getElementById('container').clientHeight;
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setClearColor(0x8B8B8B, 1.0); // 背景光
      container.appendChild(renderer.domElement);
      renderer.setPixelRatio(window.devicePixelRatio);
      // 初始化標(biāo)簽
      labelRenderer = new CSS2DRenderer();
      labelRenderer.setSize(window.innerWidth, window.innerHeight);
      labelRenderer.domElement.style.position = "absolute";
      labelRenderer.domElement.style.top = 0;
      labelRenderer.domElement.style.pointerEvents = 'none';
      labelRenderer.domElement.className = "allLabel"
      container.appendChild(labelRenderer.domElement);

    },
// 鼠標(biāo)點(diǎn)擊創(chuàng)建標(biāo)簽
    clickEvents () {
      window.addEventListener('click', this.clickPickPosition);
    },
     // 當(dāng)前鼠標(biāo)點(diǎn)擊坐標(biāo)
    clickPickPosition (e) {
      this.events.pickPosition.x = e.clientX / renderer.domElement.clientWidth * 2 - 1;
      this.events.pickPosition.y = -(e.clientY / renderer.domElement.clientHeight * 2) + 1;
      this.pickEvents(this.events.pickPosition, scene, camera, obj => {
        obj.userData.checked = !obj.userData.checked;
        if (!obj.userData.checked) {
          obj.material.emissive.setHex(this.events.pickedObjectSavedColor)
        } else {
          obj.material.emissive.setHex(0xFFFF00)
        }
      })
    },
    // 創(chuàng)建點(diǎn)擊事件(默認(rèn)是離攝像頭最近的相交)
    pickEvents (normalizedPosition, scene, camera, callback) {
      // 如果存在拾取的對(duì)象,則恢復(fù)顏色
      if (this.events.pickedObject) {
        this.events.pickedObject.material.emissive.setHex(this.events.pickedObjectSavedColor);
        this.events.pickedObject = undefined;
      }
      // 沿著攝像頭的方向投射射線
      this.events.raycaster.setFromCamera(normalizedPosition, camera)
      // 獲取與射線光線相交的對(duì)象列表
      const intersectedObjects = this.events.raycaster.intersectObjects(scene.children);
      if (intersectedObjects.length) {

        // // 獲取與射線光纖相交的第一個(gè)對(duì)象。也是最近的一個(gè)
        this.events.pickedObject = intersectedObjects[0].object;
        // // 保存當(dāng)前對(duì)象的顏色
        this.events.pickedObjectSavedColor = this.events.pickedObject.material.emissive.getHex();
        // // 將其發(fā)射顏色設(shè)置為閃爍的紅色/黃色
        this.events.pickedObject.material.emissive.setHex(0xFFFF00)
        // 點(diǎn)擊設(shè)置標(biāo)簽
        // intersectedObjects[0].point.y *= 1.08;
        // intersectedObjects[0].point.x *= -1.08;
        console.log(intersectedObjects[0].point)
        let pointLabelDom = this.createLableObj(intersectedObjects[0].object.name, intersectedObjects[0].point)
        scene.add(pointLabelDom);//將模型加入場(chǎng)景中
        if (callback) {
          callback(this.events.pickedObject)
        }
      }
    },
    //創(chuàng)建標(biāo)簽方法
    createLableObj (text, vector) {
      let laberDiv = document.createElement('div');//創(chuàng)建div容器
        laberDiv.className = 'laber_name';
        // laberDiv.textContent = text;
        laberDiv.innerHTML = `
            <div class='label_count'>
                ${text}
            </div>
        `
      // 給標(biāo)簽設(shè)置坐標(biāo)位置
      let pointLabel = new CSS2DObject(laberDiv);
      	pointLabel.position.set(vector.x, vector.y, vector.z);
      return pointLabel;
    }

集成在init中調(diào)用

init () {
      this.initScene();
      this.initCamera();
      this.initRenderer();
      this.initOrbitControls()
      //調(diào)用點(diǎn)擊事件
      this.clickEvents()
    },

刷新動(dòng)畫

animate () {
  // requestAnimationFrame 應(yīng)運(yùn)而生,它采用的是系統(tǒng)時(shí)間間隔(約16.7ms),保持最佳繪制效果與效率,
  // 使各種網(wǎng)頁(yè)動(dòng)畫有一個(gè)統(tǒng)一的刷新機(jī)制,從而節(jié)省系統(tǒng)資源,提高系統(tǒng)性能。
  requestAnimationFrame(this.animate);
  // controls.update();
  renderer.render(scene, camera);
  labelRenderer.render(scene, camera)
},

在mounted中調(diào)用,

mounted () {
    this.$nextTick(() => {
      this.init();
      this.loadMTL()
      this.animate();
      }
   }

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue兩組件間值傳遞 $router.push實(shí)現(xiàn)方法

    vue兩組件間值傳遞 $router.push實(shí)現(xiàn)方法

    兩組件間傳值,可能包含多種情況,這篇文章主要介紹了vue兩組件間值傳遞 $router.push實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2019-05-05
  • Vue——解決報(bào)錯(cuò) Computed property

    Vue——解決報(bào)錯(cuò) Computed property "****" was assigned to but it ha

    這篇文章主要介紹了Vue——解決報(bào)錯(cuò) Computed property "****" was assigned to but it has no setter.的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-12-12
  • vue、react等單頁(yè)面項(xiàng)目部署到服務(wù)器的方法及vue和react的區(qū)別

    vue、react等單頁(yè)面項(xiàng)目部署到服務(wù)器的方法及vue和react的區(qū)別

    這篇文章主要介紹了vue、react等單頁(yè)面項(xiàng)目部署到服務(wù)器的方法,需要的朋友可以參考下
    2018-09-09
  • vue實(shí)現(xiàn)導(dǎo)出excel的多種方式總結(jié)

    vue實(shí)現(xiàn)導(dǎo)出excel的多種方式總結(jié)

    在Vue中實(shí)現(xiàn)導(dǎo)出Excel有多種方式,可以通過前端實(shí)現(xiàn),也可以通過前后端配合實(shí)現(xiàn),這篇文章將為大家詳細(xì)介紹幾種常用的實(shí)現(xiàn)方式,需要的可以參考下
    2023-08-08
  • vue中解決微信html5原生ios虛擬鍵返回不刷新問題

    vue中解決微信html5原生ios虛擬鍵返回不刷新問題

    這篇文章主要介紹了vue中解決微信html5原生ios虛擬鍵返回不刷新問題,本文給大家分享解決方法,通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • vue篇之事件總線EventBus使用示例詳解

    vue篇之事件總線EventBus使用示例詳解

    這篇文章主要為大家介紹了vue篇之事件總線EventBus使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 在Vue3中進(jìn)行單元測(cè)試和集成測(cè)試的操作方法

    在Vue3中進(jìn)行單元測(cè)試和集成測(cè)試的操作方法

    隨著越來(lái)越多的企業(yè)和開發(fā)者選擇使用 Vue.js 構(gòu)建他們的前端應(yīng)用程序,確保代碼質(zhì)量和可靠性變得尤為重要,在本博客中,我們將深入探討如何在 Vue 3 中進(jìn)行單元測(cè)試和集成測(cè)試,并提供示例代碼來(lái)幫助您上手,需要的朋友可以參考下
    2025-01-01
  • 解決vue3中內(nèi)存泄漏的問題

    解決vue3中內(nèi)存泄漏的問題

    在項(xiàng)目中會(huì)發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象,當(dāng)我們?cè)谑褂胑lement-plus中的圖標(biāo)組件時(shí)會(huì)出現(xiàn)內(nèi)存泄漏,所以本文講給大家講講如何解決vue3中的內(nèi)存泄漏的問題,需要的朋友可以參考下
    2023-07-07
  • vue實(shí)現(xiàn)雙向綁定和依賴收集遇到的坑

    vue實(shí)現(xiàn)雙向綁定和依賴收集遇到的坑

    這篇文章主要介紹了vue的雙向綁定和依賴收集,主要是通過Object.defineProperty() 實(shí)現(xiàn)雙向綁定,具體思路代碼大家跟隨小編一起看看吧
    2018-11-11
  • vue中defineProperty和Proxy的區(qū)別詳解

    vue中defineProperty和Proxy的區(qū)別詳解

    這篇文章主要介紹了vue中defineProperty和Proxy的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論