vue3.0 + ts + threejs 实现简单的demo
背景
去年之所以再次兴起了学习 WebGL 的念头,主要是有两个原因:
其一是现阶段元宇宙概念巨火;
其二是想用 Web 技术实现游戏和3D动画场景,比如头号玩家电影中的科幻场景,或者像宫崎骏的动漫中的场景,简直酷毙了。
技术
vue3.0
typescript
threejs
实现
创建一个项目
用 ue-cli 可以快速的创建一个项目,我本地已经创建好了如下:
引入 threejs
因为我们用typescript
,所以我们引入@types/three
要看@types/three文档可以去
npm: www.npmjs.com/package/@ty…
github: github.com/DefinitelyT…
安装threejs
npm install --save @types/three
安装好的效果,如下
应用threejs
在我们要用得项目中引入three
import * as THREE from "three";
引入后我们发现报错,解决如下:在shims-vue.d.ts
文件中加入
declare module "@types/three";
写个demo
在router/index.ts增加路由,代码如下:
{ path: "/demo01", name: "Demo01", component: () => import("@/views/Demo01/Demo01.vue"), } 复制代码
2. 在views中增加目录,如下:
demo01.vue代码:
<template> <div class="demo"></div> </template> <script lang="ts"> import ThreeJs from "./index"; import { defineComponent, onMounted } from "vue"; export default defineComponent({ name: "Demo01", props: {}, setup() { onMounted(() => { new ThreeJs(); }); }, }); </script> <style scoped lang="scss"></style> 复制代码
index.ts 代码,如下:
import * as THREE from "three"; export default class ThreeJs { scene: THREE.Scene | null = null; camera: THREE.PerspectiveCamera | null = null; renderer: THREE.WebGLRenderer | null = null; ambientLight: THREE.AmbientLight | null = null; mesh: THREE.Mesh | null = null; constructor() { this.init(); } init(): void { // 第一步新建一个场景 this.scene = new THREE.Scene(); this.setCamera(); this.setRenderer(); this.setCube(); this.animate(); } // 新建透视相机 setCamera(): void { // 第二参数就是 长度和宽度比 默认采用浏览器 返回以像素为单位的窗口的内部宽度和高度 this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); this.camera.position.z = 5; } // 设置渲染器 setRenderer(): void { this.renderer = new THREE.WebGLRenderer(); // 设置画布的大小 this.renderer.setSize(window.innerWidth, window.innerHeight); //这里 其实就是canvas 画布 renderer.domElement document.body.appendChild(this.renderer.domElement); } // 设置环境光 setLight(): void { if (this.scene) { this.ambientLight = new THREE.AmbientLight(0xffffff); // 环境光 this.scene.add(this.ambientLight); } } // 创建网格模型 setCube(): void { if (this.scene) { const geometry = new THREE.BoxGeometry(); //创建一个立方体几何对象Geometry // const material = new THREE.MeshBasicMaterial({ color: 0xff3200 }); //材质对象Material const texture = new THREE.TextureLoader().load( "/assets/imgs/dalishi.jpg" ); //首先,获取到纹理 const material = new THREE.MeshBasicMaterial({ map: texture }); //然后创建一个phong材质来处理着色,并传递给纹理映射 this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh this.scene.add(this.mesh); //网格模型添加到场景中 this.render(); } } // 渲染 render(): void { if (this.renderer && this.scene && this.camera) { this.renderer.render(this.scene, this.camera); } } // 动画 animate(): void { if (this.mesh) { requestAnimationFrame(this.animate.bind(this)); this.mesh.rotation.x += 0.01; this.mesh.rotation.y += 0.01; this.render(); } } } 复制代码
看效果:
作者:027西瓜皮
链接:https://juejin.cn/post/7056241894451314725