Automatically generating a graphical user interface to control your javascript animation
Often times when building an animation in webGL or canvas or SVG, it’s nice to add a graphical user interface (GUI) so you can easily move sliders and click buttons to change your variables, and see those changes without having to leave your browser. And it gives non-coders/clients the chance to play around with things see what changes would look like without having to know how to write code, meaning you don’t have to go through dozens of rounds of review to fine-tune an animation. This is a tutorial that shows you how to (semi)automatically build a GUI for your animation using DAT.gui and javascript.
DAT.gui is a javascript GUI library from the Google Data Arts team that facilitates UI building, but each control must be added manually, and often times I’m working with anywhere from tens to hundreds of variables I want to control, which makes adding them to DAT.gui manually a cumbersome prospect. So this is a quick article to help you automate the process!
TLDR: Copy and adapt this gist to your purposes.
This tutorial will assume that all of your variables that you want to control live inside a javascript/JSON object, like the image below:
First, if you’re not familiar with DAT.gui — their tutorial is short and wonderfully done and will provide a great primer, but here’s a couple terms I’ll be using:
Step
— the increment by which each number value will increase or decrease each time you move a slider.Limit
— the max or minimum value a slider can be moved to
To not try and overcomplicate the code, I only have a few rules in place:
- Loop through the top level of the javascript object and read all the values.
- If the object value is a HEX color (like
#FFOOOO
), then I’ll make sure to use theaddColor
method vsadd
so you can use a colorPicker, versus a text field. - If it’s a
string
orboolean
, just let DAT.gui do it’s thing — it will provide a text field for strings, and a checkbox for booleans. - If it’s a number between -1 and 1, I’ll set the
step
to.1
and the limit to-1:1
so each time you move the slider, it will go from.1
to.2
to.3
etc. - If it’s any other number, I’ll set it’s step to 1 digit less than the number, and it’s limit to 1 digit greater. So, for example, the number
150
would have a step of10
and a limit of-1000
to1000
. The number15
would have a step of1
and a limit of-100
to100
. - If it’s a nested javascript object, we’ll loop through that object and find all of its keys, and assign them to the same GUI folder as their parent.
- I’m not currently handling arrays. I could see how these might be useful in a GUI though, as a sort of multiple choice option or dropdown. If you have a good method for handling them, let me know!
Anyway, here is the (pseudo)code:
Some notes:
- You will obviously need to include the DAT.gui javascript file somewhere in your project before you run this code.
- You will need to replace the
config
object with your own javascript object full of variables you want to be able to control with the GUI. Rather than iterate through a bunch of nested objects, I usually add one folder per 2 levels. - You’ll see from the screenshot below that the
timings
nested object just gets wrapped in with all the other variables in the GUI. - Click to update: Notice that
guiUpdate
object? For whatever reason, DAT.gui doesn’t have support for buttons, but this object allows you to make one. This button, when pressed, allows you to execute a function. In my case, I’m adding anupdate
function to DAT.gui, when calls therestartAnimation
function, which will allow users to restart my animation with all of the changes they made in the GUI. getNumDigits
: this is a function which calls a regex that converts our number to a string and counts how many actual numerical digits are in the number (ignoring things like.
)Math.pow(10,numDigits -2)
: If you have a 3 digit number, like150
, this means that you are taking the number 10, and multiplying it by itself3-2
times, or 1 time.10*1 = 10
. So that is your step. Each time you move the slider, you increase the number by 10. And as for your limit,Math.pow(10,numDigits)
means that150
has 3 digits, so a limit of10*10*10
or-1000
to1000
.
That’s all there is to it. For situations where you have a lot of variables to control with your GUI, hopefully this is helpful!