lil-gui

repository·main·Indexed 23 days ago

https://github.com/georgealways/lil-gui

A lightweight library for creating floating control panels on the web, designed as a drop-in replacement for dat.gui. It allows developers to expose object properties as interactive UI controllers, including checkboxes, buttons, text fields, number fields (with slider and stepping support), color pickers, and dropdown menus. Version 0.21.0 features support for folders, change event handlers, and save/load presets.

Tokens
3.6K
Snippets
15
Records
21
Agent score
76%

What's inside lil-gui

  1. Quickstart: Create a floating control panel with lil-gui

    main

    To use lil-gui, import the GUI class, instantiate it, and use the .add() method to attach properties from an object to the interface. lil-gui automatically detects the type of the property (Boolean, Function, String, or Number) and renders the appropriate controller (Checkbox, Button, Text Field, or Number Field).

    import GUI from 'lil-gui'; 
    
    const gui = new GUI();
    
    const myObject = {
    	myBoolean: true,
    	myFunction: function() { ... },
    	myString: 'lil-gui',
    	myNumber: 1
    };
    
    gui.add( myObject, 'myBoolean' );  // Checkbox
    gui.add( myObject, 'myFunction' ); // Button
    gui.add( myObject, 'myString' );   // Text Field
    gui.add( myObject, 'myNumber' );   // Number Field
  2. Install lil-gui

    main

    You can install lil-gui via npm for use with bundlers, or use a CDN for quick sketches.

    NPM Installation:

    $ npm install lil-gui --save-dev

    ESM Import:

    import GUI from 'lil-gui';

    CDN (ESM):

    <script type="module">
    import GUI from 'https://cdn.jsdelivr.net/npm/lil-gui@VERSION/+esm';
    </script>

    CDN (UMD):

    <script src="https://cdn.jsdelivr.net/npm/lil-gui@VERSION"></script>
    <script>
    var GUI = lil.GUI;
    </script>
    $ npm install lil-gui --save-dev
  3. Handle color controller changes in lil-gui

    main

    The primary difference in color handling is the expected RGB range. While dat.gui assumes a range of [0-255] for RGB objects/arrays, lil-gui uses the standard [0-1] range.

    Key differences:

    • lil-gui uses the native HTML input[type=color] tag instead of a custom picker.
    • lil-gui always writes to #rrggbb format for strings (even if input was rgb() or #RGB).
    • lil-gui does not support HSL or alpha color formats.

    Simplifying Three.js integration: If you are using three.js, you no longer need to manually convert hex values in an onChange handler because both libraries agree on the [0-1] RGB range.

    // Old dat.gui + three.js pattern
    params = { color: color.getHex() };
    
    dat_gui.addColor( params, 'color' ).onChange( v => {
        color.setHex( v )
    } );
    
    // New lil-gui + three.js pattern
    params = { color };
    
    lil_gui.addColor( params, 'color' );
  4. Migrate from dat.gui to lil-gui

    main
    For most projects, migrating from dat.gui to lil-gui is as simple as updating the import URL. The API is designed for backwards compatibility, but you must address several breaking changes regarding internal property names, folder management, and removal methods.
  5. Customize lil-gui styling

    main

    Container and Width

    By default, the GUI is attached to document.body at the top right. You can specify a different container or a custom width in the constructor.

    const gui = new GUI( { container: $( '#gui' ), width: 400 } );

    CSS Variables

    You can customize the appearance using CSS variables on the .lil-gui class:

    • --width: Sets the panel width.
    • --name-width: Sets the width of the controller names.
    • --background-color: Sets the background.
    • --widget-color: Sets the widget color.
    • --padding: Sets the padding.
    .lil-gui { 
    	--width: 400px;
    	--name-width: 65%;
    	--background-color: #000;
    }

    Touch Styles

    lil-gui applies larger touch-friendly styles via @media (pointer: coarse). To disable this, use touchStyles: false in the constructor, or manually add the .force-touch-styles class to the GUI's root element.

    const gui = new GUI( { container: $( '#gui' ) } );
  6. Use color pickers with different color formats

    main

    Use the .addColor() method to create color pickers. lil-gui supports several color formats, including hex strings, integer hex values, RGB objects, and RGB arrays.

    const colorFormats = {
    	string: '#ffffff',
    	int: 0xffffff,
    	object: { r: 1, g: 1, b: 1 },
    	array: [ 1, 1, 1 ]
    };
    
    gui.addColor( colorFormats, 'string' );
  7. Configure number fields with sliders and stepping

    main

    You can transform a standard number field into a slider by providing min and max values as additional arguments to .add(). You can also specify a step value to control snapping (e.g., snapping to even numbers).

    // Add sliders to number fields by passing min and max
    gui.add( myObject, 'myNumber', 0, 1 );
    
    // Add slider with step (snap to even numbers)
    gui.add( myObject, 'myNumber', 0, 100, 2 );
  8. Save and Load GUI presets

    main

    Use gui.save() to create a JSON-compatible object containing the current values of all controllers. Use gui.load(data) to restore them.

    Important Notes:

    • Name Collisions: save() will throw an error if multiple controllers or folders share the same name. Use .name('unique_name') to avoid this.
    • Recursion: Both methods accept a recursive boolean parameter (default true). If false, folders are ignored.
    • Format: The saved object contains controllers and folders keys.
    let preset = {};
    
    const obj = {
    	value1: 'original',
    	value2: 1996,
    	savePreset() {
    		preset = gui.save();
    	},
    	loadPreset() {
    		gui.load( preset );
    	}
    };
    
    gui.add( obj, 'value1' );
    gui.add( obj, 'value2' );
    gui.add( obj, 'savePreset' );
    let preset = {};
    
    const obj = {
    	value1: 'original',
    	value2: 1996,
    	savePreset() {
    		// save current values to an object
    		preset = gui.save();
    		loadButton.enable();
    	},
    	loadPreset() {
    		gui.load( preset );
    	}
    }
    
    gui.add( obj, 'value1' );
    gui.add( obj, 'value2' );
    
    // ...
  9. Add controllers to a GUI

    main

    Use gui.add(object, propertyName) to create a controller. lil-gui automatically selects the appropriate input type based on the property's data type:

    • Boolean: Checkbox
    • String: Text field
    • Number: Number field
    • Function: Button
    const gui = new GUI();
    const obj = {
    	myBoolean: true,
    	myString: 'lil-gui',
    	myNumber: 1,
    	myFunction: function() { alert( 'hi' ) }
    };
    
    gui.add( obj, 'myBoolean' );
    gui.add( obj, 'myString' );
    gui.add( obj, 'myNumber' );
    gui.add( obj, 'myFunction' );
    const gui = new GUI();
    gui.add( document, 'title' );
  10. Handle change events

    main

    Controller-specific events

    • .onChange(callback): Fires every time the value changes. The new value is passed to the callback.
    • .onFinishChange(callback): Fires after a controller changes and loses focus (useful for expensive operations triggered by sliders).
    gui.add( params, 'foo' ).onChange( value => {
    	console.log( value );
    } );

    Global change handlers

    You can attach handlers to the root GUI or a Folder. These events bubble up. The callback receives an event object containing:

    • event.object: The object that was modified.
    • event.property: The name of the property (string).
    • event.value: The new value.
    • event.controller: The controller instance that was modified.
    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
    } );
  11. Organize controllers with Folders

    main

    Use addFolder(name) to create a collapsible group. The method returns a new GUI instance representing the folder, to which you can add controllers.

    const folder = gui.addFolder( 'Position' );
    folder.add( obj, 'x' );
    folder.add( obj, 'y' );
    folder.add( obj, 'z' );
    // 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' );
  12. Use color pickers with addColor()

    main

    Use gui.addColor() to create a color picker. It supports CSS strings, RGB objects, or integer hex values.

    Note on RGB Objects/Arrays: When controlling objects like { r: 0, g: 0, b: 0 } or arrays like [0, 0, 0], lil-gui modifies the components in place without replacing the object/array. By default, channels are assumed to be between 0 and 1. You can override this range by passing a third parameter to addColor().

    obj = { colorObject: { r: 0.667, g: 0, b: 1 }, colorArray: [ 0.667, 0, 1 ] }
    
    gui.addColor( obj, 'colorObject' );
    gui.addColor( obj, 'colorArray' );
    
    // With custom range (e.g. 0-255)
    obj = { colorObject: { r: 170, g: 0, b: 255 } }
    gui.addColor( obj, 'colorObject', 255 );
    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' );