Last active
February 6, 2024 03:52
-
-
Save heaversm/b159b51f4e68603b05dc417dfadb43c5 to your computer and use it in GitHub Desktop.
Automatically build a dat gui from a javascript object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
thanks for that example π€ππ
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
well done sir