Using Grids in Creative Coding

Written by radarboy3000 | Published 2017/03/03
Tech Story Tags: javascript | web-development | creative-coding | generative-art | learning-to-code

TLDRvia the TL;DR App

How to create a reusable grid system in Javascript

I’m a massive fan of repetition. So I use grids pretty much every day. It’s a fast and easy way to layout things on the screen.

All the code and libraries for these tutorials can be found here: https://github.com/GeorgeGally/creative_coding

Grid creation is pretty simple really. We have the number of items we want horizontally, and vertically, as well as the grid’s width and height. Throw in a start position for good measure to place it nicely where we want it on the screen and we have our grid.

So let’s pass in those conditions to our grid creation function:

function Grid(_num_items_horiz, _num_items_vert, _grid_w, _grid_h, _startx, _starty){

return this;

}

One thing I learned recently from Javascript Hacks for Hipsters is that your can use || to test is if a variable is undefined, instead of using an if statement, like so:

// usual way// if (_num_items_horiz == undefined) _num_items_horiz = 1;

// hipster wayvar num_items_horiz = _num_items_horiz || 1;

We create a createGrid() function that loops through the x and y points to create our grid, and pushes them onto an array:

function Grid(_num_items_horiz, _num_items_vert, _grid_w, _grid_h, _startx, _starty){

// these are temp variables to store the original _num_items// variables passed in the constructor var num_items_horiz = _num_items_horiz || 1;var num_items_vert = _num_items_vert || 1;

this.horiz = 0;this.vert = 0;

this.start = {x: _startx || 0 , y: _starty || 0};

this.grid_w = _grid_w || w;this.grid_h = _grid_h || h;

// empty arrays to store our grid positionsthis.x = [];this.y = [];

//work out how far apart the grid items are this.spacing_x = this.grid_w / this.num_items_horiz;this.spacing_y = this.grid_h / this.num_items_vert;

this.createGrid = function() {for (var _y = 0; _y < this.grid_h; _y+=this.spacing_y) {for (var _x = 0; _x < this.grid_w; _x+=this.spacing_x) {

  _// we use spacing/2 so that the grid fits nicely   
  // in our defined area _**  
  this.x.push(this.start.x + this.spacing\_x/2 + \_x);  
  this.y.push(this.start.y + this.spacing\_y/2 + \_y);  
 }  

}**

createGrid();return this;

}

The only thing left to do was to create an add() function, so items can be added on the fly, so the final code look like this:

function Grid(_num_items_horiz, _num_items_vert, _grid_w, _grid_h, _startx, _starty){

if (_num_items_horiz == undefined) _num_items_horiz = 1;if (_num_items_vert == undefined) _num_items_vert = 1;var _horiz = _num_items_horiz || 1;var _vert = _num_items_vert || 1;

this.spacing_x;this.spacing_y;

this.num_items_horiz = 0;this.num_items_vert = 0;

this.start = {x: _startx || 0 , y: _starty || 0};

this.grid_w = _grid_w || w;this.grid_h = _grid_h || h;

this.x = [];this.y = [];

this.add = function(_horiz, _vert) { // if we don't pass a value just add 1 to the size this.num_items_horiz += _horiz || 1;this.num_items_vert += _vert || 1;this.spacing_x = this.grid_w / this.num_items_horiz;this.spacing_y = this.grid_h / this.num_items_vert;this.createGrid();return this;

}

this.setStart = function(_x, _y) {this.start = {x: _x || 0 , y: _y || 0};createGrid();return this;}

this.createGrid = function() {for (var _y = 0; _y < this.grid_h; _y+=this.spacing_y) {for (var _x = 0; _x < this.grid_w; _x+=this.spacing_x) {this.x.push(this.start.x + this.spacing_x/2 + _x);this.y.push(this.start.y + this.spacing_y/2 + _y);}};}

this.add(_horiz, _vert);

return this;

}

Ok, end of the boring stuff. Let’s put our grid to use.

Let’s use a particle system to make it easy (if you haven’t been following along, see here on how to create one). Let’s build a grid of particles like so:

To create our grid we could now do something like this:

// create gridvar num_grid_horiz = 10;var num_grid_vert = 10;var grid_w = 400;var grid_h = 400;var grid_startx = w/2 - grid_w/2;var grid_starty = h/2 - grid_h/2;

var grid = new Grid(num_grid_horiz, num_grid_vert, grid_w, grid_h, grid_startx, grid_starty);

This will give us back a grid object can contains an array of x and y positions. Which are now easy to work with. We just iterate through our grid to get their positions, grid.x[0] and grid.y[0] to get their first position, grid.x[1] and grid.y[1] to get their second position,etc. The complete code looks like this:

var ctx = createCanvas("canvas1");

// create gridvar num_grid_horiz = 10;var num_grid_vert = 10;var grid_w = 400;var grid_h = 400;var grid_startx = w/2 - grid_w/2;var grid_starty = h/2 - grid_h/2;

var grid = new Grid(num_grid_horiz, num_grid_vert, grid_w, grid_h, grid_startx, grid_starty);

console.log(grid);

// create particlesvar balls = [];var number_of_balls = num_grid_horiz * num_grid_vert;

for (var i = 0; i < number_of_balls; i++) {addBall(grid.x[i], grid.y[i]);}

function addBall(_x, _y){var ball = {x: _x,y: _y,speed_x: random(1),speed_y: random(1),size: 20,colour: rgb(0),angle: random(360)}balls.push(ball);}

function draw(){ctx.background(235, 0.5);moveBall();drawBall();}

function moveBall(){

for (var i = 0; i < balls.length; i++) {var b = balls[i];b.size = random(2, 30);}

}

function drawBall(){

for (var i = 0; i < balls.length; i++) {var b = balls[i];ctx.fillStyle = b.colour;ctx.fillEllipse(b.x, b.y, b.size);}

}

And there we have it. Let’s build on this and create something a little more complicated:

To create the image above, which is just a slight variation of header image. We change the size of the particle with a sin oscillation, and move our particle using sin and cos as per the Math.sin and Math.cos tutorial:

var ctx = createCanvas("canvas1");

// create gridvar num_grid_horiz = 20;var num_grid_vert = 10;

var grid = new Grid(num_grid_horiz, num_grid_vert);

console.log(grid);

// create particlesvar balls = [];var number_of_balls = num_grid_horiz * num_grid_vert;for (var i = 0; i < number_of_balls; i++) {addBall(grid.x[i], grid.y[i]);}

function addBall(_x, _y){var ball = {x: _x,y: _y,startx: _x,starty: _y,speed_x: 1,speed_y: random(1),size: 20,colour: rgb(0),angle: random(360)}balls.push(ball);}

function draw(){ctx.background(235, 0.1);moveBall();drawBall();}

function moveBall(){

for (var i = 0; i < balls.length; i++) {var b = balls[i];** b.angle += b.speed_x/10;b.x = b.startx + Math.cos(b.angle) * 20;b.y = b.starty + Math.sin(b.angle) * 20;b.size = 5 + Math.sin(b.angle) * 20;**}

}

function drawBall(){for (var i = 0; i < balls.length; i++) {var b = balls[i];ctx.fillStyle = b.colour;ctx.fillEllipse(b.x, b.y, b.size);}}

And that’s it. We’re done. Happy repetitions.

As usual the full code is available on my github, this article is part 11 (be sure to do a pull every now and then, because I’m updating things often): https://github.com/GeorgeGally/creative_coding

See previous editions of Introduction to Creative Coding here: https://hackernoon.com/@radarboy3000

Follow me on Instagram here: https://www.instagram.com/radarboy3000/

Follow me on Twitter here: https://twitter.com/radarboy_japan

And be nice and like my Facebook Page to get tutorial and workshop updates here: https://www.facebook.com/radarboy3000


Published by HackerNoon on 2017/03/03