Simple P5.js Mandalas

I’m always looking for fun “absolutely first experience with code” activities - things that feel satisfying without requiring too much background. These kinds of activities aren’t about teaching specific skills as much as they are about getting kids excited about what’s possible with programming. I’ve often used drawing with shapes as this onramp, but laying out shapes requires an understanding of and comfort with the coordinate plane that might turn off students who are math-phobic.

I was ecstatic when I recently discovered the p5.Polar library for p5.js, which makes it dead easy to create really intricate geometric patterns in the style of a Mandala. Depending on the age and ability level of the students you could either

Using p5.Polar

Compare the two following programs:


See inside
1
2
3
4
5
6
7
8
9
function setup() {
  createCanvas(400, 400);
  noFill();
}

function draw() {
  background("white");
  rect(150, 150, 100, 100);
}

See inside
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function setup() {
  createCanvas(400, 400);
  noFill();
}

function draw() {
  background("white");
  setCenter(200, 200);
  polarSquares(10, 100, 50);
}

In terms of code complexity they’re pretty similar - the second program has one more line of code, calling the setCenter() function to put our mandala in the center of the canvas. While the code is of a similar complexity, the output from the second program is drastically more visually interesting and satisfying. Moreover, experimenting with the parameters of the polarSquares() function will generate greater variability in output that experimenting with the parameters of rect(). So what can we do with this?

3D Printers, Lasers, and CNCs

One of my favorite ways to supercharge simple student code is to turn it physical. p5.Polar has already done a lot to make a lot of visual interest with only a little bit of code, which makes a physical representation of that code even more exciting.

The easiest route here is to do 2.5D modelling, that is to take a 2D vector file and either extrude it up (in the case of additive tools like 3D printing) or engrave it down (in the case of subtractive tools like laser cutters or CNC). All we need is to get our image out into a vector file out p5, which can be done with the p5 SVG runtime. Take a look at the next example, which includes both the p5.Vector library and the p5 SVG runtime.


See inside
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function setup() {
  createCanvas(400, 400, SVG);
  noFill();
}

function draw() {
  background("white");
  setCenter(width/2, height/2);

  /* Experiment with the numbers here! */
  polarEllipses(4, 50, 50, 50);
  polarTriangles( 8, 50, 100);
  noLoop();
}

/* Click on your drawing to download a copy */
function mouseClicked() {
  save("myDesign.svg");
}

Some important elements of this code.

  • First, on line 2 note that the createCanvas() function has been given a third parameter SVG - this tells it to produce SVG output instead of a standard p5 canvas.
  • Next, the noLoop() on line 13 makes sure the draw() function is only run once. The SVG runtime can struggle to save an SVG while the draw loop is running, and it can really be a problem if you accidentally try and save the file from within the draw loop (ask me how I know).
  • Finally, I’ve put the save() command inside a mouse click handler. This allows the student to save an image they like by clicking on it, which I’ve found more conducive to experimentation than trying to make the script download an SVG every single time.

You’ll likely need to do some post-processing on the SVGs that get pumped out of p5 depending on software and tooling stack. I’ve had success with the following workflow:

  • Bring the SVG into Illustrator or Inkscape and use the background shape to crop down any shapes that extend too far outside the canvas.
  • Import the edited SVG into Easel.
  • Engrave on my CNC using a v bit.

Try it out!

If you’re curious, I put together a quick resource page for this project that provides a handful of starter projects, student guidance, and a bit of documentation for p5.Vector. Give it a try with your students and let me know how it goes!


See Also