lil-gui 界面库的基本用法

lil-gui 是一个可以在运行时修改 JavaScript 对象属性的界面库。相信用过 three.js 的同学对它一定不会陌生,three.js 的很多示例都用到了这个轻量的界面库修改三维场景的属性。我也是因为接触到 three.js 才打算学习一下这个库的。

下面通过一组例子总结 lil-gui 的基本用法

用这个库之前,需要实例化它的对象

const gui = new GUI();

1、属性类型和界面控件的对应关系

        const obj = {
            myBoolean: true,
            myString: 'lil-gui',
            myNumber: 1,
            myFunction: function() { alert( 'hi' ) }
        }

        gui.add( obj, 'myBoolean' ); 	// checkbox
        gui.add( obj, 'myString' ); 	// text field
        gui.add( obj, 'myNumber' ); 	// number field
        gui.add( obj, 'myFunction' ); 	// button

上面的例子用到了 gui.add 方法,该方法的函数签名如下所示:

gui.add(object, property, [$1], [max], [step])

             object: 目标对象

             property:目标对象上要修改的属性

             $1:数值属性的最小值或可选值列表

             max: 数值属性的最大值

             step:数值属性的步进

lil-gui 会根据要修改属性的数据类型选择合适的界面控件,主要数据类型对应的控件

  • 布尔值:checkbox
  • 字符串:text field
  • 数值:number field
  • 函数:button

2、指定最大值、最小值和步进量

        const obj = { hasMin: 0, hasMax: 100, hasStep: 60 }

        gui.add( obj, 'hasMin' ).min( 0 );
        gui.add( obj, 'hasMax' ).max( 100 );
        gui.add( obj, 'hasStep' ).step( 10 ); // 四舍五入到10的倍数

3、为数值属性提供滑块

同时设置数值的最大值和最小值,lil-gui会提供一个滑块

        const obj = { number1: 1, number2: 40 }

        gui.add( obj, 'number1', 0, 1, 0.1); // min, max, step
        gui.add( obj, 'number2', 0, 100, 10 ); // min, max, step

示例5:为属性提供可选值的下拉列表

下拉列表中的可选值可以用数组或者对象组织。用对象组织时,界面上显示的是对象中的键值。

        const obj = { size: 'Large', speed: 1 };

        gui.add( obj, 'size', [ 'Small', 'Medium', 'Large' ] );
        gui.add( obj, 'speed', { Slow: 0.1, Normal: 1, Fast: 5 } );

4、修改颜色属性

lil-gui 可以识别 CSS字符串 或 十六进制 数值表示的颜色,通过  addColor() 方法创建颜色选择器

        const obj = {
            color1: '#AA00FF',
            color2: '#a0f',
            color3: 'rgb(170, 0, 255)',
            color4: 0xaa00ff
        }

        gui.addColor( obj, 'color1' );
        gui.addColor( obj, 'color2' );
        gui.addColor( obj, 'color3' );
        gui.addColor( obj, 'color4' );

5、通过分量指定颜色初始值

可以通过 对象 或 数组 两种形式指定颜色初始值

        const obj = {
            colorObject: { r: 0.39215686274509803, g: 0.18823529411764706, b: 0.49411764705882355 },
            colorArray: [ 0.25098039215686274, 0.12549019607843137, 0.3137254901960784 ]
        }

        gui.addColor( obj, 'colorObject' );
        gui.addColor( obj, 'colorArray' );

6、修改颜色分量的范围

默认颜色分量在 [ 0, 1 ] 区间内,可以设置 addColor 方法的第三个参数将颜色分量扩展到 [ 0, 255 ]

        // 指定0-255范围的颜色值
        const obj = {
            colorObject: { r: 170, g: 0, b: 255 },
            colorArray: [ 170, 0, 255 ]
        };

        gui.addColor( obj, 'colorObject', 255 );
        gui.addColor( obj, 'colorArray', 255 );

 addColor 方法的函数签名如下所示

addColor( object, property, rgbScale=1 )

        object:目标对象

        property:目标对象中作为颜色的属性名称

        rgbScale:颜色通道的最大值,默认为1

7、为属性分组

        const obj = { 
            scale: 0.5,
            x: 1,
            y: 2,
            z: 3
        };
        // top level controller
        gui.add(obj, 'scale', 0, 1);

        // nested controllers
        const folder = gui.addFolder('Position');
        folder.add(obj, 'x');
        folder.add(obj, 'y');
        folder.add(obj, 'z');

在界面上,将 obj 对象的 x、y、z 属性在界面上组织成名称为 Position 的可折叠分组

8、属性变化监听事件

有两种属性变化监听事件:onChange 和 onFinishChange 。它们的区别是 onChange 修改立即触发;onFinishChange 修改并失去焦点后触发。

onChange :

        const params = {
            foo: 'foo'
        };
        // 链式调用
        gui.add(params, 'foo').onChange(value => {
            // 修改后的新值
            console.log(value);
        });

onFinishChange :

        // 修改属性,界面控件失去焦点时才触发
        const params = {
            foo: 'foo'
        };
        gui.add(params, 'foo').onFinishChange(value => {
            // 修改后的新值
            console.log(value);
        });

9、全局的属性变化监听事件

除了针对对象上具体属性的监听方式外,lil-gui 还提供全局的监听方式。任何属性的变化都会触发它们。

全局 onChange :

        gui.onChange(event => {
            /*
                // event.object     // object that was modified
                // event.property   // string, name of property
                // event.value      // new value of controller
                // event.controller // controller that was modified
            */
            console.log(event.object);
            console.log(event.property);
            console.log(event.value);
            console.log(event.controller);
            
        });

        const params1 = {
            foo: 'foo'
        };
        gui.add(params1, 'foo');

        const params2 = {
            bar: 'bar'
        };
        gui.add(params2, 'bar');

全局 onFinishChange :

        gui.onFinishChange(event => {
            console.log(event.object);
            console.log(event.property);
            console.log(event.value);
            console.log(event.controller);
            // event.object     // object that was modified
            // event.property   // string, name of property
            // event.value      // new value of controller
            // event.controller // controller that was modified
        });

        const params1 = {
            foo: 'foo'
        };
        gui.add(params1, 'foo');

        const params2 = {
            bar: 'bar'
        };
        gui.add(params2, 'bar');

10、界面外部修改属性值的情况

通过界面外的方式修改了属性值,lil-gui并不会做出响应。这时可以用 listen 方法监听属性值在界面外的变化,并在界面上更新

        const params = {
            feedback: 0,
        };
        gui.add( params, 'feedback', -1, 1 ).listen();

        document.getElementById('test').onclick = function () {
            params.feedback = 0.5;
        };

11、保存界面上的属性值

gui.save 将当前界面上的属性值保存到一个对象中,以 JSON 对象的形式存储

        let preset = {};

        const obj = {
            value1: 'original',
            value2: 1996,
            savePreset() {
                // 保存当前值到一个对象中
                preset = gui.save();
                loadButton.enable();
            },
            loadPreset() {
                // gui.load 将通过 gui.save保存的对象重新加载到界面上
                gui.load(preset);
            }
        }

        gui.add(obj, 'value1');
        gui.add(obj, 'value2');

        gui.add(obj, 'savePreset');

        const loadButton = gui.add(obj, 'loadPreset');
        loadButton.disable();

12、处理属性名称冲突

界面上有相同的属性名时,用 gui.save 会报名称冲突的错误。这时可以用 name 方法改名可以避免这个问题

        const position = {
            x: 1
        };
        const rotation = {
            x: 2
        };
        // gui.add( position, 'x' );
        // gui.add( rotation, 'x' );
        // 避免两个对象中的 x 同名
        gui.add(position, 'x').name('position.x');
        gui.add(rotation, 'x').name('rotation.x');

        const obj = {
            savePreset() {
                preset = gui.save();
                loadButton.enable();
            },
            loadPreset() {
                gui.load(preset);
            }
        };

        let preset = {};

        gui.add(obj, 'savePreset');

        const loadButton = gui.add(obj, 'loadPreset');
        loadButton.disable();

13、改变面板的位置

默认情况下面板是位于页面右上角的,实际应用中可能由于界面元素冲突需要调整面板的位置。

在实例化的时候设置 autoPlace 属性为 false,然后指定 CSS 进行修改即可

      const gui = new lil.GUI({
        autoPlace: false
      });

      const guiWrapper = document.createElement("div");
      guiWrapper.style.position = "absolute";
      guiWrapper.style.left = "15px";
      guiWrapper.style.top = "0";
      guiWrapper.style.zIndex = 1001;
      guiWrapper.appendChild(gui.domElement);
      document.body.appendChild(guiWrapper);

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值