Three.js学习7:dat.GUI 参数控制

每个学 Three.js 的都被安利了 dat.GUI 吧?

我也不例外!

今天就来了学习下 dat.GUI,并记录下来自己的学习成果。

一、什么是 dat.GUI?

dat.GUI 是一个轻量级的图形用户界面库(GUI 组件),使用这个库可以很容易地创建出能够改变代码变量的界面组件。

官网:https://github.com/dataarts/dat.gui

国内地址:GitCode - 开发者的代码家园

Three.js 每个官方的案例都有这个面板,用于参数调试。

二、引入方式

从官网下载 dat.gui-master.zip,解压后,在 build 目录看到相关文件,用的就是它们。

1. script 标签方式

javascript 复制代码
<script src="js/gui/dat.gui.min.js"></script>
<script>
  const gui = new dat.GUI();
</script>

2. npm 安装

bash 复制代码
$ npm install --save dat.gui
javascript 复制代码
// CommonJS:
const dat = require('dat.gui');

// ES6:
import * as dat from 'dat.gui';

三、创建 GUI 对象

javascript 复制代码
const gui = new dat.GUI();

此时,我们在页面就有了一个 GUI 面板,不过此刻面板里什么都没有。

四、参数控制

主要用到的方法是:

  • gui.add()

  • gui.addColor()

它们都会返回一个参数控制对象。

1. 数值参数控制

javascript 复制代码
gui.add(object, attr, min, max, step);

添加某个参数的控制块。其参数含义:

  • object必须。要控制的对象。

  • attr必须。控制对象的某个参数。

  • min,max:数值的最小值和最大值。它们必须同时存在。可选。

  • step:步进。即拖动下,数据改变多少。可选。

javascript 复制代码
let ctrl = gui.add(obj, attr);   // input 型,有一个输入框
let ctrl = gui.add(obj, attr, 1, 100);  // 拖动滑块型。最小,最大值
let ctrl = gui.add(obj, attr, 1, 100, 1);  // 拖动滑块型。最小,最大值,步进

或者
let ctrl = gui.add(obj, attr).min(1).max(100).step(1);

2. 颜色参数控制

javascript 复制代码
gui.addColor( object, attr);

针对颜色的参数设置。

  • object必须。要控制的对象。

  • attr必须。控制对象的某个颜色型属性。

GUI提供了4种颜色值类型的控件(CSSRGBRGBAHue ),四种类型均使用 gui.addColor()添加。

javascript 复制代码
var palette = {
  color1: '#FF0000', // CSS string
  color2: [ 0, 128, 255 ], // RGB array
  color3: [ 0, 128, 255, 0.3 ], // RGB with alpha
  color4: { h: 350, s: 0.9, v: 0.3 } // Hue, saturation, value
};
gui.addColor(palette, 'color1');
gui.addColor(palette, 'color2');
gui.addColor(palette, 'color3');
gui.addColor(palette, 'color4');

3.下拉框参数控制

下拉框控件既可以是数字类型 ,也可以是字符串类型 ,它们都是通过 gui.add() 方法进行配置。

javascript 复制代码
gui.add(object, attr, array/object );
  • object必须。要控制的对象。

  • attr必须。控制对象的某个属性。

  • array : 字符串类型配置; object:数字类型配置。

javascript 复制代码
 gui.add( obj, "addr", ["北京","上海","天津"] );
javascript 复制代码
gui.add( obj, "speed", {
     "fast":1,
     "normal":2,
     "slow":3
} );

4. 单选框参数控制

首先,要保证对应的属性值为 true/false 布尔值 。利用 gui.add() 方法,自然会形成单选框。

javascript 复制代码
gui.add(object, attr)
  • object必须。要控制的对象。

  • attr必须 。控制对象的某个属性。其值必须为布尔值

javascript 复制代码
gui.add(obj, "isCenter");

5. 添加/删除菜单文件夹

javascript 复制代码
// 添加文件夹
let f = gui.addFolder( folderName )
// 给文件夹添加参数控制
f.addColor( obj, attr )
// 删除文件夹
gui.removeFolder(f)

例如:

javascript 复制代码
let obj = {
    "fontSize": 30,
    "color" : "#ff0000",
    "isCenter": true,
    "addr":"北京",
    "speed": 1
}
// 创建 GUI 面板。
const gui = new dat.GUI();
// 创建文件夹
let f = gui.addFolder("文字设置");
f.add(obj, "fontSize", 1, 100, 1);
f.addColor(obj, "color");
f.open();
let f2 = gui.addFolder("其他");
f2.add(obj, "addr", ["北京","上海","天津"]);
f2.add(obj, "isCenter");

6. 事件

修改参数后,能执行什么操作?

对于面板中的每一个控制项,可以设置 onChangeonFinishChange 监听事件。

  • onChange:控制项值改变时响应,比如拖动滑块过程中。

  • onFinishChange:控制项值改变完毕后相应。

**注意:**这两个事件本质是 gui 定义的对象方法,不能通过 addEventListener 添加。

javascript 复制代码
f.add(obj, "fontSize", 1, 100, 1);
f.onChange(function(value){     // value 就是改变后的值
    console.log("onChange:" + value)
});
f.onFinishChange(function(value){     // value 就是改变后的值
    console.log("onFinishChange:" + value)
});

// 也可以直接链式操作。
f.add(obj, "fontSize", 1, 100, 1).onChange(function(value){     // value 就是改变后的值
    console.log("onChange:" + value)
});

五、其他功能

1. 折叠,展开,隐藏,显示

javascript 复制代码
gui.close();  // gui折叠
f.close();    // 文件夹折叠

gui.open();  // gui展开
f.open();    // 文件夹展开

gui.hide();  // 隐藏
f.hide();

gui.show();  // 显示
f.show();

2. 获取设置值

javascript 复制代码
ctrl.getValue() 
ctrl.setValue(newValue)
javascript 复制代码
const one=gui.add(options, 'color5');
one.setValue('333')
console.log(one.getValue());//333

3. 刷新控制器

刷新此控制器的视图显示,以便与对象的当前值保持同步。

javascript 复制代码
const options = {
    color5: 'xxxx',
    speed: 40,
    types: 'two'
};
const gui = new dat.GUI();
let num = gui.add(options, 'speed', 10, 20, .1);
options.speed=12
// 比如直接修改对象,然后更新
gui.updateDisplay()

六、示例:用 GUI 控制某个标签的样式

要利用 GUI 控制某个标签的样式。

javascript 复制代码
<h1 id="box">你好,这是 GUI 测试示例。</h1>

<script src="js/gui/dat.gui.js"></script>
<script>
let box = document.getElementById("box");
// 要修改参数的对象。
let obj = {
    "fontSize": 30,
    "color" : "#ff0000",
    "isCenter": true
}
// 修改 h1 样式
box.style.cssText = `
    font-size:30px;
    color:#ff0000;
    text-align:center;
`;
</script>

添加 GUI 代码:

javascript 复制代码
// 创建 GUI 面板。利用 GUI 修改 h1 样式。
const gui = new dat.GUI();
// 创建文件夹
let f = gui.addFolder("文字设置");
let ctrl1 = f.add(obj, "fontSize", 1, 100, 1);
ctrl1.onChange(function(value){
    box.style.fontSize = value +"px"
});
f.addColor(obj, "color").onFinishChange(function(value){
    box.style.color = value ;
});
f.open();  // 默认第一个文件夹打开
// 创建文件夹2
let f2 = gui.addFolder("其他");
f2.add(obj, "addr", ["北京","上海","天津"]);
f2.add(obj, "isCenter").onFinishChange(function(value){
    if(value){
        box.style.textAlign = "center";
    }else{
        box.style.textAlign = "left";
    }
});

七、示例:跟 Three.js 结合

构建一个立方体,利用 dat.gui 控制网格的大小和格子数量;控制立方体的颜色和缩放。

html:

javascript 复制代码
<script type="importmap">
    {
        "imports":{
            "three":"./js/three.module.min.js",
            "three/addons/":"./js/jsm/",
            "dat":"./js/gui/dat.gui.module.js"
        }
    }
</script>
<script type="module" src="./js/myjs6.js"></script>

JS:

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import * as dat from 'dat';

// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color("#cccccc");

// 网格辅助器
let gridSize = 10;
let gridDivs = 10;
let gridHelper = new THREE.GridHelper(gridSize,gridDivs);
scene.add( gridHelper ); 

// 相机
let winH = window.innerHeight;
let winW = window.innerWidth;
const camera = new THREE.PerspectiveCamera(50, winW/winH, 1, 1000 );
camera.position.set(5,5,5);
camera.lookAt( scene.position );
scene.add(camera);

// 物体
const geometry = new THREE.BoxGeometry(1,1,1);
const material = new THREE.MeshBasicMaterial({
    color:"#ff3300"
});
const box = new THREE.Mesh( geometry, material );
scene.add( box );

// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(winW, winH);
renderer.render( scene, camera );
document.body.appendChild( renderer.domElement );

// 4. 渲染:不停的渲染
function animation() {
    renderer.render(scene, camera)
    requestAnimationFrame(animation)
  }
animation()

添加 dat.gui 控制:

javascript 复制代码
// gui 控制
const params = {
    gridParam:{
        size: 10,
        divsitions:10
    },
    boxParam:{
        color:"#ff3300"
    }
}
const gui = new dat.GUI();
// 网格控制
const folderGrid = gui.addFolder("网格控制");
folderGrid.add( params.gridParam, "size",10,100 ).onChange(function(value){
    scene.remove( gridHelper );  // 删除原有的网格
    // 添加新的网格
    gridSize = value;
    gridHelper = new THREE.GridHelper(gridSize,gridDivs);
    scene.add( gridHelper ); 
    renderer.render( scene, camera );
});
folderGrid.add( params.gridParam, "divsitions",5,100 ).onChange(function(value){
    scene.remove( gridHelper );  // 删除原有的网格
    // 添加新的网格
    gridDivs = value;
    gridHelper = new THREE.GridHelper(gridSize,gridDivs);
    scene.add( gridHelper ); 
    renderer.render( scene, camera );
});
folderGrid.open();
// box控制
const folderBox = gui.addFolder("立方体控制");
folderBox.add( box.scale,"x",1,10);
folderBox.add( box.scale,"y",1,10);
folderBox.add( box.scale,"z",1,10);
folderBox.addColor( params.boxParam,"color").onChange(function(value){
    material.color.set(value);
});
folderBox.open();
相关推荐
西岸行者12 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意12 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码12 天前
嵌入式学习路线
学习
毛小茛13 天前
计算机系统概论——校验码
学习
babe小鑫13 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms13 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下13 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。13 天前
2026.2.25监控学习
学习
im_AMBER13 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J13 天前
从“Hello World“ 开始 C++
c语言·c++·学习