Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Automatically build a dat gui from a javascript object
config = { //SAMPLE OBJECT - replace this with your data object
stroke: 2, //svg stroke value
opacity: 0.3, //0-1
offsetX: 120, //px
offsetY: 80,
fontWeight: 400, //css font-weight
fontSize: 12, //in px
changePositive: '\u25B4', //unicode character for up arrow
changeNegative: '\u25BE', //unicode character for down arrow
colorBlue: '#1190A3', //all hex colors will automatically use the addColor dat gui function
timings: {
delay: 1000, //in ms
}
}
class guiBuilder {
constructor() {
this.buildGUI();
}
buildGUI(){
this.gui = new dat.GUI();
this.guiFolder = this.gui.addFolder('My Folder');
this.gui.remember(config);
this.addToGui(config, this.guiFolder);
//add a button to be able to update your scene with changed variables if they don't auto-update things on screen
const guiUpdate = {
update: () => { //when button pressed, animation will restart with updated values
this.restartAnimation();
}
};
this.gui.add(guiUpdate, 'update');
}
addToGui(obj, folder) {
for (const key in obj) { //for each key in your object
if (obj.hasOwnProperty(key)) {
let val = obj[key];
if (typeof val == 'number') { //if the value of the object key is a number, establish limits and step
const numDigits = this.getNumDigits(val);
let step, limit;
if (val > -1 && val < 1) { //if it's a small decimal number, give it a GUI range of -1,1 with a step of 0.1...
step = 0.1;
limit = 1;
} else { //otherwise, calculate the limits and step based on # of digits in the number
const numDigits = this.getNumDigits(Math.round(val)); //to establish a step and limit, we'll use a base number that is an integer
limit = Math.pow(10, numDigits); //make the limit one digit higher than the number of digits of the itself, i.e. '150' would have a range of -1000 to 1000...
step = Math.pow(10, numDigits - 2); //...with a step one less than the number of digits, i.e. '10'
}
folder.add(obj, key, -limit, limit).step(step); //add the value to your GUI folder
} else if (typeof val === 'object') {
this.addToGui(val, folder); //if the key is an object itself, call this function again to loop through that subobject, assigning it to the same folder
} else {
if (val.startsWith('#')) { //if it's a HEX value, we're going to assume it's a color. You could run a more advanced check here
folder.addColor(obj, key);
} else { //just add the value to the folder with no specific step, and let dat GUI interpret it as it sees fit...
folder.add(obj, key); //...this would include things like boolean values as checkboxes, and strings as text fields
}
}
}
}
}
getNumDigits(val) {
return (`${val}`.match(/\d/g) || []).length //a regex to compute the number of digits in a number. Note that decimals will get counted as digits, which is why to establish our limit and step we rounded
}
restartAnimation(){
//your restart / teardown code here
}
}
window.guiBuilder = new guiBuilder();
@basilbeltran

This comment has been minimized.

Copy link

commented Oct 17, 2018

well done sir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.