【小沐学Web3D】three.js 加载三维模型(vue3)

文章目录

  • [1、three 简介](#1、three 简介)
  • [2、three + vue](#2、three + vue)
  • [3、three + CDN](#3、three + CDN)
  • 结语

1、three 简介

Three.js 是一个基于 JavaScript 的开源库,用于在网页上创建和显示 3D 图形。它基于 WebGL 技术,简化了 3D 图形的开发过程,使得开发者能够轻松地在浏览器中实现复杂的 3D 场景和动画。

Three.js经常会和WebGL混淆, 但也并不总是,three.js其实是使用WebGL来绘制三维效果的。 WebGL是一个只能画点、线和三角形的非常底层的系统. 想要用WebGL来做一些实用的东西通常需要大量的代码, 这就是Three.js的用武之地。它封装了诸如场景、灯光、阴影、材质、贴图、空间运算等一系列功能,让你不必要再从底层WebGL开始写起。

2、three + vue

如果还没有创建项目,可以使用以下命令创建一个 Vue 3 项目,并选择 Vite 作为构建工具:

bash 复制代码
npm create vite@latest my-three-project -- --template vue

在项目目录下,使用 npm 安装 Three.js:

bash 复制代码
cd my-three-project
npm install three


bash 复制代码
npm install 

在 src/components 目录下创建一个新组件,例如 ThreeScene.vue。

bash 复制代码
my-three-project\src\components\ThreeScene.vue
html 复制代码
<template>
  <div ref="threeContainer" class="three-container"></div>
</template>

<script>
import * as THREE from 'three';

export default {
  name: 'ThreeScene',
  mounted() {
    this.initThree();
  },
  methods: {
    initThree() {
      // 创建场景
      const scene = new THREE.Scene();

      // 创建相机
      const camera = new THREE.PerspectiveCamera(
        75,
        this.$refs.threeContainer.clientWidth / this.$refs.threeContainer.clientHeight,
        0.1,
        1000
      );
      camera.position.z = 5;

      // 创建渲染器
      const renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(
        this.$refs.threeContainer.clientWidth,
        this.$refs.threeContainer.clientHeight
      );
      this.$refs.threeContainer.appendChild(renderer.domElement);

      // 创建一个立方体
      const geometry = new THREE.BoxGeometry();
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      const cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

      // 动画循环
      const animate = () => {
        requestAnimationFrame(animate);
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render(scene, camera);
      };
      animate();

      // 监听窗口大小变化,更新相机和渲染器
      window.addEventListener('resize', () => {
        camera.aspect = this.$refs.threeContainer.clientWidth / this.$refs.threeContainer.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(
          this.$refs.threeContainer.clientWidth,
          this.$refs.threeContainer.clientHeight
        );
      });
    },
  },
  beforeUnmount() {
    // 组件卸载时清理资源,避免内存泄漏
    if (this.renderer) {
      this.renderer.dispose();
      this.$refs.threeContainer.removeChild(this.renderer.domElement);
    }
  },
};
</script>

<style scoped>
.three-container {
  width: 100%;
  height: 100vh;
}
</style>

修改 App.vue 文件,引入并使用刚才创建的 ThreeScene 组件:

my-three-project\src\App.vue

html 复制代码
<template>
  <div id="app">
    <ThreeScene />
  </div>
</template>

<script>
import ThreeScene from './components/ThreeScene.vue';

export default {
  name: 'App',
  components: {
    ThreeScene,
  },
};
</script>

<style>
#app {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}
</style>

在项目根目录下运行以下命令启动开发服务器:

bash 复制代码
npm run dev

也可以不新建ThreeScene.vue,将相关代码都写在App.vue里面,如下:

html 复制代码
<template>
  <div ref="threeContainer" class="three-container"></div>
</template>

<script>
import * as THREE from 'three';

export default {
  name: 'ThreeScene',
  data() {
    return {
    };
  },
  mounted() {
    this.initThree();
  },
  beforeDestroy() {
    this.cleanupThree();
  },
  methods: {
    initThree() {
      // 初始化场景
      this.scene = new THREE.Scene();
      
      // 初始化相机
      this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      this.camera.position.z = 5;
      
      // 初始化渲染器
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.$refs.threeContainer.appendChild(this.renderer.domElement);
      
      // 创建立方体
      const geometry = new THREE.BoxGeometry();
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      this.cube = new THREE.Mesh(geometry, material);
      this.scene.add(this.cube);
     
      // 渲染循环
      const animate = () => {
        requestAnimationFrame(animate);
        this.cube.rotation.x += 0.01;
        this.cube.rotation.y += 0.01;
        this.renderer.render(this.scene, this.camera);
      };
      animate();
      
      // 监听窗口大小变化
      window.addEventListener('resize', this.handleResize);
    },
    handleResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },
    cleanupThree() {
      window.removeEventListener('resize', this.handleResize);
      this.renderer.dispose();
      this.renderer.forceContextLoss();
      this.renderer.context = null;
      this.renderer.domElement = null;
    }
  }
};
</script>

<style scoped>
.three-container {
  width: 100%;
  height: 100%;
}
</style>

3、three + CDN

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three.js 示例</title>
  <style>
    body { margin: 0; }
    canvas { display: block; }
  </style>
</head>
<body>
  <script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.138.3/three.min.js"></script>
  <script>
    // 创建场景
    const scene = new THREE.Scene();

    // 创建相机
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 5;

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // 创建立方体
    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    // 动画函数
    function animate() {
      requestAnimationFrame(animate);
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render(scene, camera);
    }

    // 启动动画
    animate();

    // 监听窗口大小变化
    window.addEventListener('resize', () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    });
  </script>
</body>
</html>

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

相关推荐
胚芽鞘68144 分钟前
vue + element-plus自定义表单验证(修改密码业务)
javascript·vue.js·elementui
小陈同学呦1 小时前
聊聊双列瀑布流
前端·javascript·面试
来自星星的坤1 小时前
SpringBoot 与 Vue3 实现前后端互联全解析
后端·ajax·前端框架·vue·springboot
键指江湖2 小时前
React 在组件间共享状态
前端·javascript·react.js
烛阴2 小时前
零基础必看!Express 项目 .env 配置,开发、测试、生产环境轻松搞定!
javascript·后端·express
诸葛亮的芭蕉扇2 小时前
D3路网图技术文档
前端·javascript·vue.js·microsoft
徐小夕2 小时前
花了2个月时间研究了市面上的4款开源表格组件,崩溃了,决定自己写一款
前端·javascript·react.js
拉不动的猪3 小时前
UniApp金融理财产品项目简单介绍
前端·javascript·面试
苏卫苏卫苏卫3 小时前
【Vue】案例——To do list:
开发语言·前端·javascript·vue.js·笔记·list
XDIGAS4 小时前
Dockerfile项目实战-单阶段构建Vue2项目
docker·容器·centos·node.js·vue