Learn Creative Coding (#2) - Your First Sketch: Shapes, Colors, and the Canvas

avatar
(Edited)

Learn Creative Coding (#2) - Your First Sketch: Shapes, Colors, and the Canvas

banner

What will I learn

  • How the p5.js coordinate system works;
  • drawing shapes: rectangles, ellipses, lines, triangles, arcs;
  • fill, stroke, and transparency;
  • RGB and how to think about color in code;
  • combining shapes into a simple composition.

Requirements

  • A modern web browser;
  • Read episode #1 of this series (or know how to open the p5.js editor).

Difficulty

  • Beginner

Curriculum (of the Learn Creative Coding Series):


Learn Creative Coding (#2) - Your First Sketch: Shapes, Colors, and the Canvas

Before we can make beautiful things, we need to understand the canvas we're drawing on.

Last episode we threw random circles at the screen and it looked cool. But we were mostly guessing. This time we're going to understand exactly what we're telling the computer to draw, and where.

The coordinate system

The p5.js canvas is a grid. The top-left corner is position (0, 0). X increases to the right. Y increases downward.

That Y-going-down thing trips people up. In math class, Y goes up. In computer graphics, Y goes down. Just accept it and move on. :-)

function setup() {
  createCanvas(400, 400);
  background(240);
  
  // mark the origin
  fill(255, 0, 0);
  noStroke();
  ellipse(0, 0, 10, 10);  // top-left corner
  
  // mark the center
  fill(0, 0, 255);
  ellipse(200, 200, 10, 10);  // center
  
  // mark the bottom-right
  fill(0, 180, 0);
  ellipse(400, 400, 10, 10);  // only a quarter visible!
}

Run this. Red dot in the corner, blue in the middle, green barely visible in the bottom-right. Everything in p5.js uses this coordinate system.

Shapes

p5.js gives you a bunch of shape functions. Here are the ones you'll use 90% of the time:

Rectangle

rect(x, y, width, height);

By default, x and y are the top-left corner. You can change this with rectMode(CENTER) to make x and y the center point instead.

function setup() {
  createCanvas(400, 400);
  background(240);
  
  fill(100, 150, 255);
  rect(50, 50, 120, 80);  // top-left mode (default)
  
  rectMode(CENTER);
  fill(255, 150, 100);
  rect(300, 200, 120, 80);  // center mode
}

Ellipse

ellipse(x, y, width, height);

Ellipse draws from the center by default (opposite of rect - I know, it's weird). Equal width and height gives you a circle.

function setup() {
  createCanvas(400, 400);
  background(240);
  
  fill(200, 100, 200);
  ellipse(200, 200, 150, 150);  // circle
  
  fill(100, 200, 150);
  ellipse(200, 200, 200, 80);   // oval
}

Line

line(x1, y1, x2, y2);

Lines don't have fill, only stroke. The strokeWeight() function controls thickness.

function setup() {
  createCanvas(400, 400);
  background(240);
  
  stroke(50);
  strokeWeight(1);
  line(50, 50, 350, 350);  // thin diagonal
  
  stroke(200, 50, 50);
  strokeWeight(5);
  line(50, 350, 350, 50);  // thick diagonal, other direction
}

Triangle

triangle(x1, y1, x2, y2, x3, y3);

Three points. That's it.

function setup() {
  createCanvas(400, 400);
  background(240);
  
  fill(255, 200, 50);
  triangle(200, 50, 50, 350, 350, 350);
}

Arc

arc(x, y, w, h, start, stop);

Arcs use radians, not degrees. p5.js gives you constants: PI, HALF_PI, QUARTER_PI, TWO_PI. Or use radians(degrees) to convert.

function setup() {
  createCanvas(400, 400);
  background(240);
  
  fill(100, 200, 255);
  arc(200, 200, 200, 200, 0, PI + HALF_PI);  // pac-man-ish
}

Fill and Stroke

Every shape has two visual properties: fill (the inside color) and stroke (the outline).

fill(r, g, b);       // set fill color
noFill();             // no fill, just outline
stroke(r, g, b);     // set stroke color
noStroke();           // no outline
strokeWeight(n);      // outline thickness in pixels

These work like a "state machine" - once you set a fill, everything after uses that fill until you change it.

function setup() {
  createCanvas(400, 400);
  background(240);
  
  // red fill, no outline
  fill(220, 60, 60);
  noStroke();
  ellipse(100, 200, 100, 100);
  
  // no fill, blue outline
  noFill();
  stroke(60, 60, 220);
  strokeWeight(3);
  ellipse(200, 200, 100, 100);
  
  // green fill + dark outline
  fill(60, 200, 60);
  stroke(20);
  strokeWeight(2);
  ellipse(300, 200, 100, 100);
}

Color and transparency

RGB colors go from 0 to 255. You can add a fourth value for alpha (transparency):

fill(255, 0, 0, 128);  // red at 50% opacity

Alpha is incredibly useful for creative coding. Layering semi-transparent shapes creates depth and richness that opaque shapes can't.

function setup() {
  createCanvas(400, 400);
  background(20);
  noStroke();
  
  // layer 20 semi-transparent circles
  for (let i = 0; i < 20; i++) {
    fill(
      100 + i * 7,     // red increases
      50,
      200 - i * 5,     // blue decreases
      40                // low opacity
    );
    ellipse(
      150 + i * 8,
      200 + sin(i) * 50,
      80 + i * 3,
      80 + i * 3
    );
  }
}

See how the overlapping creates colors that don't exist in your palette? That's the beauty of alpha blending. This is something you'll use in almost every creative coding project.

A single-value shortcut

When you pass one number to fill(), stroke(), or background(), it's a grayscale value:

fill(0);    // black
fill(128);  // middle grey
fill(255);  // white

Two values means grayscale + alpha:

fill(0, 100);    // black at ~40% opacity

Let's make something

Enough theory. Let's combine what we know into a simple geometric composition:

function setup() {
  createCanvas(500, 500);
  background(245, 240, 235);  // warm off-white
  
  noStroke();
  
  // big circle, bottom-left
  fill(35, 60, 120, 200);
  ellipse(150, 380, 280, 280);
  
  // overlapping rectangle, top-right
  fill(200, 75, 50, 180);
  rect(220, 40, 240, 300);
  
  // small circle on top of the rectangle
  fill(240, 190, 50, 220);
  ellipse(340, 200, 140, 140);
  
  // thin lines cutting across
  stroke(20, 80);
  strokeWeight(1);
  for (let i = 0; i < 12; i++) {
    line(0, i * 45, 500, i * 45 + 20);
  }
  
  // accent triangle
  noStroke();
  fill(245, 240, 235, 180);
  triangle(80, 80, 200, 40, 140, 180);
}

This gives you a layered geometric composition with overlapping shapes, transparency, and some visual rhythm from the lines. Not random, not messy - designed. Change some numbers and you get a completely different composition. That's the whole idea.

't Komt erop neer...

  • Canvas origin is top-left, Y goes down
  • Core shapes: rect(), ellipse(), line(), triangle(), arc()
  • fill() and stroke() control appearance, work like a state machine
  • The fourth color value is alpha (transparency) - use it constantly
  • Layering semi-transparent shapes is a core creative coding technique

Next episode we're adding motion. Things are about to get fun - we'll learn how draw() actually works as an animation loop and use sin() and cos() to make things move in ways that feel organic.

Sallukes! Thanks for reading.

X

@femdev



0
0
0.000
3 comments
avatar

Nice Char! (I saw your ping, just got back from the datacenter middle of the night, yesterday night snow, now icy rain ... can't wait for the summer!)

P5.js is pretty cool , years ago I was messing with it too following stuff on https://thecodingtrain.com/ , but I like you a lot more as a Creative Coding instructor (you look a lot more attractive to me as well! whahaha....)

Xxxxxx (Trusten)

0
0
0.000
avatar

Hahaha Scippie you're terrible :-) Coming back from the datacenter in icy rain at 2am, and THEN you decide to flirt in my comment section? Priorities!

But thanks, The Coding Train is great — Daniel Shiffman is a legend honestly. I just have a slightly different approach I guess, more "here's what I figured out at work" and less "HELLO FRIENDS" energy XD

Also, "more attractive"... alee, you're not so bad yourself for an old bush kangaroo ;-)

Xx

0
0
0.000
avatar

⚠️⚠️⚠️ ALERT ⚠️⚠️⚠️

HIVE coin is currently at a critically low liquidity. It is strongly suggested to withdraw your funds while you still can.

0
0
0.000