DEV Community

Cover image for Randomly Generated Grid | Creative Coding tutorial with Javascript and Canvas Sketch
Ahmad Altaf
Ahmad Altaf

Posted on

Randomly Generated Grid | Creative Coding tutorial with Javascript and Canvas Sketch

For randomly generated grid of colorful squares, we will use three libraries.

  • Canvas Sketch
  • Canvas Sketch Utils
  • Nice Color Palettes

If haven’t installed these libraries yet, you will need Node and NPM installed on your system. After installing them, you can use the documentation available on the NPM pages of the libraries to install them onto your computer.

Step:1

In the terminal write this command.

canvas-sketch-cli <nameOfTheFile>.js --new --open
Enter fullscreen mode Exit fullscreen mode

This will create a new file with the given name and open a instance in the browser, where you can see all the changes as soon as you save your code.

The created file will have following code pre-written:

const canvasSketch = require('canvas-sketch');

const settings = {
  dimensions: [ 2048, 2048 ]
};

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white';
    context.fillRect(0, 0, width, height);
  };
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Add the following code after the first line. This will import all the libraries we need for this artwork.

const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')
Enter fullscreen mode Exit fullscreen mode

Step:2

Start by creating a function above sketch() function, named girdGeneration().

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

//Create this function
const gridGeneration = () => {

}

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white';
    context.fillRect(0, 0, width, height);
  };
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Step:3

Define two constants in girdGeneration() function, named points(array) and count.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

const gridGeneration = () => {
    const points = []
    const count = 5


}

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white';
    context.fillRect(0, 0, width, height);
  };
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Next create a Nested For-Loop.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

const gridGeneration = () => {
    const points = []
    const count = 5

    for(let i = 0; i < count; i++){
        for(let j = 0; j < count; j++){
        }       
    }

}

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white';
    context.fillRect(0, 0, width, height);
  };
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Step:4

Inside the nested loop, define two constants (for example u and v). Set the values like following. Then use array .push() method to add the values of u and v to the array points. Lastly return the array Points.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

const gridGeneration = () => {
    const points = []
    const count = 5

    for(let i = 0; i < count; i++){
        for(let j = 0; j < count; j++){
            const u = i/(count-1)
            const v = j/(count-1)
            points.push([u, v])
        }       
    }
    return points
}

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white';
    context.fillRect(0, 0, width, height);
  };
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Step5:

Create a constants named points and margins after the gridGeneration() function. We will use it to create gap between the artwork and the border. Inside the sketch function using forEach loop, write the following code.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

const gridGeneration = () => {
    const points = []
    const count = 5

    for(let i = 0; i < count; i++){
        for(let j = 0; j < count; j++){
            const u = i/(count-1)
            const v = j/(count-1)
            points.push([u, v])
        }       
    }
    return points
}

//Create these constants
const points = gridGeneration()
const margins = 400

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white'
    context.fillRect(0, 0, width, height)

    //Write this code
    points.forEach(([u,v]) => {
            const x = lerp(marigns, width-margins, u)
            const y = lerp(margins, hieght-margins, v)
        }

  }
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Step6:

Now we will draw our actual grid. Beneath the constants x and y, start creating the squares with context.beginPath() method.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

const gridGeneration = () => {
    const points = []
    const count = 5

    for(let i = 0; i < count; i++){
        for(let j = 0; j < count; j++){
            const u = i/(count-1)
            const v = j/(count-1)
            points.push([u, v])
        }       
    }
    return points
}

const points = gridGeneration()

const margins = 400

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white'
    context.fillRect(0, 0, width, height)

      points.forEach(([u,v]) => {
            const x = lerp(margins, width-margins, u)
            const y = lerp(margins, height-margins, v)

            context.beginPath()
            context.rect(x, y, 20, 20) //rect method takes 4 arguments (x co-ordinate, y co-ordinate, width of rectange, height of rectangle)
            context.fillStyle = "black"
            context.fill()
        })

  }
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

It is important to use fillStyle before fill() method, otherwise it will not render properly. After these step you will something that looks similar to this.

Square Grid with count of 5

You can increase the numbers of squares on screen by increasing the count variable, and size of squares by increasing the width and height arguments in the rect method. Here, I am using 30 for count and 40 for width & height.

Square Grid with count of 30

Step7:

To add random colors on each refresh, we will need to tweak our code a bit. Above the gridGeneration() function, declare a new constant palette. Inside gridGeneration() and points.push() make the following changes.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

//Declare this constant
const palette = random.pick(palettes)

const gridGeneration = () => {
    const points = []
    const count = 30

    for(let i = 0; i < count; i++){
        for(let j = 0; j < count; j++){
            const u = i/(count-1)
            const v = j/(count-1)
            //Change previous code to this
            points.push({
            position: [u,v],
            color: random.pick(palette)
            })
        }       
    }
    return points
}

const points = gridGeneration()

const margins = 400

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white'
    context.fillRect(0, 0, width, height)

        //Change previous code to this
      points.forEach((data) => {
            const {position, color} = data
            const [u, v] = position
            const x = lerp(margins, width-margins, u)
            const y = lerp(margins, height-margins, v)

            context.beginPath()
            context.rect(x, y, 40, 40) //rect method takes 4 arguments (x co-ordinate, y co-ordinate, width of rectange, height of rectangle)
            context.fillStyle = "black"
            context.fill()
        })

  }
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Step8:

Now change the context.fillStyle() value to color. Your final code should look like this. If you are having any error check Console in DevTools.

const canvasSketch = require('canvas-sketch');
const { lerp } = require('canvas-sketch-util/math')
const random = require('canvas-sketch-util/random')
const palettes = require('nice-color-palettes')

const settings = {
  dimensions: [ 2048, 2048 ]
};

const palette = random.pick(palettes)

const gridGeneration = () => {
    const points = []
    const count = 30

    for(let i = 0; i < count; i++){
        for(let j = 0; j < count; j++){
            const u = i/(count-1)
            const v = j/(count-1)
            points.push({
                color: random.pick(palette),
                position: [u,v]
            })
        }       
    }
    return points
}

const points = gridGeneration()

const margins = 400

const sketch = () => {
  return ({ context, width, height }) => {
    context.fillStyle = 'white'
    context.fillRect(0, 0, width, height)

      points.forEach((data) => {
            const {
            position,
            color} = data

            const [u, v] = position
            const x = lerp(margins, width-margins, u)
            const y = lerp(margins, height-margins, v)

            context.beginPath()
            context.rect(x, y, 40, 40) //rect method takes 4 arguments (x co-ordinate, y co-ordinate, width of rectange, height of rectangle)
            context.fillStyle = color
            context.fill()
        })

  }
};

canvasSketch(sketch, settings);
Enter fullscreen mode Exit fullscreen mode

Here are the final results:

Result#1

Result#2

Result#3

Top comments (0)