Stages
At the beginning of the year, I had a chat with 12 min albums record label. Dante, the guy from the label, said that if I record mini album (12 minutes) they would be glad to publish it. One of the requirements from their side was that, together with audio, I needed to provide video. So, naturally, I spent the last few months developing a tool to make trippy animations. Like this one:
TLDR:
The spacebar hides/shows controls. Click on animation makes it fullscreen.
While animation does work on mobile, controls are too big to be comfortable on mobile.
Open the link and drag some sliders around.
#Documentation.
Top left corner has 0,0 coordinates. X axis goes from left to right, Y axis goes from top to bottom.
There is two types of controls and factory to spawn them.
- Value producers. Some of them are just values like zero or one. Some of them need other vales to produce values. For example, math needs two other values to produce a value.
- Outputs, are the ones that draw something on the screen. A line is an example of an output.
All changes are synced to the URL. That has two side effects:
- Browser back/forth works like undo/redo
- If you come up with a nice animation, you can embed it into anywhere just by URL.
It does crush on division by zero or if connections form a loop. Browser back (undo) does fix the issue most of the time.
#Built in value producers.
zero: 0one: 1two: 2width: width of the browser windowheight: height of the browser windowi- In each frame, some amount of shapes will be drawn, this will be the serial number of the shape drawn.now- Time since animation start in milliseconds.
#Factory
The factory spawns any available control.
#Slider
Produces a value that can be changed by user in UI. Minimum slider resolution is 0.00001, if min and max are
close enough to each other.
#Math
Produces a value that is a result of math operations.
sum- adds two valuessub- subtracts two valuesmul- multiplies two valuesdiv- divides two valuesavg- averages two values
In order to use screen real estate efficiently, math has two blocks a (top) and b (bottom). Each block has
lhs and rhs values and mode that specifies operation. Those two blocks produce two values with _a and _b
postfixes.
#Oscillator
Produces a value that oscillates between min and max in time specified by raise and fall.
All oscillators are synced to the same zero time.
raise and fall are in milliseconds.
#Random
Produces a random value between min and max
#Line output
Connects vertices amount of vertices by a straight line.
For each frame, it will read values from vertices and sr (sample rate) parameters. Then it will read values from
x and y, vertices amount of time, advancing now by sr and i by one.
#Logic
Produces a value that is a result of logic operation.
eq: left hand equals right handneq: left hand not equals right handgt: left hand greater than right handlt: left hand less than right handgte: left hand greater than or equals right handlte: left hand less than or equals right hand
If logic operation evaluates to true, value from is_true connector will be returned, otherwise value from is_false.
Writing documentation is hard.
If you know how to make it better, please let me know.
#Walkthrough A
In this part we will learn how to draw lines and position them on the screen.
#Simple line
Lets open empty stage, add a slider with name y and line with name line to the stage.
Nothing happens, that because we do not have any connections yet. Lets connect:
line.xtowidthline.ytoyline.verticestoheightline.srtoone
Now we have a line that goes from the left side of the screen to the right side of the screen. When you move the
y slider, the line will move up and down.
#Vertical line that always in the center of the screen
In a previous example we were able to draw a line at position that can be adjusted manually. If we want to draw a line
at specific position let's, say at center of the screen, we need math. With math we will divide
height value by two.
Lets open empty stage, add a math with name center and line with name vl to the
stage. Then add connections:
center.mode_atodivcenter.lhs_atoheightcenter.rhs_atotwovl.xtowidthvl.ytocenter_avl.verticestowidthvl.srtoone
#Horizontal line that always in the center of the screen
Let's add another line that will be drawn at the center of the screen. Use previous stage, add one more line
control with name hl and connect it like this:
center.mode_btodivcenter.lhs_btowidthcenter.rhs_btotwohl.xtocenter_bhl.ytoihl.verticestoheighthl.srtoone
#Triangle wave in the top right corner
With oscillator control we can create a triangle wave. And to make it more interesting lets draw it in the top left corner.
To achieve that we need to add three controls:
- slider with name
y_tto control the frequency - oscillator with name
yto produce y value - line with name
trto draw in top left corner
And connect them like this:
y.mintozeroy.maxtocenter_ay.raisetoy_ty.falltoy_ttl.xtoitl.ytoytl.verticestocenter_atl.srtoone
#Triangle wave in the bottom right corner
Let's add another triangle wave, but this time in the bottom right corner. To make it more interesting, we will make it run in a different direction. To achieve that we need a bit more math, and of course, another line control.
Add following controls:
Then connect them like this:
br_pos.mode_atosubbr_pos.lhs_atowidthbr_pos.rhs_atoibr.xtobr_pos_abr.ytobr_pos_bbr.verticestocenter_abr.srtoone
#Movement in both directions
We have two corners left. Let's fill top right corner with graph that moves in both directions. To achieve that we need to add following controls:
- slider with name
x_tto control frequency - oscillator with name
xto produce x value - line with name
trto draw in top right corner
And connect them like this:
x.mintocenter_ax.maxtowidthx.raisetox_tx.falltozerotr.xtoxtr.ytoytr.verticestowidthtr.srtoone
#Distortion
Last corner to fill! You know what? We will get graph from previous step and distort it. To do that we will need a bit more stuff than usual. Lets add following controls:
- slider with name
n_amointto control amount of distortion - math with name
n_widthto control width of the noise - random with name
noiseto generate noise - math with name
bl_posto calculate position - math with name
bl_disto calculate distortion - line with name
blto draw distorted graph
And connect them like this:
n_width.mode_ato subn_width.lhs_atozeron_width.rhs_aton_amountnoise.minton_width_anoise.maxton_amountbl_pos.mode_atosubbl_pos.lhs_atoxbl_pos.rhs_atocenter_abl_pos.mode_btosumbl_pos.lhs_btoybl_pos.rhs_btocenter_bbl_dis.mode_atosumbl_dis.lhs_atobl_pos_abl_dis.rhs_atonoisebl_dis.mode_btosumbl_dis.lhs_btobl_pos_bbl_dis.rhs_btonoisebl.xtobl_dis_abl.ytobl_dis_bbl.verticestowidthbl.srtoone
Congrats!
You just finished first ever Stages tutorial!
How was it?
#Walktrough B
In this part we will recreate Stages logo.
#U shape
Lets start with a U shaped wave.
Open an empty stage and add following controls:
- slider with name
y_tto control frequency of first oscillators - oscillator with name
y_min_modto modulate min value - oscillator with name
yto getycoordinate - line with name
lineto draw a line
Then connect them like this:
y_min_mod.mintozeroy_min_mod.maxtoheighty_min_mod.raisetoy_ty_max_mod.falltoy_ty.mintoy_min_mody.maxtoheighty.raisetoy_ty.falltoy_tline.xtoiline.ytoyline.verticestowidthline.srtoone
#Logo
To achieve the same result as on the logo we need one more oscillator control that runs with a higher frequency. Lets add to previous stage following controls:
- oscillator with name
y_min_mmto modulatey_min_mod.min - slider with name
mm_tto control frequency of modulation
And connect them like that:
y_min_mm.mintozeroy_min_mm.maxtoheighty_min_mm.raisetomm_ty_min_mm.falltomm_ty_min_mod.mintoy_min_mm
Yay!
The logo is complete, and no AI was harmed in the process.
What do you think?
#Walktrough C
The idea was to introduce logic control, but I failed to find the time. Here is the final result:
#Pulsed distortion
This post is too long anyway.
I will stop here.
If you have any questions or suggestions, feel free to open an issue on the Stages repo.
#TODO
Plans for the future looks like that:
- Resolve circular dependencies.
- Resolve division by zero.
- Color control. Most likely in HSB format.
- More shapes. Circles, squares, etc.
- Trigonometry. cos, sin, tan, etc.
- Math control requires more options: powers, roots, logs, etc.
- Actual audio support.
- Gates and ADSR.
- MIDI support would be awesome.
- Better docs.
- Better UI.
I am extremely curious what you will create with Stages. Send me links!