In last few months, apart from creating Koonchi, I’ve developed a strong affection for Generative Art.
“Generative Art often refers to algorithmic art (algorithmically determined computer generated artwork)” — Wikipedia
Also known as Creative Coding, it is a mix of creativity and everything a modern world computers has to offer. I’ve been working professionally as a Software Engineer for 8+ years now, but it is still hard for me to fathom why I did not think writing code to create art. But as they say better late than never, so let’s begin our adventure.
I plan to write a series of articles about my journey through creative coding, and the first step in this process is to explore HML5
How to Get Started with HTML5 Canvas?
It is a two step process.
Step 1: Add
<canvas> element to your HTML document, like —
const canvas = document.querySelector("#myCanvas")
const ctx = canvas.getContext("2d")
What is a Context?
How to set Width and Height of Canvas?
<canvas id="myCanvas" width="200" height="300"></canvas>
const canvas = document.querySelector("#myCanvas")canvas.width = 200
canvas.height = 300// To set width and height of current viewport do// canvas.width = window.innerWidth
// canvas.height = window.innerHeight
The Grid or Coordinate Space
It is important to understand the coordinate space of canvas, if you want elements to be positioned as desired. Top left of canvas represents (0,0) or origin coordinate. All the elements on canvas are placed with reference to this origin. 1 point on grid is roughly equivalent to 1px.
Pic 1 further elaborates: we have red border around our canvas and we have drawn a rectangle of 100px width and height with a stroke of blue.
Providing x and y coordinates would translate the element relative to the canvas’ origin coordinates. As shown in Image 2, our rectangle has moved 20 pixels to the right and bottom as we have provided the values of x and y as 20.
How to Draw Basic Shapes?
It is easy to draw basic shapes like rectangle, triangle, square, circle, polygon or a just a simple line between two points. But by default Canvas provides a method only to draw rectangle. However, rest of shapes can be created by joining points using path API, and a combination of line and arc APIs. Let’s look at some code examples to further elaborate.
Rectangle: Rectangles can be drawn using
fillRect(x, y, width, height) and
strokeRect(x, y, width, height) method on context.
stroke are ink methods and each case it means to draw a rectangle with a filled color, or to draw a rectangular outline of a color. The default color is black.
const ctx = canvas.getContext("2d")// fill color of rectangle
ctx.fillStyle = "tomato" // draw rectangle, and fill it with "tomato" color
// x = 10
// y = 20
// width = 200
// height = 300
ctx.fillRect(10, 20, 200, 300)// now change style to stroke
ctx.strokeStyle = "green" // draw rectangle with "green" color stroke (no fill)
ctx.strokeRect(100, 100, 200, 100)
Circle: As we mentioned earlier there is no straight forward method to create a circle, but we can use a combination of path APIs and arc method to draw our circle. Let’s understand a little more about path:
“A path is list of points connected to form different shapes”.
This means a path can be formed between two given points on screen. It can be a straight line or curved arc or can be any shape or color. There are three steps to follow to create a shape using path:
beingPath()method on context a create a new path. Once a path is created all future commands to draw are applied on this path.
- Next create a path using drawing methods, like
rect, etc. Refer MDN for list of all available methods that used with path.
- Once path has been created it needs to actually be rendered on canvas; we can do that using ink methods
Let’s get back drawing our circle. We have to use
arc(x, y, radius, startAngle, endAngle) method on context to draw our circle. If we try to recollect basic geometry, to draw a circle using a protractor we need a radius, and a start & end angle. A semi-circle starts at angle 0 and ends at 180 degree or PI radians. So a full-circle extends further and just ends at 2*PI or 360 degrees. This exact concept can be used to draw a circle using
// Step 1. Invoke path method
// Step 2. Creating a circular path
// x = 300
// y = 320
// start angle = 0
// end angle = 360 or 2*PI
ctx.arc(300, 320, 75, 0, 2*Math.PI)
// Fill with Lavender color
ctx.fillStyle = "Lavender"
//Step 3. Now ink on canvas
Line: To draw a line between two points we use
lineTo(x, y)methods. If we consider two points A & B with x and y coordinates respectively, then
moveTo acts as a position of A on canvas, while
lineTo as position of point B.
ctx.beginPath(); // Point A
// Point B
ctx.strokeStyle = "DeepPink"
Triangle: Triangle is simply three lines connected together. We are going to use a special path method called as
closePath() to complete our triangle.
closePath basically adds a straight line from end coordinate to the start coordinate inside a path. If we assume a triangle is made of three points A, B & C, then we can draw our triangle like:
// Point A
// Point B
// Point C
// Join C & A
ctx.closePath() ctx.strokeStyle = "Navy"
So that’s it! Creative Coding is a lot more involved and we are just scratching the surface. In next few articles we will look at adding randomness, noise, vectors, and many more concepts, to generate an artwork. So stay tuned!
CodePen below provides complete sample of all the code mentioned in this post:
A bonus pen with all the basic elements placed with pleasing colors:
Since I have started exploring my understanding of basic maths have flourished. I’ve always wondered where am I going to apply concepts of physics, geometry and complex algorithms that I have learnt in school. Now I guess I have an answer!
Let your creative spirits go wild and generate something awesome!