Bauhaus and Code Pt. II
Bauhaus and Code Pt.2
By Davíd Raphael Lockard
“The investigation should proceed in a meticulously exact and pedantically precise manner. Step by step, this “tedious” road must be traversed — not the smallest alteration in the nature, in the characteristics, in the effects of the individual elements should escape the watchful eye.” (p.21)
As a point of reference, we will be using Vasily Kandinsky’s pedagogical writing – as it is interestingly suited for transposition onto digital drawing. Kandinsky was a central teacher at the Bauhaus. He used his experiences teaching the preliminary course to write the book Point and Line to Plane – an attempt at formulating a systematic approach to painting. The quotes are all taken from this book.
This tutorial is designed for people with no previous experience programming. If you have coded before, you are more than welcome to join along. This is the moment to suggest you settle deeper into your seat and make sure to be using a computer with a keyboard rather than a mobile device.
One important thing before we start: If this tutorial grabs your interest, you are warmly encouraged to visit P5.js, an amazing resource for taking ones first steps in creative coding. This tutorial relies deeply on the amazing tools and methodologies built by the P5 community, and is inspired by its ethos. For robust and welcoming tutorials, you are warmly encouraged to visit Dan Shiffman’s online videos, to which this tutorial is heavily indebted. P5 was created by Lauren McCarthy and developed by a community of collaborators, with support from the Processing Foundation and NYU ITP.
The Environment
There is a wide variety of programming languages. Different ones are good for different needs, but the underlying logic of all programming languages is for all intents and purposes the same. We will be learning Javascript, which is a language a lot of the internet is built in.
We will be learning it through a library called P5. For now, just think of library as a sort of dialect – P5 is a dialect of Javascript. It is well suited for people who think visually.
As we were saying earlier, the grey window below is an editor, in which one can both write programs – on the left side – and execute them, on the right. (Thanks to Atul Varna for creating this embeddable editor.)
1. The Point
The point is the result of the initial collision of the tool with the basic plane. Paper, wood, canvas, stucco, metal — may all serve as this basic plane. The tool may be pencil, burin, brush, pen, etching-point, etc. The basic plane is impregnated by this first collision. (p. 27)
To examine this ‘basic collision’ on an interactive digital surface, let’s start with learning to write a program like the one below: a rectangle that follows your mouse. In doing so, we will experiment with functions and variables – two key terms in programming.
2. createCanvas and background
Functions are building blocks that carry out tasks. A large part of coding is learning to write your own functions. But at first we will be using a few functions that come ‘ready to use’ in p5. Our first two functions will generate our surface – or canvas as it is called in P5 – and give it color:
createCanvas generates the surface. (Note the capitalization)
background determines the surface’s color
createCanvas(400,200) background(0,0,0)
Notice that each of these functions is followed by numbers. These numbers are called arguments. They must be wrapped in parentheses and separated by commas. An argument tells ‘its’ function how to do its job. Not all functions need arguments, as we shall see soon. But the first ones we will use do. Let’s take a closer look at what these two particular functions work, and what their arguments are doing.
The createCanvas function needs two arguments to determine its dimensions. The first will determine the canvas width, and the second its height. Writing createCanvas(400,200) will result in a horizontal canvas that is 400 by 200 pixels in size. To get a canvas in the same ratio but vertically oriented, one would flip the order of those two numbers.
In the editor below, go ahead and change the canvas dimensions by modifying the createCanvas arguments. Hit play to execute the code. Try making a square canvas of 300 by 300, for example, and a few other combinations. Be sure to keep the numbers separated with a comma, and between parentheses. Code is very particular about how you write it – as you will see, even one small mistake may cause your program to not to run at all.
createCanvas(400,200) background(0,0,0)
“The point is a small world cut off more or less equally from all sides and almost torn out of its surroundings…it maintains itself firmly in place and reveals not the slightest tendency to movement in any direction whatsoever, either horizontal or vertical.” (p.21)
Onward to our next function: background. This one determines the color of the canvas. We are using the RGB (a red-green-blue) model, in which colors are created through a mix of three separate values: of red, green, and blue. The scale is 0 to 255, with dark being 0 and light being 255. So black is 0,0,0 – and white is 255,255,255. This might sound complex but it’s easier to understand once you start playing around.
Try plugging in a few different combinations in the editor below. Make the canvas red by using 255,0,0. (You will have to hit play to see your changes take effect) Try making it green by using 0,255,0. Or blue by 0,0,255. And then try some other random combinations of three values. Remember, always separated by commas, and between parentheses!
createCanvas(400,200) background(0,0,0)
3. fill and rect
“The point’s external concept in painting is not precise. The invisible geometric point must assume a certain proportion when materialized, so as to occupy a certain area of the basic plane. In addition, it must have certain boundaries or outlines to separate it from its surroundings.” (p.28)
Once you are comfortable with changing the canvas size and background color, let’s go ahead and place a static, white rectangle on our canvas. We will do this using the functions fill and rect.
fill picks a new color
rect draws a rectangle and determines its location and dimensions
createCanvas(400,200) background(0,0,0) fill(255,255,255) rect(200,100,20,20)
In the editor above, you will see added to our canvas a rectangle whose color, location, and size are determined by the arguments of these two new functions.
Let’s see how. The fill function is determining the rectangle’s color. It comes before the rectangle – just like in painting one first dips a brush into a new color, and then paints a shape.
Similarly to the background function we looked at earlier, fill always requires three arguments (for red, green, and blue). In line 3 of the panel below, try playing around with fill‘s arguments to modify the rectangle’s color.
createCanvas(400,200) background(0,0,0) fill(255,255,255) rect(200,100,20,20)
As for the rect function – notice that it takes four arguments. Different functions require different amounts of arguments, and they use them in different ways. In rect, the first two arguments will always determine the rectangle’s location. rect‘s first argument will determine its distance from the horizontal axis (X), and its second from the vertical axis (Y). In p5 the zero point is always at top left, so the smaller these numbers, the closer your rectangle will be to the top left. Try moving the rectangle to a different place on the canvas. (Hit play to update the code, as usual). Notice that your rectangle will not be visible if you place it outside the canvas bounds!
rect‘s third and fourth arguments, meanwhile, determine the rectangle’s size: once again, first X, then Y. In the editor below, try playing around with the size of the rectangle.
createCanvas(400,200) background(0,0,0) fill(255,255,255) rect(200,100,20,20)
Once you have are comfortable changing the color, location, and size of your rectangle, try adding another rectangle, by writing a new line of code right below line 4, in line 5. You can either write it yourself or just copy line 4 – in either case, you will have to modify your new rectangle’s location so it doesn’t just ‘hide’ your previous one. You can add as many rectangles as you want to – try creating a few more. Then see if you can make another rectangle that is in a different color: to do this, you will need to add another fill function before your new rectangle, and modify its arguments to the new color you want. Once you have created a canvas with a few different rectangles in different sizes and colors in different location, let’s move on.
“The point is a small world cut off more or less equally from all sides and almost torn out of its surroundings…it maintains itself firmly in place and reveals not the slightest tendency to movement in any direction whatsoever, either horizontal or vertical.” (p.21)
4. setup and draw
Before ripping our square away from its surroundings and making it interactive, we must devote our attention to a fundamental aspect in the structure of our code: how it functions in time. While this all looks as if we have only created our canvas and whatever is on it once, these lines of code are actually being executed over and over again – about 60 times per second.
And it works like this: right now, the computer is reading all our functions in the order they are listed, then executing them all at once, and then starting over again.
So right now our computer is being instructed to execute four functions in a loop:
1> Make a canvas
2> Paint it black
3> Select white color
4> Paint a rectangle (Or more than one, if you added more.)
5> Go back to step 1
In order to do more interesting things, we are going to make a separation between things that loop forever and things that happen just once. This may be unclear, but you will soon understand what this means. For now, let’s look at how we can separate our functions, so that our first function createCanvas happens only once (when the code is first executed) – and the rest to happen over and over again as long as the program is running.
To do this, we will have to make two new functions, and place the current functions inside of them. This is what it will look like:
function setup() { createCanvas(400, 200) } function draw() { background(0,0,0); fill(255,255,255) rect(200,100,20,20) }
As you can see, while the output remains the same, our code looks quite different.
We have created two new functions called setup and draw, and placed our four lines of code inside them. These new functions are not taking arguments. Instead, they each have a pair of curly brackets, into which we are placing other lines of code – other functions, in this case.
setup and draw are two very useful functions provided by p5, and there is an important distinction regarding what happens to code that is placed within either. Consider it like this: whatever code is inside setup‘s curly brackets will happen only once when the program is started. Whatever code is inside draw, on the other hand, will be executed repeatedly happening again and again as long as the program is running. If this doesn’t make sense don’t worry, you will soon see what this means in practice, as we learn about variables in the next section.
Aside from its scientific value, which depends upon an exact examination of the individual art elements, the analysis of the art elements forms a bridge to the inner pulsation of a work of art. (p.17)
5. Variables
Now that we have made this separation into the setup and draw function, we can make our little rectangle change in all sort of ways. For example, in the editor below, in size.
function setup() { createCanvas(400, 200) } function draw() { background(0,0,0) fill(255,255,255) rect(20,100, mouseX,20) }
Have a look at the rectangle’s size arguments in the code above. As you can see, in place of a number in its width argument, we have placed the word mouseX. Instead of a static value, we have given it a fluid variable.
Variables are sort of like containers for values. Soon we will write our own variables, but right now we are using predefined variables that are part of the p5 library. mouseX and mouseY are p5 variables that ‘listen’ to the location of the user’s mouse (relative to the canvas’ top left corner). By placing these particular variables in a function’s arguments, the function becomes responsive to your mouse. In the sketch above (sketch is the word used for a p5 program) you can see that the width of the rectangle is determined by the location of the mouse in the canvas.
In the sketch above, try changing the rectangle’s height to mouseY. Then try replacing one of the arguments in the fill function with mouseX or mouseY. Play around – see what happens when you, for example, flip the arguments so that that the rectangles X location is determined by the mouse Y, and vice versa.
Try experimenting in the window below. Also try placing the mouse variables in place of the background RGB values. See if you can make an interesting composition. Mission #1, complete.
function setup() { } function draw() { }
6. The Line
“The geometric line is an invisible thing. It is the track made by the moving point; that is, its product. It is created by movement — specifically through the destruction of the intense self-contained repose of the point. Here, the leap out of the static into the dynamic occurs.” (p. 65)
Kandinsky considered the point and the line as the two most fundamental visual elements – the building blocks of all visual expression. Following his lead, let’s examine the creation of lines in code.
In order to create a program like the one above, we will need to use two new functions: stroke and line.
The line function takes four arguments: the first two determine the line’s starting point (on the x and y grids), and the third and fourth arguments determine the line’s ending point. Play around with the example below. See if you can add a fourth line from the bottom righthand corner to the mouse. Then add a horizontal line and a vertical line.
Play around, and see what behaviors you can create.
function setup (){ createCanvas(400, 400); } function draw(){ background(200,200,200) stroke(255,0,0) line(0, 0, mouseX, mouseY) line(0, 400, mouseX, mouseY) line(400, 0, mouseX, mouseY) }
The default color of our line is white. To give it a color, we will use a new function called stroke. Like fill, the stroke function takes three arguments (red green and blue), to determine its color.
In the example below, you can see two lines with different colors. Notice that each line is defined by the color above it. Think of it like a brush dipped in paint. When you want to use a new color, you must first dip your brush into a new paint. Try adding a few more lines in different colors. (You will have to change their locations, too – otherwise one will simply cover the other.)
function setup (){ createCanvas(400, 400) } function draw(){ background(0,0,0) stroke(0,0,255) line(0, 0, 150, 150) stroke(255,255,255) line(150, 150, mouseX, mouseY) }
function setup() { createCanvas(400, 400) } function draw() { background(100,160,200) fill(mouseX,mouseX,mouseX) rect(mouseX, mouseY,mouseX, 35) }
When a force coming from without moves the point in any direction, the first type of line results; the initial direction remains unchanged, and the line has the tendency to run in a straight course to infinity. This is the straight line whose tension represents the most concise form of the potentiality for endless movement.
In one of the editors above, try experimenting with the functions we have learned and mouseX and mouseY variables. Try making a few rectangles that use the mouseX or mouseY as a value for their color and size arguments, like the example below.
As we gradually tear the point out of its restricted sphere of customary influence, its inner attributes — which were silent until now — make themselves heard more and more.
One after the other, these qualities — inner tensions — come out of the depths of its being and radiate their energy. Their effects and influence upon human beings overcome ever more easily the resistances they set up. In short, the dead point becomes a living thing.” (p.26)
Once you feel comfortable with that, here’s one last thing to try before we end this first lesson: in your code above, try adding this line of code:
rect(50,50,(mouseX+30), (mouseY+30))
As you can see, we have placed the mouse variables into their own sets of parentheses, and modified them using simple math. This can work with subtraction, multiplication and division, too – but as always, you will have to pay close attention to the parentheses!
Now you have all the coding skills needed to create a program like the one at the very top of the first article page. (except for the ellipse – which you can read about here)
Perhaps this is the moment to ‘graduate’ to a more robust editor, where you can also name, save, and share your programs: the p5 Web Editor!
This is barely the start. If you are hooked and want to learn thoroughly from the experts – you would be wise to visit p5.js or Dan Shiffman’s videos.
Many thanks to peblio, the platform that inspired this piece. I would love to hear from you at drl349@nyu.edu– if this was helpful, or you ran into trouble.