vue+three.js+glb模型

运行结果

在这里插入图片描述

完整代码,复制到页面可用
<!--THREEJS组件-->
<template>
  <div id="d3Container" v-loading="loading" ref="mainContent">

  </div>
</template>
<script>
  import * as THREE from 'three'
  import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
  import {PLYLoader} from 'three/examples/jsm/loaders/PLYLoader.js'
  import {PCDLoader} from 'three/examples/jsm/loaders/PCDLoader'
  import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader'
  import {STLLoader} from 'three/examples/jsm/loaders/STLLoader'
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader";

  export default {
    name: "ThreePage",
    props: {
      /*模型资源地址*/
      ossPath: {
        type: String,
        default() {
          return ''
        }
      },
      /*文件类型*/
      suffix: {
        type: String,
        default() {
          return 'gltf'
        }
      },
      AutoFresh: {
        type: Boolean,
        default() {
          return true
        }
      },
      /*是否开启自动旋转*/
      autoAnimate: {
        type: Boolean,
        default() {
          return true
        }
      },
      /*当前模型的颜色*/
      currentColor: {
        type: String,
        default() {
          return ''
        }
      },
      /*配准后的颜色*/
      matchedColor: {
        type: String,
        default() {
          return ''
        }
      },
      /*配准后的地址*/
      matchedOssPatch: {
        type: String,
        default() {
          return ''
        }
      },
      showMatchWatch: {
        type: Boolean,
        default() {
          return false
        }
      }
    },
    data() {
      return {
        loading: false,
        publicPath: process.env.BASE_URL,
        mesh: null,
        camera: null,
        scene: null,
        originX: 20,
        originY: 0,
        originZ: 20,
        renderer: null,
        controls: null,
      }
    },
    mounted() {
      this.init()
    },
    watch: {
      //监听地址变化时需要更新地址,防止多次点击同一个渲染多次;
      ossPath(val, oldVal) {
        if (val != oldVal) {
          this.init()
        }
      },
      //监测是否更新整个场景
      AutoFresh(val, oldVal) {
        if (val) {
          this.init()
        } else {
          //自我清理
          this.destroyed();
        }
      },
      //监测是否展示配准,更新场景,该属性的变化只负责更新场景,具体业务交给按钮的最终展现结果,按钮勾中就展示配准,没有勾中就不展示配准,属性没变就是原来的状态。
      showMatchWatch(val, oldVal) {
        this.init()
      },
      //由于上传标签时,CAD会绕过。
      currentColor(val, oldVal) {
        if (val != oldVal) {
          this.init()
        }
      }
    },
    //组件被销毁时,干掉所有3D资源;
    methods: {
      destroyed() {
        this.clear();
      },
      // 初始化
      init() {
        /*利用vue单项数据流的特性做最后的守卫,在最底层监听是否需要展示配准图,只影响该组件的内部数据而不影响外部的matchedOssPatch*/
        if (!this.showMatchWatch) {
          this.matchedOssPatch = ''
        }
        this.createScene() // 创建场景
        this.loadLoader() // 加载P模型
        this.createLight() // 创建光源
        this.createCamera() // 创建相机
        this.createRender() // 创建渲染器
        this.createControls() // 创建控件对象
        this.render() // 渲染
      },
      //清除当前所有场景
      clear() {
        this.mesh = null
        this.camera = null
        this.scene = null
        this.renderer = null
        this.controls = null
        cancelAnimationFrame(this.animationId)
        console.log("我要清除啦");
      },
      // 创建场景
      createScene() {
        this.loading = true;
        this.scene = new THREE.Scene()
        var grid = new THREE.GridHelper(24, 24, 0xFF0000, 0x444444);
        grid.material.opacity = 0.4;
        grid.material.transparent = true;
        grid.rotation.x = Math.PI / 2.0;
        this.scene.add(grid)
      },
      // 加载PLY模型
      loadLoader() {
        const THIS = this
        // const loader = this.mapLoader();
         let loader = new GLTFLoader();
        loader.load(window.location.origin + `/fs/files/download/6128764fac0ba25313e73b4d`, geometry => {
        // loader.load(THIS.ossPath, geometry => {
        //   geometry.center();
          this.loading = false;
          let material = null;
                // this.isLoading = false;//关闭载入中效果
                this.mesh = geometry.scene;
                this.mesh.scale.set(0.4, 0.4, 0.4);//设置大小比例
                this.mesh.position.set(0, 0, 0);//设置位置
                this.scene.add(this.mesh); // 将模型引入three、
                // this.animate(); 
          
        })
        //如果有配准结果,加载配准结果,配准结果未ply格式;
      },
      // 创建光源
      createLight() {
        // 环境光
        let pointColor = '#ffffff';
        const ambientLight = new THREE.AmbientLight(0x222222, 0.35) // 创建环境光
        this.scene.add(ambientLight) // 将环境光添加到场景
        const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
        spotLight.position.set(50, 50, 50)
        spotLight.castShadow = true;//平行光开启阴影
        spotLight.receiveShadow = true;
        this.scene.add(spotLight)

      },

      // 创建相机
      createCamera() {
        const element = this.$refs.mainContent
        const width = element.clientWidth // 窗口宽度
        const height = element.clientHeight //
        this.cWidth = width;
        this.cHeight = height;
        const k = width / height // 窗口宽高比
        this.aspect = k;
        // PerspectiveCamera( fov, aspect, near, far )
        this.camera = new THREE.PerspectiveCamera(35, k, 1, 10000)
        this.camera.position.set(this.originX, this.originY, this.originZ) // 设置相机位置
        this.camera.up.set(0, 0, 1);
        this.camera.lookAt(new THREE.Vector3(this.originX, this.originY, this.originZ)) // 设置相机方向
        this.scene.add(this.camera)
      },
      // 创建渲染器
      createRender() {
        const element = this.$refs.mainContent
        this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true, preserveDrawingBuffer: true})
        this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
        this.renderer.shadowMap.enabled = true // 显示阴影
        this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
        this.renderer.setClearColor(new THREE.Color(0xEEEEEE)) // 设置背景颜色
        // this.renderer.setClearColor(new THREE.Color(0x111111)) // 设置背景颜色
        element.innerHTML = '';
        element.appendChild(this.renderer.domElement)
      },
      render() {
        this.animationId = requestAnimationFrame(this.render);//旋转动画;
        this.renderer.render(this.scene, this.camera)
        this.controls.update();
      },
      // 创建控件对象
      createControls() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      },
      onWindowResize() {
        this.camera.aspect = this.aspect;
        this.camera.updateProjectionMatrix();
      }
    }
  }
</script>

<style scoped>
  #d3Container {
    width: 100%;
    height: 100%;
    z-index: 888;
  }
</style>

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue.js 是一个流行的前端框架,而 Three.js 是一个用于创建 3D 图形的 JavaScript 库。将两者结合起来可以创建出令人惊叹的 3D 应用程序。下面是 vue+three.js 的每步解析: 1. 创建 Vue.js 应用程序 首先,需要创建一个 Vue.js 应用程序。可以使用 Vue CLI 来生成一个新的项目或手动创建一个新的 Vue.js 应用程序。 2. 安装 Three.js 可以使用 npm 包管理器安装 Three.js,也可以直接下载 Three.js 库文件并将其添加到项目中。 3. 在 Vue 组件中引入 Three.jsVue.js 中使用 Three.js 需要将其导入到组件中。可以使用 ES6 的 import 语句来引入 Three.js。 4. 创建场景、相机和渲染器 在 Three.js 中创建 3D 场景需要场景、相机和渲染器。可以在 Vue.js 组件的 mounted 钩子函数中创建它们。 5. 创建 3D 对象 可以使用 Three.js 来创建各种类型的 3D 对象,如立方体、球体、平面等。可以在 Vue.js 组件的 mounted 钩子函数中创建它们。 6. 将 3D 对象添加到场景中 创建 3D 对象后,需要将它们添加到场景中。可以使用场景对象的 add 方法来添加它们。 7. 渲染场景 最后,在 Vue.js 组件的 mounted 钩子函数中使用渲染器对象来渲染场景。 这是一个基本的 vue+three.js 应用程序的步骤。当然,还有很多其他的细节需要注意,如处理用户交互、加载 3D 模型等。但是,掌握了这些基本步骤,就可以开始创建自己的 3D 应用程序了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值