threejs(六)lil-gui库的使用

945 阅读5分钟

1. 基本概念

GUI是图形用户界面(Graphical User Interface)的简写。

在官网介绍几何体的案例的时候,右上角会有一个操作区,该操作区即为Gui面板,更改操作区的参数,来改变对应几何体的属性,从而找到最适合的参数。

threejs中内置了一种Gui库(lil-gui官网),当然也可以选择常见的dat-gui库等,我们这里主要介绍lil-gui的用法,并在使用该工具的时候,再熟悉一下之前没有介绍到的一些材质和实例。

2. 使用方法

2.1 导入

无需重新安装库,直接从three库中找到后引入进来,如果不记得,就去可在node_modules中找找。

import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";

2.2 创建GUI

方法:

new GUI( { autoPlace, container, width, title, closeFolders, injectStyles, touchStyles, parent } )

该方法对应的各个对象的介绍:

属性类型默认值含义
autoPlacebooleantrue是否自动将 GUI 放置在页面中,并默认为右上角。如果设置为 false,则需要手动将 GUI 元素添加到页面中
containerHTMLElementdocument.body指定 GUI 的容器元素。如果未设置该参数,则默认将 GUI 添加到 document.body 中
widthnumber245设置 GUI 的宽度(以像素为单位)
titlestringControls设置 GUI 的标题
closeFoldersbooleanfalse是否默认折叠所有的文件夹(使用 addFolder() 方法创建的)
injectStylesbooleantrue是否自动注入 lil-gui 的默认样式表。将其设置为 false 可以自定义样式
touchStylesbooleantrue是否启用针对触摸设备的样式。这可以改善移动设备上的操作体验
parentlil-guinull指定一个父 GUI 实例。这样可以将当前 GUI 作为父 GUI 的子 GUI 添加(使用 addFolder() 方法创建的)
//使用默认值创建gui
const gui = new GUI({ 'title': "操作区" });

2.3 应用

2.3.1 搭建场景

在讲解用例之前,我们先搭建一个场景,场景中除了必要的场景参数外放置一个球,一个平面,一个聚光灯。

//相机
const camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000);
camera.lookAt(0,0,0)
camera.position.set(2,4,6)

//添加一个球
const sphereGe = new THREE.SphereGeometry(0.5)
const sphereMa = new THREE.MeshStandardMaterial({
    color:'#ff0000',
})
const sphereMesh = new THREE.Mesh(sphereGe,sphereMa)
sphereMesh.position.y=1
scene.add(sphereMesh)
sphereMesh.castShadow = true

//添加一个平面
const planeGe = new THREE.PlaneGeometry(2,3)
const planeMa = new THREE.MeshPhongMaterial({
    color: 0xff0F8f,
})
const planeMesh = new THREE.Mesh(planeGe,planeMa)
planeMesh.rotation.x = -0.5 * Math.PI
planeMesh.receiveShadow = true
scene.add(planeMesh)

//添加一个聚光灯
const light = new THREE.SpotLight(0xffffff,20)
light.position.set(2,3,2)
light.angle = 65 / 180 * Math.PI
scene.add(light)
light.castShadow = true
scene.add(new THREE.SpotLightHelper(light))
scene.add(new THREE.AmbientLight(0xffffff,0.2))
场景效果图

补充说明:这里我们展示了聚光灯和照射的阴影效果,要给灯光加上light.castShadow = true、平面接受阴影投射planeMesh.receiveShadow = true、球体网格对象 sphereMesh.castShadow = true 设置为可以投射阴影的属性,才会投射阴影。还有就是注意这里球体和平面的属性需要受到光照的影响,可设置为MeshPhongMaterial或者MeshStandardMaterial

2.3.2 常用方法列举

gui常用的方法列举如下:

  1. add(object, property, [min, max, step]) : 添加一个新的控制元素。object 是要控制的对象, property 是对象的属性名。可以额外指定数值类型属性的最小值、最大值和步长。
  2. addColor(object, property) : 添加一个颜色选择器控制元素。
  3. addFolder(title) : 创建一个可折叠的文件夹,用于组织相关的控制元素。
  4. addButton(title, callback) : 添加一个按钮控制元素。点击按钮时会执行 callback 函数。
  5. addSeparator() : 添加一个分隔线,用于分隔不同的控制元素组。
  6. onChange(callback) : 注册一个全局的变更事件监听器。当任何控制元素的值发生变化时,会调用 callback 函数。
  7. onFinishChange(callback) : 注册一个全局的变更完成事件监听器。当用户完成某个控制元素的值的修改时,会调用 callback 函数。
  8. open()  和 close() : 展开或折叠整个 GUI 控制面板。
  9. destroy() : 销毁 lil-gui 实例,移除所有的控制元素和事件监听器。

2.3.3 addColor()、add()

//设置一组对象,添加对应的默认值
const obj = {
    color: '#ff0000',
    speed: 2.5,
    isVisible: false
};
//添加颜色选择器,默认色值为'#ff0000'
gui.addColor(obj,'color');
//添加一个数值滑块,取值范围为 0 到 10,步长为 0.2,默认值为2.5
gui.add(obj,'speed',0,10,0.2);
//添加一个复选框控制器
gui.add(obj, 'isVisible');

在上述代码添加进去后,我们可以看到的效果如下所示:

2.png

出现右上角的操作区。color色值能更改,speed也能按照步长0.2滑动,isVisible也能勾选。但是并未与图中场景的元素进行关联,所以我们这里需要用到onChange()

//将色值与球的材质进行关联
gui.addColor(obj,'color').onChange((value)=>{
    sphereMa.color.set(value);
});
//是否可见与平面的显示关联
gui.add(obj,'isVisible').onChange((value)=>{
    if(value) scene.add(planeMesh)
    else scene.remove(planeMesh)
});

2.3.4 addFolder()

当我们需要对多个实例对象进行操作的时候,需要区分一下工作区。通过close()可以让指定的文件夹进行折叠。

//创建文件夹,区分sphere的操作区、camera操作区、light操作区
const sphereFol = gui.addFolder('球')
sphereFol.add(sphereMesh.position,'x',-5,5)
sphereFol.add(sphereMesh.position,'y',-5,5)
sphereFol.add(sphereMesh.position,'z',-5,5)

const cameraFol = gui.addFolder('相机')
cameraFol.add(camera.position,'x',-5,5)
cameraFol.add(camera.position,'y',-5,5)
cameraFol.add(camera.position,'z',-5,5)

const lightFol = gui.addFolder('灯光')
lightFol.add(light.position,'x',-5,5)
lightFol.add(light.position,'y',-5,5)
lightFol.add(light.position,'z',-5,5)
//灯光选项默认折叠
lightFol.close()

2.3.5 下拉选择

按照这样的方法更改后,即可与场景中的实例关联上。那如果要展示一个下拉框,该如何去实现呢

const folder = gui.addFolder('下拉选择');
const availableOptions = ['苹果🍎','香蕉🍌','橘子🍊','蓝莓🫐'];
const controller = folder.add(obj,'selectedOptions',availableOptions).name('选项');
controller.onChange((value)=> {
     alert('选择的是:'+value);
});

效果如下所示,可进行下拉选择操作。

select.png

3. 案例

看下完整的代码吧。

4. 总结

lil-gui库为threejs内置的库,体积小,简单易用。总的来说,使用gui 面板能够大大提高应用程序的可用性、可访问性和用户体验,是现代应用程序设计的重要组成部分。gui 面板的可视化效果有助于发现数据中的模式和趋势,提高数据分析的效率,通过图形化的展示和交互方式,用户可以更直观地掌握应用程序的状态和功能,提高工作效率。