threejs安装与开始
安装导入
npm
npm i three
导入
并非所有功能都在three,还需从子目录导入
// three模块
import * as three from 'three'
// 一些不在three模块的功能,这里是OrbitControls导入示例
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
静态页面/CDN
three是一个esm模块,需要按模块导入方法导入,
// 不是所有浏览器都支持ems模块,这是一个esm模块兼容库
<script defer src="https://unpkg.com/es-module-shims@0.4.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@<version>/build/three.module.js",
"three/addons/": "https://unpkg.com/three@<version>/examples/jsm/"
}
} </script>
<script type="module">
import * as THREE from 'three'; const scene = new THREE.Scene()
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
</script>
npm包查看
build
目录有5个js文件,大致分为three.js
与three.module.js
,three.js
中提示已经弃用,现在应该使用three.module.js
开始
环境
场景
const scene = new three.Scene()
相机
const camera = new three.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
相机有多种,这里是透视相机
- 视野角度。就是你能看到的场景范围
- 宽高比。注意不是宽高,是宽高比,宽高比及分辨率在渲染器设置
- 近视距。相机与目标物体小于此值,此物体将不会渲染
- 远视距。相机与目标物体大于此值,此物体将不会渲染
帧渲染器
const renderer = new three.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.append(renderer.domElement)
setSize
函数
- 宽
- 高
- 布尔。默认
true
,宽高既是高度也是分辨率。false
仅设置分辨率
直接设置canvas
的宽高后,就不用在这里设置宽高了,这里设置分辨率就行。
动画都是基于
canvas
标签的,示例中的renderer.domElement
就是一个canvas
标签,所以可以直接设置宽高。
动画编写
const geometry = new three.BoxGeometry(1, 1, 1)
const material = new three.MeshBasicMaterial({ color: 0xf1f1aa })
const cube = new three.Mesh(geometry, material)
scene.add(cube)
camera.position.z = 5
- 形状。一个几何立体形状
- 材质。一个内置的普通材质
- 物体。创建物体对象
- 添加到场景
- 移动相机。任何物体在场景的初始位置都是(0, 0, 0),包括相机,所以移动一下相机,不然看不到这个物体,当然,你也可以不移动相机,而去移动物体,这样
// camera.position.z = 5
cube.position.z = -5
渲染动画
function animate() {
requestAnimationFrame(animate)
cube.rotation.x += 0.1
cube.rotation.y += 0.1
renderer.render(scene, camera)
}
animate()
你将看到一个不断旋转的立方体。
rotation
是旋转属性
renderer.render()
是一次性的渲染器
requestAnimationFrame(callback)
是属于window
的,辅助渲染动画的一次性方法。
- 因为一次性,所以需要将你的动画函数,传入它的回调参数,且每次都要调用它,以达到不断变化的动画效果。
- 我认为它和定时器的功能差不多,我进行尝试过
function animate() {
cube.rotation.x += 0.1
cube.rotation.y += 0.1
renderer.render(scene, camera)
}
setInterval(() => {
animate()
}, 20);
不过它是js内置的用来专门渲染动画的,使用requestAnimationFrame()
肯定更好
完整示例
import * as three from 'three'
const scene = new three.Scene()
const camera = new three.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
const renderer = new three.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.append(renderer.domElement)
const geometry = new three.BoxGeometry(1, 1, 1)
const material = new three.MeshBasicMaterial({ color: 0xf1f1aa })
const cube = new three.Mesh(geometry, material)
scene.add(cube)
camera.position.z = 5
function animate() {
requestAnimationFrame(animate)
cube.rotation.x += 0.1
cube.rotation.y += 0.1
renderer.render(scene, camera)
}
animate()