three.js 安装与使用
three.js 是一个基于 WebGL
的 JavaScript
库,用于创建 3D
图形。
three.js
安装
shell
npm install three
注意 three.js
的版本号
在项目中引入 three.js
ts
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
ts
const WIDTH = 400
const HEIGHT = 300
const container = ref() // 挂着元素的容器
const scene = new THREE.Scene() // 场景
const camera = new THREE.PerspectiveCamera(75, WIDTH / HEIGHT, 0.1, 1000) // 相机
camera.position.set(200, 200, 200)// 相机位置
const renderer = new THREE.WebGLRenderer()// 渲染器
renderer.setSize(WIDTH, HEIGHT) // 设置渲染器的尺寸
const material = new THREE.MeshBasicMaterial({color: 0x409eff})// 创建一个网格模型(材质)
const geometry = new THREE.BoxGeometry(100, 100, 100) // 创建一个网格模型(几何体)
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh) // 把网格模型添加到场景中
scene.add(camera) // 把相机添加到场景中
nextTick(() => {
const controls = new OrbitControls(camera, renderer.domElement)
container.value.appendChild(renderer.domElement)
})
Scene 场景
可以理解为世界地图,是一个三维空间,可以放置 物体
,可以放置光源
,可以放置摄像机
。
PerspectiveCamera 透视相机
画面的透视,可以理解为眼睛的视角。
- 参数
fov
:相机视角,类似视线宽度,值越大,相机视线内角度越大aspect
:相机的宽高比,类似可视屏的宽高比。near
:相机可视最近的距离。far
:相机可视最远的距离。
MeshBasicMaterial,BoxGeometry 网格模型材质和长方体几何
这里创建一个长方体 颜色 0x409eff
尺寸 : (100, 100, 100)
并且使用 Mesh
创建模型
WebGLRenderer 渲染器
将相当于捕获相机的当前的帧,并渲染到canvas画布上
- 需要在初始化中通过
renderer.setSize
设置渲染器的尺寸 并挂载到页面中
OrbitControls 相机控制器
可以通过鼠标控制相机的移动,缩放,旋转
更新相机帧
ts
function animate() { // 刷新
requestAnimationFrame(animate)
// 操作
renderer.render(scene, camera)
}
// 当页面尺寸改变时,更新相机的宽高比
window.addEventListener('resize', () => {
camera.aspect = WIDTH / HEIGHT
camera.updateProjectionMatrix()
renderer.setSize(WIDTH, HEIGHT)
})
效果
这里通过 修改 控制物体旋转
ts
mesh.rotation.x += 0.01
mesh.rotation.y += 0.01
点击查看代码
vue
<script setup lang="ts">
import * as THREE from 'three'
import { nextTick, ref, watchEffect } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { useElementSize } from '@vueuse/core';
const container = ref()
const { width, height } = useElementSize(container)
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, 100 / 100, 0.1, 2000)
camera.position.set(200, 200, 200)
const renderer = ref<THREE.WebGLRenderer>(new THREE.WebGLRenderer())
const material = new THREE.MeshBasicMaterial({
color: 0x409eff
})
const geometry = new THREE.BoxGeometry(150, 150, 150)
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
scene.add(camera)
function animate() {
mesh.rotation.x += 0.01
mesh.rotation.y += 0.01
renderer.value.setSize(width.value, height.value)
renderer.value.render(scene, camera)
requestAnimationFrame(animate)
}
watchEffect(() => {
camera.aspect = width.value / height.value
camera.updateProjectionMatrix()
renderer.value.setSize(width.value, height.value)
})
nextTick(() => {
new OrbitControls(camera, renderer.value.domElement)
container.value.appendChild(renderer.value.domElement)
animate()
})
</script>
<template>
<div ref="container" style="height: 400px;" />
</template>