实战:使用Vue和Three.js创建3D场景

蓝色妖姬 2022-05-24 ⋅ 15 阅读

在本篇博客中,我们将介绍如何使用Vue和Three.js创建一个令人惊叹的3D场景。通过结合Vue的数据驱动和Three.js的强大渲染引擎,我们可以轻松地构建一个富有交互性的3D场景。

准备工作

首先,我们需要创建一个新的Vue项目。在终端中运行以下命令:

vue create my-3d-scene

按照提示进行配置,选择默认配置即可。然后进入项目目录:

cd my-3d-scene

安装Three.js:

npm install three

安装Vue-threejs插件:

npm install vue-threejs

创建场景

我们将在Vue组件中创建我们的3D场景。在src/components目录下创建一个名为Scene.vue的文件,并添加以下内容:

<template>
  <div ref="container"></div>
</template>

<script>
import { Scene } from 'three';

export default {
  mounted() {
    this.initScene();
  },
  methods: {
    initScene() {
      this.scene = new Scene();

      // 添加场景元素的代码将写在这里
    }
  }
}
</script>

以上代码创建了一个Scene组件,并在组件挂载时调用了initScene方法。

现在我们需要在场景中添加一些元素。比如,我们可以添加一个立方体。在initScene方法中添加以下代码:

import { Scene, BoxGeometry, MeshBasicMaterial, Mesh } from 'three';

initScene() {
  this.scene = new Scene();
  
  // 创建立方体
  const geometry = new BoxGeometry(1, 1, 1);
  const material = new MeshBasicMaterial({ color: 0x00ff00 });
  const cube = new Mesh(geometry, material);
  
  // 将立方体添加到场景中
  this.scene.add(cube);
}

以上代码创建了一个立方体,并将其添加到场景中。

渲染场景

现在我们已经创建了一个场景,并向其中添加了一个立方体,接下来需要渲染这个场景。我们将在Vue组件中创建一个渲染器。继续编辑Scene.vue文件:

<template>
  <div ref="container"></div>
</template>

<script>
import { Scene, BoxGeometry, MeshBasicMaterial, Mesh, PerspectiveCamera, WebGLRenderer } from 'three';

export default {
  data() {
    return {
      camera: null,
      renderer: null,
    };
  },
  mounted() {
    this.initScene();
    this.initCamera();
    this.initRenderer();
    this.renderScene();
  },
  methods: {
    initScene() {
      this.scene = new Scene();
  
      // 创建立方体
      const geometry = new BoxGeometry(1, 1, 1);
      const material = new MeshBasicMaterial({ color: 0x00ff00 });
      const cube = new Mesh(geometry, material);
  
      // 将立方体添加到场景中
      this.scene.add(cube);
    },
    initCamera() {
      this.camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      this.camera.position.z = 5;
    },
    initRenderer() {
      this.renderer = new WebGLRenderer();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.$refs.container.appendChild(this.renderer.domElement);
    },
    renderScene() {
      this.renderer.render(this.scene, this.camera);

      requestAnimationFrame(this.renderScene);
    }
  }
}
</script>

以上代码创建了一个相机和一个渲染器,并且在每一帧都渲染场景。

添加交互

最后,我们可以添加一些交互性。比如,在鼠标移动时旋转场景。编辑Scene.vue文件,添加以下代码:

<template>
  <div ref="container"></div>
</template>

<script>
import { Scene, BoxGeometry, MeshBasicMaterial, Mesh, PerspectiveCamera, WebGLRenderer, Vector2, Quaternion, Euler } from 'three';

export default {
  data() {
    return {
      camera: null,
      renderer: null,
      mousePosition: new Vector2(),
      rotationSpeed: 0.02,
      previousMousePosition: new Vector2()
    };
  },
  mounted() {
    this.initScene();
    this.initCamera();
    this.initRenderer();
    this.renderScene();

    this.$refs.container.addEventListener('mousemove', this.handleMouseMove);
  },
  destroyed() {
    this.$refs.container.removeEventListener('mousemove', this.handleMouseMove);
  },
  methods: {
    initScene() {
      this.scene = new Scene();
  
      // 创建立方体
      const geometry = new BoxGeometry(1, 1, 1);
      const material = new MeshBasicMaterial({ color: 0x00ff00 });
      const cube = new Mesh(geometry, material);
  
      // 将立方体添加到场景中
      this.scene.add(cube);
    },
    initCamera() {
      this.camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      this.camera.position.z = 5;
    },
    initRenderer() {
      this.renderer = new WebGLRenderer();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.$refs.container.appendChild(this.renderer.domElement);
    },
    renderScene() {
      this.renderer.render(this.scene, this.camera);

      requestAnimationFrame(this.renderScene);
    },
    handleMouseMove(event) {
      this.mousePosition.x = (event.clientX / window.innerWidth) * 2 - 1;
      this.mousePosition.y = -(event.clientY / window.innerHeight) * 2 + 1;

      const rotationX = new Euler(0, this.mousePosition.x - this.previousMousePosition.x, 0);
      const rotationY = new Euler(this.mousePosition.y - this.previousMousePosition.y, 0, 0);
      const quaternionX = new Quaternion().setFromEuler(rotationX);
      const quaternionY = new Quaternion().setFromEuler(rotationY);
      this.scene.quaternion.multiplyQuaternions(quaternionX, Quaternion.multiplyQuaternions(this.scene.quaternion, quaternionY));

      this.previousMousePosition.x = this.mousePosition.x;
      this.previousMousePosition.y = this.mousePosition.y;
    }
  }
}
</script>

以上代码将允许用户在鼠标移动时旋转场景。

恭喜,我们已经成功地使用Vue和Three.js创建了一个令人惊叹的3D场景!你现在可以尝试添加更多的场景元素和交互效果,让你的场景更加丰富多样。Happy coding!


全部评论: 0

    我有话说: