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 传递第三个参数(选项数组) 下拉列表
相关推荐
程序员_三木17 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
MossGrower3 天前
36. Three.js案例-创建带光照和阴影的球体与平面
3d图形·webgl·three.js·光照与阴影
MossGrower3 天前
34. Three.js案例-创建球体与模糊阴影
webgl·three.js·3d渲染·阴影效果
广东数字化转型3 天前
Three.js相机Camera控件知识梳理
3d·three.js
关山月4 天前
9个学习着色器的GLSL示例
前端·three.js
程序员_三木4 天前
Three.js资源-贴图材质网站推荐
javascript·webgl·three.js·材质·贴图
MossGrower5 天前
37. Three.js案例-绘制部分球体
3d图形·webgl·three.js·球体几何体
关山月5 天前
如何使用Three.js创建3D音频可视化工具
前端·three.js
MossGrower6 天前
35. Three.js案例-创建带阴影的球体与平面
webgl·three.js·阴影·球体
MossGrower7 天前
28. Three.js案例-创建圆角矩形并进行拉伸
3d图形·webgl·three.js·圆角矩形