VUE整合ThreeJS并创建一个带动画的简单场景
一、环境准备开始之前,需要准备好如下工具,本例使用的工具及其版本号如下(后续如有相关文章,则都基于此环境),IDE使用的Webstorm,当然你可以选择vs code等工具,yarn非必要,如果你习惯用npm可忽略yarn。angular或react整合都大同小异。名称版本nodev14.7.0vue-cli4.4.6yarn..
先上效果图
一、环境准备
开始之前,需要准备好如下工具,本例使用的工具及其版本号如下(后续如有相关文章,则都基于此环境),IDE使用的Webstorm,当然你可以选择vs code等工具,yarn非必要,如果你习惯用npm可忽略yarn。
angular或react整合都大同小异。
名称 | 版本 |
node | v14.7.0
|
vue-cli | 4.4.6
|
yarn | 1.9.4
|
threejs | 127 |
webstorm | 2019.3.3 |
二、创建vue工程
输入如下命令,创建vue工程
vue create vue-threejs
等待完成,如下图所示
输入命令,启动服务,测试是否创建成功
cd vue-threejs
yarn serve
输入http://localhost:8080/
至此,vue环境准备完毕,接下来我们用开发工具打开这个工程,准备添加threejs。
三、添加threejs
使用如下命令添加threejs相关包,注意下面的包为一些常用的包,本例不一定全用到,只是在这罗列一下,按需安装即可,包的详细介绍可单独搜索查询,这里不详细阐述。
包名 | 命令 | 描述 |
three | yarn add three | threejs核心 |
three-obj-mtl-loader | yarn add three-obj-mtl-loader | 加载外部obj和mtl所需 |
three-orbit-controls | yarn add three-orbit-controls | 轨道控制器,用于控制场景中的对象围绕场景中心旋转和平移。 |
three-trackballcontrols | yarn add three-trackballcontrols | 轨迹球控制器,可以使用鼠标来轻松移动、平移和缩放场景 |
dat-gui | yarn add dat-gui | 可以容易地创建修改代码变量的界面组件 |
stats-js | yarn add stats-js | 能够在页面显示帧数,辅助开发 |
添加后,package.json如下
四、构建一个简单的场景
直接上干货,代码如下:
import * as THREE from 'three'
import Stats from 'stats-js'
import * as Dat from 'dat-gui'
import TrackballControls from 'three-trackballcontrols'
export default {
name: 'HelloThreeJs',
data() {
return {
step: 0
}
},
mounted() {
this.renderer
this.camera
this.scene
this.light
this.gui
this.axesHelper
this.stats
this.trackballControls
this.clock
this.sphere
this.cube
this.controls
// 执行
this.execute()
// 窗口大小变化
window.onresize = this.onWindowResize
},
methods: {
initScene() {
this.scene = new THREE.Scene()
},
initCamera() {
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
// 设置相机位置
this.camera.position.x = -30
this.camera.position.y = 40
this.camera.position.z = 30
// 设置相机指向的位置 默认0,0,0
this.camera.lookAt(this.scene.position)
},
initHelper() {
this.axesHelper = new THREE.AxesHelper(10)
this.scene.add(this.axesHelper)
},
initRender() {
this.renderer = new THREE.WebGLRenderer({ antialias: true })
this.renderer.setSize(window.innerWidth, window.innerHeight)
// 告诉渲染器需要阴影效果
this.renderer.shadowMap.enabled = true
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
// 设置背景色
this.renderer.setClearColor(new THREE.Color(0x000000))
document.querySelector('#container').appendChild(this.renderer.domElement)
},
initStats() {
this.stats = new Stats()
document.body.appendChild(this.stats['dom'])
},
initModel() {
// 创建一个球体
const sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
// 创建球体材质
const sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff })
this.sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
// 开启阴影
this.sphere.castShadow = true
// 设置位置
this.sphere.position.x = 20
this.sphere.position.y = 4
this.sphere.position.z = 2
// 添加球体
this.scene.add(this.sphere)
// 创建一个立方体 长宽高为4
const cubeGeometry = new THREE.BoxGeometry(4, 4, 4)
// 创建立方体材质
const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 })
this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 立方体开启投影效果
this.cube.castShadow = true
// 设置位置
this.cube.position.x = -4
this.cube.position.y = 3
this.cube.position.z = 0
// 添加立方体
this.scene.add(this.cube)
// 创建一个几何平面,宽60,高20
const planeGeometry = new THREE.PlaneGeometry(60, 20)
// 创建带颜色材质,更换为MeshLambertMaterial材质,去掉网格结构
const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc })
this.plane = new THREE.Mesh(planeGeometry, planeMaterial)
// 平面开启接收阴影效果
this.plane.receiveShadow = true
// 设置平面角度和位置
this.plane.rotation.x = -0.5 * Math.PI
this.plane.position.x = 15
this.plane.position.y = 0
this.plane.position.z = 0
// 添加平面
this.scene.add(this.plane)
},
initLight() {
// 添加光源
const spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(-40, 60, -10)
spotLight.castShadow = true
this.scene.add(spotLight)
},
initGui() {
this.controls = {
rotationSpeed: 0.02,
bouncingSpeed: 0.03
}
const gui = new Dat.GUI()
gui.add(this.controls, 'rotationSpeed', 0, 0.5)
gui.add(this.controls, 'bouncingSpeed', 0, 0.5)
},
initControls() {
this.trackballControls = new TrackballControls(this.camera, this.renderer.domElement)
this.trackballControls.rotateSpeed = 1.0
this.trackballControls.zoomSpeed = 1.2
this.trackballControls.panSpeed = 0.8
this.trackballControls.noZoom = false
this.trackballControls.noPan = false
this.trackballControls.staticMoving = true
this.trackballControls.dynamicDampingFactor = 0.3
this.trackballControls.keys = [65, 83, 68]
},
initClock() {
this.clock = new THREE.Clock()
},
render() {
this.trackballControls.update(this.clock.getDelta())
this.stats.update()
// rotate the this.cube around its axes
this.cube.rotation.x += this.controls['rotationSpeed']
this.cube.rotation.y += this.controls['rotationSpeed']
this.cube.rotation.z += this.controls['rotationSpeed']
// bounce the this.sphere up and down['']
this.step += this.controls['bouncingSpeed']
this.sphere.position.x = 20 + (10 * (Math.cos(this.step)))
this.sphere.position.y = 2 + (10 * Math.abs(Math.sin(this.step)))
// render using requestAnimationFrame
requestAnimationFrame(this.render)
this.renderer.render(this.scene, this.camera)
},
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(window.innerWidth, window.innerHeight)
},
execute() {
// 初始化场景
this.initScene()
// 初始化摄像头
this.initCamera()
// 初始化三维坐标系
this.initHelper()
// 初始化辅助UI
this.initGui()
// 初始化帧数显示工具
this.initStats()
// 初始化时钟工具
this.initClock()
// 初始化模型
this.initModel()
// 初始化渲染器
this.initRender()
// 初始化光源
this.initLight()
// 初始化控制器
this.initControls()
// 执行渲染
this.render()
}
}
}
更多推荐
所有评论(0)