当前位置: 首页 > article >正文

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

文章目录

  • 1、three 简介
  • 2、three + vue
  • 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 作为构建工具:

npm create vite@latest my-three-project -- --template vue

在这里插入图片描述
在项目目录下,使用 npm 安装 Three.js:

cd my-three-project
npm install three

在这里插入图片描述
在这里插入图片描述

npm install 

在这里插入图片描述
在 src/components 目录下创建一个新组件,例如 ThreeScene.vue。

my-three-project\src\components\ThreeScene.vue
<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

<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>

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

npm run dev

在这里插入图片描述

在这里插入图片描述
也可以不新建ThreeScene.vue,将相关代码都写在App.vue里面,如下:

<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

<!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???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!


http://www.kler.cn/a/587130.html

相关文章:

  • 23.生产者消费者模型
  • C# NX二次开发:旋转UFUN函数使用详解
  • ​AI时代到来,对电商来说是效率跃升,还是温水煮青蛙
  • PyTorch PINN实战:用深度学习求解微分方程
  • IPoIB驱动中RSS与TSS技术的深度解析:多队列机制与性能优化
  • 洛谷 P1962:斐波那契数列 ← 矩阵快速幂
  • [人工智能]实现神经网络实例
  • 04.Python基础3
  • go~大型项目的参数注册
  • [local-file-system]基于服务器磁盘的本地文件存储方案
  • CentOS 系统安装 docker 以及常用插件
  • Elasticsearch分页查询、关键词高亮与性能优化全解析
  • 国产芯片替代方案:解析沁恒以太网控制器芯片,内置MAC地址
  • 【MySQL】undo日志类型
  • CSS3学习教程,从入门到精通,CSS3 选择器权重问题语法知识点及案例代码(5)
  • Freertos--把队列加入队列集
  • 使用tiptap快速搭建markdown-富文本编辑器
  • 电路基础【2】:三极管基础:PNP与NPN三极管详解
  • FPGA 中 assign 和 always 区别
  • 2.4滑动窗口专题:将 x 减到 0 的最小操作数