Sketch from Scratch 1 Colorful checkerboard in P5JS

01/26/2021

Why you need a visual medium alongside your music

Twitter and Instagram are primarily visual mediums and are not extremely well suited for sharing audio content. Digital artists, designers and models can get a lot of traction from posting beautiful pictures or videos, especially since it would be something that other people would want to re-tweet or share in their stories. As a musician or producer, screen recordings of your DAW playing back your track is usually not extremely aesthetically pleasing. Personally, it's been extremely difficult to find something visually interesting and also thematically appropriate to use as cover art for your social media post.

Keeping it original

Another restriction that I restrained myself with was that everything that I post had to be completely original, which naturally includes the cover art. This led me to experiment with different programming languages and tools that could technically be used for creating these visuals. I've seen a lot of posts that use touchdesigner to create visuals for their music and it's quite fantastic in that regard. Touchdesigner is a python powered node based visual programming language that's seeing a lot of use by DJs and visual performers, however I found it too difficult to use for my purposes, as I wanted something quick and simple. I also experimented with OpenGL and GLSL, all the time while reminiscing about the computer graphics class that I've taken a few years ago. But shading languages are also way overkill for simple visuals. I also attempted to use OpenFramenworks, a creative coding library in c++ and built on top of OpenGL, but I found it equivalently too difficult.

P5JS

What's P5JS?

However recently I discovered P5JS, another creative coding library built with Javascript. What I found most exciting about it was that it had online editor where you could code up sketches very quickly and run them directly in your browser. No hassle with any downloads or installation, no dealing with a compiler on system, and tons of tutorials and sketches from other people that you can simply view and get inspired by.

How does P5JS work?

Comprehensive and exhaustive tutorials on P5JS can be found on The Coding Train's Youtube channel, and the complete P5JS can be found on the official website. Quick sketches can be spun up in the web editor.

An empty sketch starts with two functions. Setup and Draw. The setup functions contains the canvas() statement that creates the (surprise!) canvas and should usually contain everything that you want to do before drawing to the canvas. When you hit the run button in the top left corner of the web editor, the setup function is executed, and then immediately after, the draw function is called. The draw function will then continuously execute it's contents, and depending on what that is, will make something appear on screen.

In the embedded instagram post above you can see the final product. The warbly music that's playing alongside the animation will be the topic for another blog post.

Creating the checkerboard

The Colors

The first thing we'll want to do is grab a bunch of harmonious colors from Coolors, which conveniently lets us export the hex codes. We can later on randomly draw colors from this array to color the squares in our grid:

var listOfColors = ["#1c77c3", "#39a9db", "#40bcd8", "#f39237", "#d63230",
                                "#540d6e", "#ee4266", "#ffd23f", "#f3fcf0", "#1f271b"];

This array is in the global scope and therefore accesible everywhere throughout the rest of the code.

The Square

Next we create a template square class which we can reuse to create each individual square in our grid. For now the square will contain it's position, it's size and it's color:

class Square{
  constructor(px,py,s){
    this.positionX = px
    this.positionY = py
    this.size = s
    this.c = listOfColors[int(random(0, listOfColors.length))]
  }

  display(){
    fill(this.c)
    rect(this.positionX-this.size/2, this.positionY-this.size/2, this.size, this.size)
  }
}

The move function will be empty for now, as the individual squares do not have any moving behaviour. Experiment with it though, maybe you can come up with something interesting!

The Grid

Next we create an object that creates, arranges and shows the individual squares in our grid. The tricky part about it is calculating the space between all the squares as well as their respective widths, such that the grid is always centered:

class SquareGrid{
  constructor(){
    this.squares = []
    this.gridSize = 8
    this.squareSize = 13
    this.spacing = 16
    this.positionX = width/2 - ((this.gridSize-1) * (this.spacing))/2
    console.log(this.positionX)
    this.positionY = height/2 - ((this.gridSize-1) * (this.spacing))/2

    for(let i=0; i<this.gridSize; i++){
      let row = []
      for(let j=0; j<this.gridSize; j++){
        row.push(
          new Square((this.positionX + this.spacing * i),(this.positionY + this.spacing * j ),this.squareSize)
        )
      }
      this.squares.push(row)
    }
  }

  display(){
    for(let i=0; i<this.gridSize; i++){
      for(let j=0; j<this.gridSize; j++){
        this.squares[i][j].display()
      }
    }
    this.squares[int(random(this.gridSize))][int(random(this.gridSize))].c = listOfColors[int(random(0, listOfColors.length))]
  }
}

The final statement at the bottom of the display function is there to make the grid appear animated. Simply after drawing the entire grid, one cell will be selected at random and it's color will be updated by a random color from the color array.

Setup and Draw and Voila

The last thing we still need to do is instantiate the grid and we'll obtain the grid that you've already seen above.

function setup() {
  createCanvas(256, 256);
  grid = new SquareGrid()
}

function draw() {
  background(220);
  grid.display()
}

The entire code can run in the web editor here. If there's something that's not very clear leave me a comment below. And if you enjoyed this post consider following me on Instagram or Twitter, or alternatively shoot me an email. Cheers and thanks for reading.