最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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動(dòng)態(tài)添加class可能帶來(lái)的問(wèn)題解讀(被覆蓋)

    Vue動(dòng)態(tài)添加class可能帶來(lái)的問(wèn)題解讀(被覆蓋)

    文章討論了在使用Vue.js時(shí),通過(guò)動(dòng)態(tài)class修改元素樣式時(shí)可能會(huì)遇到的問(wèn)題,當(dāng)通過(guò)JavaScript動(dòng)態(tài)添加類時(shí),Vue的動(dòng)態(tài)class會(huì)覆蓋掉通過(guò)JavaScript添加的類,導(dǎo)致樣式丟失,這個(gè)問(wèn)題在實(shí)際開(kāi)發(fā)中可能會(huì)遇到,尤其是在使用第三方框架
    2024-12-12
  • 結(jié)合el-upload組件實(shí)現(xiàn)大文件分片上傳功能

    結(jié)合el-upload組件實(shí)現(xiàn)大文件分片上傳功能

    Element UI的el-upload上傳組件相信各位小伙伴都已經(jīng)非常熟悉,最近接了一個(gè)新需求,要求在el-upload組件基礎(chǔ)上實(shí)現(xiàn)分片上傳功能,即小于等于5M文件正常上傳,大于5M文件切成5M每片上傳,那么這個(gè)功能怎么實(shí)現(xiàn)呢?一起看看吧
    2022-09-09
  • vue+element_ui上傳文件,并傳遞額外參數(shù)操作

    vue+element_ui上傳文件,并傳遞額外參數(shù)操作

    這篇文章主要介紹了vue+element_ui上傳文件,并傳遞額外參數(shù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Vue3+TypeScript+Vite服務(wù)端渲染項(xiàng)目的實(shí)現(xiàn)

    Vue3+TypeScript+Vite服務(wù)端渲染項(xiàng)目的實(shí)現(xiàn)

    本文主要介紹了Vue3+TypeScript+Vite服務(wù)端渲染項(xiàng)目的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • vue中this.$parent的使用方式

    vue中this.$parent的使用方式

    這篇文章主要介紹了vue中this.$parent的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Vue中使用方法、計(jì)算屬性或觀察者的方法實(shí)例詳解

    Vue中使用方法、計(jì)算屬性或觀察者的方法實(shí)例詳解

    這篇文章主要介紹了Vue中如何使用方法、計(jì)算屬性或觀察者的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-10-10
  • 如何在vue中使用HTML 5 拖放API

    如何在vue中使用HTML 5 拖放API

    這篇文章主要介紹了如何在vue中使用HTML 5 拖放API,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2021-01-01
  • Vue?Hook?封裝通用型表格的詳細(xì)過(guò)程

    Vue?Hook?封裝通用型表格的詳細(xì)過(guò)程

    這篇文章主要介紹了Vue?Hook?封裝通用型表格,設(shè)計(jì)通用型表格組件首先,需要設(shè)計(jì)一個(gè)基礎(chǔ)的表格組件,它接受列配置、數(shù)據(jù)和分頁(yè)信息等參數(shù),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • Vue打包程序部署到Nginx 點(diǎn)擊跳轉(zhuǎn)404問(wèn)題

    Vue打包程序部署到Nginx 點(diǎn)擊跳轉(zhuǎn)404問(wèn)題

    這篇文章主要介紹了Vue打包程序部署到Nginx 點(diǎn)擊跳轉(zhuǎn)404問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 如何在vue中使用pdfjs預(yù)覽pdf文件

    如何在vue中使用pdfjs預(yù)覽pdf文件

    本文主要講解了如何在vue中使用pdfjs預(yù)覽pdf文件,這樣的優(yōu)勢(shì)是無(wú)須讓用戶安裝專門的軟件即可實(shí)現(xiàn)預(yù)覽,下面就看看如何實(shí)現(xiàn)這個(gè)需求
    2021-06-06

最新評(píng)論

遵化市| 娱乐| 蓬安县| 江川县| 岢岚县| 军事| 六安市| 长春市| 南安市| 清水河县| 陇川县| 靖安县| 厦门市| 石首市| 芦溪县| 昌宁县| 和田县| 辽源市| 庄河市| 凤山市| 湖州市| 贺州市| 辉县市| 安仁县| 闻喜县| 望奎县| 中方县| 清水县| 鄯善县| 新民市| 常熟市| 临泽县| 福州市| 景洪市| 怀宁县| 和林格尔县| 乌苏市| 苍南县| 深州市| 平陆县| 邛崃市|