three.js 快速上手,实现一个简单的例子
对于3D上的内容,需要知道一些基本的概念,例如摄像机、场景、模型、材质、贴图、光源、环境等。
基础知识
WebGL:https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API
WebGL的功能有很多很多,但是基于WebGL去开发,很难并且效率也不高,three.js是一个开源的,功能齐全的 3D WebGL 库。
简单实现
安装
shell
npm i three
npm i -D @types/three
最小例子实现代码
使用vite vue-ts 实现基本的开发环境。
vue
<template>
<div class="canvas" ref="canvas">
</div>
</template>
<script lang='ts' setup>
import * as THREE from "three"
import { ref, onMounted, nextTick } from "vue"
const canvas = ref();
const handleInit = () => {
// 宽
let innerWidth = canvas.value.offsetWidth;
// 高
let innerHeight = canvas.value.offsetHeight;
// 场景
const scene = new THREE.Scene();
// 设置场景为白色
scene.background = new THREE.Color('#ffffff');
// 摄像机
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 1000);
camera.position.z = 5;
camera.position.y = 1;
// 渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器大小
renderer.setSize(innerWidth, innerHeight);
// 创建一个盒子模型数据
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 设置盒子的材质 MeshBasicMaterial材质不受光照
const material = new THREE.MeshBasicMaterial({ color: 0x03a9f4 });
// 组成一个盒子的网络
const cube = new THREE.Mesh(geometry, material);
// 场景加入盒子网络,默认为 场景世界的 (0,0,0) 坐标
scene.add(cube);
// renderer.domElement 实际是 canvas dom 对象
canvas.value.appendChild(renderer.domElement)
function animate() {
// 下一帧执行
requestAnimationFrame(animate);
// 为了更能直观的看出 立体的盒子 让盒子在每一帧的 围绕z x 轴旋转度数增加
cube.rotation.z += 0.01;
cube.rotation.x += 0.01;
// 渲染器渲染场景
renderer.render(scene, camera);
}
animate();
}
onMounted(() => {
nextTick(() => {
handleInit();
})
})
</script>
<style>
.canvas {
width: 100%;
height: 600px;
border-radius: 8px;
border: 1px solid #ddd;
overflow: hidden;
}
</style>
实现效果
自适应视图
当我们改变浏览器窗口大小时,渲染器的大小并不会更新,所以需要监听视图大小的变化,重新设置渲染器大小。
js
window.addEventListener('resize', () => {
let innerWidth = canvas.value.offsetWidth;
let innerHeight = canvas.value.offsetHeight;
renderer.setSize(innerWidth, innerHeight);
});