Skip to content

Instantly share code, notes, and snippets.

@basilbeltran
Forked from heaversm/datgui-build.js
Created October 17, 2018 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save basilbeltran/c6ff6deb61beeb00d223ed6d6091e0e8 to your computer and use it in GitHub Desktop.
Save basilbeltran/c6ff6deb61beeb00d223ed6d6091e0e8 to your computer and use it in GitHub Desktop.
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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment