
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.x
towidth
line.y
toy
line.vertices
toheight
line.sr
toone
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_a
todiv
center.lhs_a
toheight
center.rhs_a
totwo
vl.x
towidth
vl.y
tocenter_a
vl.vertices
towidth
vl.sr
toone
#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_b
todiv
center.lhs_b
towidth
center.rhs_b
totwo
hl.x
tocenter_b
hl.y
toi
hl.vertices
toheight
hl.sr
toone
#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_t
to control the frequency - oscillator with name
y
to produce y value - line with name
tr
to draw in top left corner
And connect them like this:
y.min
tozero
y.max
tocenter_a
y.raise
toy_t
y.fall
toy_t
tl.x
toi
tl.y
toy
tl.vertices
tocenter_a
tl.sr
toone
#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_a
tosub
br_pos.lhs_a
towidth
br_pos.rhs_a
toi
br.x
tobr_pos_a
br.y
tobr_pos_b
br.vertices
tocenter_a
br.sr
toone
#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_t
to control frequency - oscillator with name
x
to produce x value - line with name
tr
to draw in top right corner
And connect them like this:
x.min
tocenter_a
x.max
towidth
x.raise
tox_t
x.fall
tozero
tr.x
tox
tr.y
toy
tr.vertices
towidth
tr.sr
toone
#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_amoint
to control amount of distortion - math with name
n_width
to control width of the noise - random with name
noise
to generate noise - math with name
bl_pos
to calculate position - math with name
bl_dis
to calculate distortion - line with name
bl
to draw distorted graph
And connect them like this:
n_width.mode_a
to subn_width.lhs_a
tozero
n_width.rhs_a
ton_amount
noise.min
ton_width_a
noise.max
ton_amount
bl_pos.mode_a
tosub
bl_pos.lhs_a
tox
bl_pos.rhs_a
tocenter_a
bl_pos.mode_b
tosum
bl_pos.lhs_b
toy
bl_pos.rhs_b
tocenter_b
bl_dis.mode_a
tosum
bl_dis.lhs_a
tobl_pos_a
bl_dis.rhs_a
tonoise
bl_dis.mode_b
tosum
bl_dis.lhs_b
tobl_pos_b
bl_dis.rhs_b
tonoise
bl.x
tobl_dis_a
bl.y
tobl_dis_b
bl.vertices
towidth
bl.sr
toone
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_t
to control frequency of first oscillators - oscillator with name
y_min_mod
to modulate min value - oscillator with name
y
to gety
coordinate - line with name
line
to draw a line
Then connect them like this:
y_min_mod.min
tozero
y_min_mod.max
toheight
y_min_mod.raise
toy_t
y_max_mod.fall
toy_t
y.min
toy_min_mod
y.max
toheight
y.raise
toy_t
y.fall
toy_t
line.x
toi
line.y
toy
line.vertices
towidth
line.sr
toone
#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_mm
to modulatey_min_mod.min
- slider with name
mm_t
to control frequency of modulation
And connect them like that:
y_min_mm.min
tozero
y_min_mm.max
toheight
y_min_mm.raise
tomm_t
y_min_mm.fall
tomm_t
y_min_mod.min
toy_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!