Perfect GUI

A nice, simple and (probably not) perfect GUI for JavaScript.

See code

Options

label (string)

Label displayed at the top of the panel.

const gui = new GUI({ label: 'Basics' });

draggable (boolean)

Determines whether the panel can be moved manually.
Default is false.

const gui = new GUI({ draggable: true });

container (string|HTMLElement)

Parent element of the panel. Can be a string selector or a DOM element.
Default is document.body.

const gui = new GUI({ container: '.container' });

position (string)

GUI instances can be positioned in any corner of the screen / container.
When multiple instances share the same position (like GUI 1 and GUI 2 in the example below), they are stacked next to each other.
Possible values are top left, top right, bottom left, bottom right.
Default is top right.

const gui = new GUI({ position: 'top left' });

width (number)

Determines the width of the panel.
Default is 290.

const gui = new GUI({ width: 200 });

closed (boolean)

Just like folders, GUI panels can be closed by default by setting the closed option to true.
Default is false.

const gui = new GUI({ closed: true });

maxHeight (number)

Determines to define the maximum height of a panel beyond which scrolling is necessary.
Default is the smallest value between the height of the window and the height of the container.

const gui = new GUI({ maxHeight: 400 });

color (string)

Can be applied to GUI panels and folders to customize the background color.

const gui = new GUI({ color: '#ff0000' });

opacity (number)

Sets the default transparency of the panel. When hovered, the panel becomes fully opaque (opacity: 1).
Default is 1.

const gui = new GUI({ opacity: 0.5 });

onUpdate (function)

Callback function, triggered each time the GUI is updated.

const gui = new GUI({ onUpdate: () => console.log('updated') });

Methods

.button( parameters, callback )

Parameter Type Description
label string Optional.
color string Optional.
hoverColor string Optional. Default is equal to color if defined.
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.
import GUI from 'perfect-gui';

const gui = new GUI();

gui.button('Button 1', changeColor);

gui.button({ label: 'Button 2', color: '#bb3333', hoverColor: '#cc3333' }, changeColor);

.slider( parameters, callback )

Parameter Type Description
label string Defaults to the prop parameter if one is provided.
value number Defaults to the average value between min and max properties.
min number Default is 0.
max number Default is 1.
step number Increment by which to change the value.
Default is calculated so that there are 100 steps between min and max.
obj object Target object. Ignored if a value is specified.
prop string Target object property. Ignored if a value is specified.
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.

This method can be used in 2 ways:

import GUI from 'perfect-gui';

const position = { x: 0 };
const gui = new GUI();

// Simple slider with value & callback
gui.slider({ label: 'Simple slider (value & callback)', value: 1 }, 
    value => {
        element.style.opacity = value;
    }
);

// Object binding
gui.slider({ label: 'Slider with object binding', obj: position, prop: 'x', min: -30, max: 30 },
    () => {
        element.style.transform = `translateX(${position.x}px)`;
    }
);

.toggle( parameters, callback )

Parameter Type Description
label string Optional.
value boolean Optional. Default is false.
obj object Optional. Target object. Ignored if a value is specified.
prop string Optional. Target object property. Ignored if a value is specified.
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.

This method can be used in 2 ways:

import GUI from 'perfect-gui';

const gui = new GUI();

// Approach 1: using a callback function
gui.toggle({ label: 'Toggle (simple callback)', value: true }, value => {
    if ( value ) element.classList.remove('round');
    else element.classList.add('round');
});

// Approach 2: using object binding
const isRound = { state: true };
gui.toggle({ label: 'Toggle (object binding)', obj: isRound, prop: 'value' }, () => {
    if ( isRound.state ) element.classList.remove('round');
    else element.classList.add('round');
});

.list( parameters, callback )

Parameter Type Description
label string Optional.
values array Options to be displayed.
value string | number Optional. Defines the default selected value in the options array. This can either be a string, which must correspond to one of the values within the options array, or a number, representing the index of the selected value in the array of options.
obj object Optional. Target object. Ignored if a value is specified.
prop string Optional. Target object property. This can either be a string, which must correspond to one of the values within the options array, or a number, representing the index of the selected value in the array of options. Ignored if a value is specified.
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.

This method can be used in 2 ways:

import GUI from 'perfect-gui';

const gui = new GUI();

// Approach 1: using a callback function
gui.list({ label: 'List', values: ['red', 'pink', 'yellow', 'blue'], value: 1 }, selected_value => {
    element.style.backgroundColor = selected_value;
});

// Approach 2: using object binding with an array of strings
const values = ['red', 'pink', 'yellow', 'blue'];
const color = { value: 2 };
gui.list({ label: 'List (object binding)', values, obj: color, prop: 'value' }, 
    ( value, index ) => {
        element.style.backgroundColor = values[color.value];
    }
);

// Approach 3: using object binding with an array of objects
// The "label" property is only used to control what's displayed in the option list
// The intrinsec value of each item is the "value" property
const color2 = { value: '#993333' };
const objectValues = [
    {label: 'reddish', value: '#993333'}, 
    {label: 'pinkish', value: '#aa33aa'}, 
    {label: 'yellowish', value: '#999933'}, 
    {label: 'blueish', value: '#333399'}
];
gui.list({ label: 'Object binding (objects)', values: objectValues, obj: color2, prop: 'value' }, 
    (obj, index) => {
        element.style.backgroundColor = obj.value;
    }
);

.image( parameters, callback )

Parameter Type Description
label string Optional. Default is the image file label.
path string Image file path.
selected boolean Default state of the item. Default is false.
selectionBorder boolean Defines if a border is visible around the selected element. Default is true.
width number | string A number type value specifies the width in pixels, while a string value allows for defining the width using various units of measurement, such as '50%' or '5vw'. Default is 33.333%.
height number Defines the height of the element in pixels. Default is 90.
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.
import GUI from 'perfect-gui';

const gui = new GUI();

gui.image({ label: 'Image 1', path: 'path/to/image1.jpg'}, changeBackground);
gui.image({ label: 'Image 2', path: 'path/to/image2.jpg', selected: true}, changeBackground);
gui.image({ label: 'Image 3', path: 'path/to/image3.jpg'}, changeBackground);
gui.image({ label: 'Image 4', path: 'path/to/image4.jpg'}, changeBackground);
gui.image({ label: 'Image 5', path: 'path/to/image5.jpg'}, changeBackground);

function changeBackground(evt) {
    element.style.backgroundImage = `url( ${evt.path} )`;
}

To select a button programmatically, you can use the click() method on the element like this:

const imageButton = gui.image(...);
imageButton.click();

.color( parameters, callback )

Parameter Type Description
label string Optional.
value string Hexadecimal color value.
Optional. Default is #000000.
obj object Optional. Target object. Ignored if a value is specified.
prop string Optional. Target object property. Ignored if a value is specified.
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.
import GUI from 'perfect-gui';

const gui = new GUI();

// Simple value & callback
gui.color({ label: 'Color (value & callback)', value: '#06ff89' }, color => {
    element.style.backgroundColor = color;
});

// Object binding
const color = { value: '#06ff89' };
gui.color({ label: 'Color (object binding)', obj: color, prop: 'value' }, () => {
    element.style.backgroundColor = color.value;
});

.vector2( parameters, callback );

Parameter Type Description
label string Optional.
x object An object containing the x-axis properties
{ obj<object>, prop<string>, min<number>, max<number> }
y object An object containing the y-axis properties
{ obj<object>, prop<string>, min<number>, max<number> }
tooltip string|boolean Descriptive text showing up on hover. If set to true, its value will be the same as the label.

A vector2() component will automatically update the value of the target object property, therefore a callback isn't necessarily needed. Directly updating the object property will also update the vector2() component.

import GUI from 'perfect-gui';
        
const position = { x: 0, y: 0 };
const gui = new GUI();

gui.vector2({ label: 'Position',
    x: { obj: position, prop: 'x', min: -50, max: 50 },
    y: { obj: position, prop: 'y', min: -50, max: 50 },
}, (x, y) => {
    element.style.transform = `translate(${x}px, ${-y}px)`;
});

.folder( parameters )

Parameter Type Description
label string Optional.
closed boolean Optional. Default is false.
color string Optional. Background color of the folder.
maxHeight number Optional.
import GUI from 'perfect-gui';

const gui = new GUI();

let folder_1 = gui.folder({ label: 'Folder 1' });
folder_1.button('Random color', changeColor);
folder_1.slider({ label: 'Size', value: 1 }, changeScale);

let folder_2 = gui.folder({ label: 'Folder 2', color: '#993333' });
folder_2.button('Random color', changeColor);

let folder_3 = gui.folder({ label: 'Folder 3', closed: true });
folder_3.button('Random color', changeColor);

.toggleClose()

import GUI from 'perfect-gui';
        
const gui_1 = new GUI();

gui_1.button('gui_2.toggleClose();', () => {
    gui_2.toggleClose();
});

const gui_2 = new GUI();

gui_2.button('gui_1.toggleClose();', () => {
    gui_1.toggleClose();
});

Killing and creating dynamically

There is no .kill() method at the moment, so instances have to be killed "manually".

See code