vue+three.js结合开发示例
vue结合three.js开发的一个简单案例
点击下方链接可在three.js官网查看例子与文档;
一、创建vue项目工程
选择一个存放项目的文件夹【E:\demo】,“cmd”打开命令行工具;
输入下列代码,创建vue项目,起一个自己的项目名称,例如:“ threejs_demo ”;
vue create threejs_demo
回车,选择vue2项目
回车,等待创建完成;
可以在我们的项目文件夹下看到我们新建的项目【threejs_demo】;
在【vs code】中打开,可以看下如下图所示的项目列表;
点击菜单栏中的【终端】,选择【新建终端】,或者使用快捷键【Ctrl + Shift + `】;
打开后,在【vs code】的下方,会出现如下图所示的窗口;一定要核对路径是否在自己项目的文件夹下,【E:\demo\threejs_demo> 】,如果不是,可以输入“cd xxx”相关命令切换盘符;
继续输入【npm run serve】命令,启动项目;
可以看到我们的项目已成功运行,可在浏览器窗口打开并查看;
(详细介绍请从上方链接查看)
二、导入three.js依赖
1、下载three.js包
在终端输入下方代码,下载three.js包;
npm i three
完成后,在<script></script>标签中,输入代码:
// 引入three.js
import * as THREE from "three";
console.log(THREE, "THREE");
如下图:
保存,运行后 可在浏览器的控制台查看打印输出结果:
看到如上输出结果,表示three.js引入成功;
三、第一个【vue + three.js】项目
1、核心代码
在【components】下新建一个vue文件,例如:threejs.vue,其余保持不变;
在【threejs.vue】文件中编写相关代码;
threejs.vue
<template>
<div class="box" ref="box"></div>
</template>
<script>
// 引入three.js
import * as THREE from "three";
console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功;
export default {
name: "ThreeJs",
methods: {
getThreeJs() {
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
100
);
camera.position.set(10, 10, 10); // 设置相机位置
camera.lookAt(0, 0, 0); // 设置相机看向原点
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const box = this.$refs.box; // 获取元素
box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素
// 添加辅助坐标
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);
// 创建几何体
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 声明渲染函数
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
},
},
mounted() {
this.getThreeJs(); // 执行three的相关代码
},
};
</script>
<style scoped>
.box {
width: 100%;
height: 100%;
}
</style>
在【App.vue】中引入【threejs.vue】,并展示;
App.vue
<template>
<div>
<!-- 使用ThreeJs组件 -->
<ThreeJs />
</div>
</template>
<script>
// 引入ThreeJs组件
import ThreeJs from "./components/threejs.vue";
export default {
name: "App",
components: {
ThreeJs, // 注册ThreeJs组件
},
};
</script>
<style>
* {
padding: 0;
margin: 0;
}
</style>
2、效果展示
将上述代码完全copy到自己的项目中, 运行成功后,你会看到如下图所示的展示效果;
四、源码解析
1、基础知识
在梳理代码之前,有必要了解three.js中的一些基本概念:
A.场景
官方给出这样的说明:【场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方】;
我们可以简单理解,场景就是一个容器,是我们用来放东西的地方;我们想要在项目中看到什么东西,便在场景中放什么进去即可;
B.相机
顾名思义,是用来给场景中的物体做投影的;相机就好比是我们的眼睛,它是将场景中的内容呈现给我们的工具;
要注意的相机中有一些必要的参数进行设置,比如,相机自身的位置,相机看向的位置,都会影响我们对整个场景的观测;
C.渲染器
如果有了场景,也有了相机,但是我们在页面中还是看不到想要的效果;
这是因为,虽然场景已经存在,相机也拍到了场景中的内容,但他们都是虚拟存在的,并不能真实呈现;这时候就需要一个工具,把相机看到的内容展示给我们,就是【渲染器】;
它的实质是将【相机】中看到的【场景】内容以Canvas的形式呈现在页面上;
D.渲染函数
渲染函数的作用就是,使渲染器能够在每次屏幕刷新时对场景进行绘制的循环;
2、引入three.js(必须)
在组件的<script></script>标签中,导入three.js包,习惯上命名为【THREE】;
可在控制台进行打印输入,确保three.js成功引入;
// 引入three.js
import * as THREE from "three";
console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功;
3、创建场景(必须)
使用【场景(Scene)】创建场景实例对象,它将是所有内容的容器;
// 创建场景
const scene = new THREE.Scene();
4、创建相机(必须)
使用【透视相机(PerspectiveCamera)】创建相机实例对象,其中四个参数分别表示: 视野角度、长宽比、近截面、远截面;
A. 视野角度
是指你在显示器上能看到场景的范围;类似我们人眼视野一样;该值越大,看到的范围越大;
B. 长宽比
是指物体宽(width)除以高(height)的比值;一般设置为窗口的宽高比;比例设置不当,会使得物体被压缩,或者拉伸;
C.近截面
是指在场景中能看到最近的地方,比近截面更近的地方不会被渲染(看不见);
D. 远截面
是指在场景中能看到最远的地方,比远截面更远的地方不会被渲染(看不见);
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
100
);
camera.position.set(10, 10, 10); // 设置相机位置
camera.lookAt(0, 0, 0); // 设置相机看向原点
5、创建渲染器(必须)
- 使用【 WebGLRenderer】构造器创建渲染器对象;其中,
- 【 setSize(width, height)方法 】,将输出canvas的大小调整为整个窗口的宽高比例;
- 【 renderer.domElement 】即为渲染器绘制输出的Canvas,将其添加到我们的页面容器中即可;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const box = this.$refs.box; // 获取元素
box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素
6、创建几何体(可选)
- 使用【立方缓冲几何体(BoxGeometry)】创建立方体,可传入 “width”、“height”、“depth” 参数设置立方体的长宽高属性;
- 使用【基础网格材质(MeshBasicMaterial)】,来创建几何体的材质;
- 使用【网格(Mesh)】,来创建立方体实例,需要传入几何体的【形状和材质】两个参数;
- 使用【scene.add()】,再将创建好的【cube】实例对象添加到【场景对象scene】中;
// 创建几何体
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
7、声明并调用渲染函数(必须)
至此,我们已经创建好了场景、相机、渲染器;不难发现,我们的页面中依旧是什么也看不见,这是因为场景中的内容还未进行【真正渲染】;
我们需要定义一个渲染函数,让它做【渲染循环 || 动画循环】;
【requestAnimationFrame(animate)】指定浏览器在下一次循环之前执行指定函数(animate);
【renderer.render(scene, camera)】用我们创建的渲染器实例对象renderer,将场景实例对象scene中内容,在相机实例对象camera中的投影,渲染在Canvas上;
// 声明渲染函数
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
8、添加坐标轴辅助对象(可选)
使用【AxesHelper】 创建坐标轴对象实例,会在我们的场景中添加一个坐标轴,辅助观测;
红色代表X轴,绿色代表Y轴,蓝色代表Z轴;
// 添加辅助坐标
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);
9、官网实例
五、可能出现的问题(注意点)
1、相机相关
- 创建相机的时候,需要注意参数的设置,考虑后续创建的模型物体的大小尺寸;避免模型过大或过小,导致不在相机的观测范围内(就像现实中离得太远或者太近的问题);
- 【相机的位置】和【相机看向的位置】要有大致的概念,避免相机观测的位置不是模型所在的位置(就像现实中有个东西在我们身后,看不见一样);
2、渲染器相关
- 一定要将渲染器输出的结果Canvas,也就是【renderer.domElement】添加到我们的页面元素中;
- 一定要声明和执行渲染函数;
3、模型相关
- 考虑模型的大小尺寸,要跟相机参数相匹配(不然就得进一步调整相机参数);
- 一开始我们先选用【基础网格材质(MeshBasicMaterial)】,“这种材质不受光照的影响”,如果选用其他材质,那可能就得设置光源等因素才能使物体呈现在我们的视野中(就像现实中,我们在没有光的时候看不见东西是一样的);
- 创建好几何体后,要注意【scene.add()】将物体添加到我们的场景中;
以上就是我个人在整个demo的开发过程中,遇到过的问题,或者是觉得需要注意的地方;简单整理,希望有用;
在整个过程中可能还会出现很多其他的问题,但是只要大家耐心,慢慢调试,成功往往就是下一个瞬间!
六、项目拓展
1、自适应窗口
不难发现,我们的项目中,如果改变窗口的大小,页面内容并不能实现自适应,
想要页面内容实现窗口自适应,我们需要添加对window的resize的监听;
一旦浏览器窗口发生大小变化,我们就去更新【渲染器绘制的宽高比】和【相机投影的宽高比】,代码如下:
// 监听窗口变化
window.addEventListener("resize", () => {
renderer.setSize(window.innerWidth, window.innerHeight); // 重置渲染器宽高比
camera.aspect = window.innerWidth / window.innerHeight; // 重置相机宽高比
camera.updateProjectionMatrix(); // 更新相机的投影矩阵
});
2、鼠标操控
此外,我们的页面内容并不能动,不像真正的3D项目,是静态的,是平面的;
我们想操控它动起来,最简单的方式就是添加【轨道控制器】,可以使得相机围绕目标进行轨道运动;
首先,需要引入
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
然后添加,代码如下:
// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 设置带阻尼的惯性
controls.dampingFactor = 0.05; // 设置阻尼的系数
controls.autoRotate = true; // 设置自动旋转
最后,需要在【渲染函数】animate()中更新控制器,添加下述代码(一定要添加!一定要添加!一定要添加!)
controls.update() // 更新控制器
完成后,我们就可以观测到页面中的内容动起来了;
我们也可以使用鼠标控制,按住【鼠标右键 || 鼠标左键】滑动一下,看看效果吧~~~
3、完整代码
只需修改【threejs.vue】即可;
<template>
<div class="box" ref="box"></div>
</template>
<script>
// 引入three.js
import * as THREE from "three";
// console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功;
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export default {
name: "ThreeJs",
methods: {
getThreeJs() {
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
100
);
camera.position.set(10, 10, 10); // 设置相机位置
camera.lookAt(0, 0, 0); // 设置相机看向原点
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const box = this.$refs.box; // 获取元素
box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素
// 添加辅助坐标
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);
// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置带阻尼的惯性
controls.enableDamping = true;
// 设置阻尼的系数
controls.dampingFactor = 0.05;
// 设置自动旋转
controls.autoRotate = true;
// 创建几何体
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 声明渲染函数
function animate() {
controls.update() // 更新控制器
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
// 监听窗口变化
window.addEventListener("resize", () => {
// 重置渲染器宽高比
renderer.setSize(window.innerWidth, window.innerHeight);
// 重置相机宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 更新相机的投影矩阵
camera.updateProjectionMatrix();
});
},
},
mounted() {
this.getThreeJs(); // 执行three的相关代码
},
};
</script>
<style scoped>
.box {
width: 100%;
height: 100%;
}
</style>
==================================================================================================================================================
现在,不出意外的话,我们已经做好了第一个vue+three.js开发的项目了!
希望通过这个入门案例,使我们对three.js开发有初步了解!
期待后续的完善和创作吧!!!
更多推荐
所有评论(0)