基本API的使用方式
根据官网的文档整理出一份API文档, 地址是:ThreeJs 官网文档,其目的还是为了方便查阅
下列代码源码地址
// 此处表示导入three
import * as THREE from 'three';
// 1. 创建一个场景
const scene = new THREE.Scene();
// 2. 创建一个相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/ window.innerHeight, 0.1, 1000);
// 表示相机位置
camera.position.set( 0, 0, 10 );
scene.add( camera );
// 3. 添加物体
const geometry = new THREE.BoxGeometry( 1, 1, 1 ); // 表示几何体
const material = new THREE.MeshBasicMaterial({color: 0x00ff00}); // 表示材质
const cube = new THREE.Mesh(geometry, material); // 根据几何体 以及材质 创建物体
scene.add( cube );
// 4. 初始化渲染器
const renderer = new THREE.WebGL1Renderer();
renderer.setSize( window.innerWidth, window.innerHeight ); // 设置渲染的尺寸大小
// 将canvas 添加到html中
document.body.appendChild(renderer.domElement);
// 通过渲染器 通过相机将场景进行渲染
renderer.render( scene, camera );
API 列表
- OrbitControls 轨道控制器 以及如何开启惯性
- AxesHelper 添加坐标辅助线
- position.set 物体移动
- scale.set/ rotation.set 物体的旋转以及缩放
- Clock 来获取执行时间 控制匀速移动
- GSAP 使用插件来设置动画
- 监听window尺寸发生变化,渲染renderer 也发生变化
- js 控制 渲染页面进入全屏模式 以及退出全屏模式
- 通过插件实现图形界面修改变量
- 通过【Texture】实现纹理贴图
API 书写代码
OrbitControls
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 5. 创建轨道控制器
const orbitControls = new OrbitControls(camera, renderer.domElement);
// 此属性表示开启阻尼(惯性)
orbitControls.enableDamping = true;
const render = () => {
orbitControls.update();
// 通过渲染器 通过相机将场景进行渲染
renderer.render( scene, camera );
requestAnimationFrame( render );
};
render();
AxesHelper
// 添加坐标轴辅助线
const axesHelper = new THREE.AxesHelper(5);
scene.add( axesHelper );
position.set
const geometry = new THREE.BoxGeometry( 2, 2, 2 ); // 表示几何体
const material = new THREE.MeshBasicMaterial({color: 0x00ff00}); // 表示材质
const cube = new THREE.Mesh(geometry, material); // 根据几何体 以及材质 创建物体
cube.position.set(5, 0, 0); // 通过API【set】 来设置xyz轴数据
cube.position.x = 5; // 单独设置某个轴的数据
scale.set/ rotation.set 物体的旋转以及缩放
跟上述position 类似。
// 物体缩放
cube.scale.set( 3, 2, 1 );
// 物体旋转 Math.PI 表示180度
cube.rotation.set(Math.PI / 4, 0, 0);
Clock
如果我们通过js设置动画的话,为了能够让动画相对平滑,我们会使用
requestAnimationFrame
. 但是ThreeJs 内部给我们提供了API,来 我们获取时间
const clock = new THREE.Clock();
// 通过requestAnimationFrame 来渲染下一帧
const render = () => {
const time = clock.getElapsedTime();
cube.position.x = time % 5 * 1;
// 通过渲染器 通过相机将场景进行渲染
renderer.render( scene, camera );
requestAnimationFrame( render );
};
render();
GSAP 插件
我们可以通过计算时间平均值来设置动画速度,使动画移动相对平滑。但是有插件【gsap】帮助我们实现这些方法。可以查看文档gsap
gsap.to
第一个参数
作用于的动作duration
花费时间ease
执行速度repeat
执行次数。如果是-1
永远不会停止yoyo
是否往返onStart
动画执行开始时间onComplete
动画执行结束时间
import {gsap} from 'gsap';
// 添加移动动画
const animation01 = gsap.to(cube.position, {
// 表示位置移动方向
x: 5,
// 表示花费时间
duration: 5,
ease: "power1.inOut",
// 执行次数
repeat: -1,
// 表示是否往返
yoyo: true,
// 动画开始方法
onStart() {
console.log("动画移动开始");
},
// 动画结束的方法
onComplete: function ( ) {
console.log("动画 移动结束");
}
});
// 添加旋转动画
const animation02 = gsap.to(cube.rotation, {
x: 2 * Math.PI,
duration: 5,
repeat: -1,
yoyo: true,
onStart: function ( ) {
console.log("旋转动画开始了");
},
onComplete: function ( ) {
console.log("旋转动画结束了");
}
});
// 暂停/ 启动 判断
window.addEventListener("dblclick", () => {
if (animation01.isActive())
animation01.paused(true );
else
animation01.resume();
if (animation02.isActive())
animation02.paused(true );
else
animation02.resume();
})
监听window尺寸发生变化,渲染renderer 也发生变化
- 其实我们能看到的内容大小 都是摄像机视锥体比例决定的。 所以如果窗口大小发生了变化,视锥体比例也应该发生变化
- 因为window尺寸发生了变化,所以渲染器的 size也应该发生变化
// 表示根据window尺寸 来进行渲染自适应
window.addEventListener("resize", function ( ) {
// 更新 摄像机视锥体长宽比
camera.aspect = window.innerWidth / window.innerHeight;
// 更新 摄像机投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器
renderer.setSize( window.innerWidth, window.innerHeight );
// 设置渲染器的像素比
renderer.setPixelRatio(window.devicePixelRatio);
})
js 控制 渲染页面进入全屏模式 以及退出全屏模式
// 表示双击 全屏 以及退出全屏
window.addEventListener("dblclick", async () => {
// 判断是否全屏。 设置全屏 以及退出全屏
const isFullScreen = document.fullscreenElement;
if (!isFullScreen) {
await renderer.domElement.requestFullscreen();
} else {
await document.exitFullscreen();
}
})
通过插件实现图形界面修改变量
实现的效果如下图的右上角部分
import dat from 'dat.gui';
// 添加图形界面
const gui = new dat.GUI();
// 添加属性 变换
gui.add( cube.position, 'x', 1, 5, 0.1 ).name("物体 x");
// 添加颜色变换
gui.addColor({color: "#00ff00"}, "color").name("物体 color").onChange(color => {
cube.material.color.set(color);
});
// 设置是否显示
gui.add( cube, 'visible' ).name("是否显示");
// 将几何体 渲染为线框
gui.add( cube.material, 'wireframe' ).name("线框显示");
// 添加文件夹
const folder = gui.addFolder("my folder");
folder.add( cube.material, 'wireframe' ).name("线框显示");
- 上述是现在实现的部分逻辑,更详细的可以参照API
通过【Texture】实现纹理贴图
可以将纹理 理解为几何体上的一个壁纸,也可以理解为一个普通div的背景图片等
// 添加纹理
const texture = new THREE.TextureLoader().load("images/3d.png");
// 设置偏移量
// texture.offset.set(0.5, 0.5);
// 设置旋转角度
// texture.rotation = Math.PI / 4;
// 设置旋转的中心点
texture.center.set(0.5, 0.5);
// 设置重复次数
texture.repeat.set(2, 2);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
const material = new THREE.MeshBasicMaterial({
color: 0xffff00,
map: texture,
});