-
-
Save alfongj/a20399c91d271ba674cb94c143ae1145 to your computer and use it in GitHub Desktop.
Automatically build a dat gui from a javascript object
This file contains 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
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