3. Three.js边角知识

代码地址

1.坐标轴辅助器

我们在设置场景中对象的位置时,往往会参考坐标轴来进行设置。但是我们创建的场景中却没有可见的坐标轴供我们参考,从而降低我们的编码效率。

为此我们可以通过AxesHelper类,来简单模拟3个坐标轴的对象。该类的构造函数接收一个参数,此参数为轴线段的长度。

js 复制代码
import { AxesHelper } from 'three';

const axes = new AxesHelper(5)

其中红色线代表X轴,绿色线代表Y轴,蓝色线代表Z轴。

2.设置物体的位置

我们可以通过调用物体position属性上的set方法来控制物体的位置。

js 复制代码
cube.position.set(2, 0, 0);
cube.position.set(0, 2, 0);
cube.position.set(0, 0, 2);

除此之外我们还可以通过直接修改对应属性上的属性值来控制物体的位置。

js 复制代码
cube.position.x = 2;
cube.position.y = 2;
cube.position.z = 2;

我们可以通过浏览器关键帧的调用来实现一些简单的动画。

js 复制代码
function animetion(time) {
  cube.position.x += 0.01;
  if (cube.position.x >= 5) {
    cube.position.x = 0;
  }
  renderer.render(scene, camera);
  requestAnimationFrame(animetion);
}

3.控制物体平移、旋转、缩放

js 复制代码
cube.translateX(2); // 向X轴正方向平移两个单位
cube.rotation.set(Math.PI / 4, 0, 0); // 沿X轴旋转45°
cube.scale.set(2, 1, 1); // 将物体的沿X轴方向扩大两倍

4.Gsap动画库

GSAP(GreenSock Animation Platform)是一个流行的JavaScript动画库,用于创建高性能和平滑的Web动画效果。GSAP提供了丰富的功能和易用的API,使开发者能够轻松地创建各种类型的动画,包括缓动、时间线、滚动动画等。

npm 复制代码
npm install gsap

基本使用

我们可以通过gsapto方法来做动画,我们需要给该方法传递两个参数。第一个参数为目标,第二个参数为动画信息的vars对象。

js 复制代码
gsap.to(cube.position, { x: 10, duration: 5 });

上面这段代码的意思就是,将cube的对象的position属性从当前的位置移动到x坐标为10的位置,动画的持续时间为5秒。

除了可以做位置属性的动画之外,还可以做颜色、透明度、旋转等属性的动画。

js 复制代码
gsap.to(cube.rotation, { x: Math.PI, duration: 5 });

上面示例中是cube的对象的rotation属性从当前的旋转状态旋转到180°,并且动画的持续时间为5秒。

特殊属性

要调整补间的行为方式,我们可以传递一些特殊属性。

属性 默认值 说明
duration 0.5 动画的持续时间(秒)。
delay ------ 动画开始之前的延时时间(秒)。
repeat ------ 动画应重复多少次。
yoyo flase 如果为true,则每隔一个重复的补间就会朝相反方向运行。(像溜溜球)
stagger ------ 每个目标动画开始之间的时间(以秒为单位)(如果提供了多个目标)。
ease "power1.out" 控制动画期间的变化率。

delay

js 复制代码
gsap.to(cube.position, {
  x: 10,
  duration: 5,
  delay: 3, // 动画开始前延迟3秒
});

repeat

js 复制代码
gsap.to(cube.position, {
  x: 10,
  duration: 5,
  repeat: 1, // 动画重复1次
  //repeat: -1 // 一直重复
});

yoyo

js 复制代码
gsap.to(cube.position, {
  x: 10,
  duration: 5,
  repeat: 1, // 动画重复1次
  yoyo: true, // 设置为true,就会每隔一个重复的补间就会朝相反方向运行
});

ease

关于运动曲线可以查看官方的可视化例子选择自己想要的效果。

js 复制代码
gsap.to(cube.position, {
  x: 10,
  duration: 5,
  // delay: 3, // 动画开始前延迟3秒
  // repeat: 1, // 动画重复1次
  // repeat: -1, //无限重复
  // yoyo: true, // 设置为true,就会每隔一个重复的补间就会朝相反方向运行
  ease: "power1.inOut",// 先快后慢
});

gaspto方法返回一个Tween对象,我们可以通过调用这个对象身上的方法,来控制动画。

js 复制代码
const animate = gsap.to(cube.position, {
  x: 10,
  duration: 5,
});

window.addEventListener("dblclick", () => {
  if (animate.isActive()) {// 是否活跃状态
    animate.pause();// 暂停动画
  } else {
    animate.resume();// 恢复动画
  }
});

gasp还提供了一系列的回调选项,允许你在动画的不同阶段执行特定的操作。

  • onComplete:动画执行完成后执行
  • onStart:动画启动时执行
  • onUpdate:动画的每一帧更新时执行
  • onRepeat:当动画重复时执行
  • onReverseComplete:当动画反向完成时执行的操作
  • ...

5.尺寸自适应

我们先将浏览器窗口缩小刷新页面,然后再将浏览器扩大化。我们就会发现渲染的尺寸并没全屏展示。

这是因为相机的纵横比和渲染器的大小以及像素比,没有随浏览器窗口的变化而变化。

js 复制代码
window.addEventListener("resize", () => {
  const width = window.innerWidth;
  const height = window.innerHeight;
  const pixelRatio = window.devicePixelRatio;

  // 更新摄像头
  camera.aspect = width / height;
  // 更新投影矩阵
  camera.updateProjectionMatrix();

  // 重新设置渲染器大小
  renderer.setSize(width, height);
  // 重新设置渲染器像素比
  renderer.setPixelRatio(pixelRatio);
});

6.dat.gui (控制面板)

dat.gui是一个用于创建图形用户界面 (GUI) 控件的JavaScript库,通常用于调整和控制代码中的参数和变量,以便在实时应用中进行交互性的调试和调整。它非常适合用于可视化应用、数据可视化、三维渲染等需要实时参数调整的场景。

three.js官网上的文档和案例中都有用到这个JavaScript库。它不但体积小,而且使用起来也很方便。

npm 复制代码
npm install dat.gui
js 复制代码
import * as dat from 'dat.gui';
const gui = new dat.GUI();

dat.gui中提供了许多GUI控件,常见的空间有滑块复选框文本框下拉列表颜色选择器按钮分组

1.滑块

我们可以通gui对象上的add方法添加控件

js 复制代码
gui.add(cube.position, 'x').min(0).max(10).step(0.01);

上示例中用于调整cube.position对象的x属性的值,并且限制了该值的最小值为0,最大值为10,并且设置了步进值为0.01,将以0.01的增量进行调整。

2.分组

我们可以通过gui对象的addFolder方法添加分组,该方法返回的是dat.gui.GUI。所以我们也可以通过add方法向分组中添加控件。

js 复制代码
// 创建分组
const cubePositionFolder = gui.addFolder("position");

// 准备分组参数
const cubePositionGuiParams = [
  { target: "x", min: 0, max: 10, step: 0.01, label: "x轴坐标" },
  { target: "y", min: 0, max: 10, step: 0.01, label: "y轴坐标" },
  { target: "z", min: 0, max: 10, step: 0.01, label: "z轴坐标" },
];

// 向分组中添加滑块控件
cubePositionGuiParams.forEach((params) => {
  const { target, min, max, step, label } = params;
  cubePositionFolder
   .add(cube.position, target)
   .min(min)
   .max(max)
   .step(step)
   .name(label);
});

3.颜色控件

gui对象上还有一个addColor的方法可以添加颜色控件。

js 复制代码
gui.addColor({ color: "#db0d0d" }, "color").onChange((value) => {
  cube.material.color.set(value);
});

上示例中的onChange函数在我们修改控件颜色时,会进行回调。这个回调接收一个参数value,即用户选择的颜色。

4.复选框

复选框控件还是通过add方法进行添加的

js 复制代码
// 添加cube显示隐藏和是否显示线框复选框控件
gui.add(cube, "visible");
gui.add(cube.material, "wireframe");

5.按钮

添加按钮控件的方法一样是add

js 复制代码
const cuebAnimates = {
  XAnimate: () => {
      gsap.to(cube.position, { x: 10, duration: 5, repeat: -1, yoyo: true });
  },
};

gui.add(cuebAnimates, "XAnimate");

6.文本框控件、选择列表

js 复制代码
const test = {
  text: "",
  option: "option1",
};
const options = ["option1", "options2", "option3"];
gui.add(test, "text").name("文本框");
gui.add(test, "option", options).name("下拉列表");

到这里我们会发现很多的控件都是通过调用guiadd方法来进行添加的。它好像能够根据我们传递的参数"聪明"的创建我们所需的控件一样。

其实如果你留心的话,就能从前面的案例中发现其中的"玄机"。实际上它采用了一种基于对象的属性值类型的方式来推断应该创建哪种类型的控件。

属性值类型 并且 对应的控件
number 指定了最小值(min)和最大值(max) 滑块
boolean ------ 复选框
function ------ 按钮
string | number ------ 文本框
any 传递第三个参数(选项数组) 下拉列表
相关推荐
格瑞@_@3 天前
11.Three.js使用indexeddb前端缓存模型优化前端加载效率
前端·javascript·缓存·three.js·indexeddb缓存
谢小飞3 天前
我做了三把椅子原来纹理这样加载切换
前端·three.js
小白菜学前端3 天前
ThreeJS创建一个3D物体的基本流程
3d·three.js
茶老翁4 天前
1-初识Three.js
前端·three.js
莫石6 天前
搓绳子(直)
前端·数学·three.js
小白菜学前端6 天前
3d 添加辅助坐标器和轨道控制器
3d·three.js
孙_华鹏8 天前
threejs——实战中材质的应用
前端·three.js·数据可视化
天涯学馆11 天前
Three.js灯光阴影与动画交互
前端·unity3d·three.js
格瑞@_@15 天前
6.Three.js贴图与uv映射(uv坐标)理解和实践
javascript·three.js·贴图·uv
入秋丶24 天前
threejs - 包围盒和包围球
three.js