Skip to content

Instantly share code, notes, and snippets.

@alfongj
Forked from heaversm/datgui-build.js
Last active August 15, 2021 08:02
Show Gist options
  • Save alfongj/a20399c91d271ba674cb94c143ae1145 to your computer and use it in GitHub Desktop.
Save alfongj/a20399c91d271ba674cb94c143ae1145 to your computer and use it in GitHub Desktop.
Automatically build a dat gui from a javascript object
const config = { //SAMPLE OBJECT - replace this with your data object
fastMode: true,
backgColor: "#a42e27",
foregColor: "#dcafad",
sun: {
x: 140,
y: 155,
radius: 240,
color: "#e3d5c4",
},
mountains: {
horizonY: 360,
shadeCount: 20,
distBetweenMountains: 45,
distBetweenShades: 5,
list: [
{
period: 0.67,
phaseShift: 0,
amplitude: 1,
},
{
period: 0.33,
phaseShift: 0,
amplitude: 1,
},
{
period: 0.5,
phaseShift: 0,
amplitude: 1,
},
],
},
};
class DatGuiBuilder {
constructor(config) {
this.config = config;
this.buildGUI();
}
buildGUI() {
this.gui = new dat.GUI();
this.gui.remember(this.config);
this.addToGui(this.config, this.gui);
const guiUpdate = {
redraw: () => {
this.restartAnimation();
},
};
this.gui.add(guiUpdate, "redraw");
}
addToGui(obj, folder) {
for (const key in obj) {
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);
} else if (typeof val === "object") {
let localFolder = folder.addFolder(key);
this.addToGui(val, localFolder);
} else {
if (val.startsWith && val.startsWith("#")) {
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() {
// TODO Restart your animation
}
}
window.guiBuilder = new guiBuilder();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment