Drawing Shapes
Every shape function in p5.js — rectangles, ellipses, lines, arcs, and custom polygons.
The basic shape functions
p5.js provides a set of built-in shape functions that cover most drawing needs:
function setup() {
createCanvas(600, 500);
background(25);
noLoop();
stroke(200);
strokeWeight(1.5);
fill(80, 120, 200);
// Line — no fill, just stroke
line(50, 50, 200, 50);
// Rectangle: rect(x, y, w, h)
rect(50, 80, 120, 70);
// Ellipse: ellipse(x, y, w, h) — x,y is the CENTRE
ellipse(200, 200, 120, 80);
// Circle: circle(x, y, diameter)
circle(400, 200, 100);
// Triangle: triangle(x1,y1, x2,y2, x3,y3)
triangle(300, 300, 250, 420, 350, 420);
// Quad: quad(x1,y1, x2,y2, x3,y3, x4,y4)
quad(420, 300, 500, 320, 520, 420, 400, 430);
}
rect() vs rectangle origins
By default, rect(x, y, w, h) treats x,y as the top-left corner. But ellipse(x, y, w, h) treats x,y as the centre.
This inconsistency is historical — Processing inherited it from its inspirations. You can change the rectangle mode:
rectMode(CENTER); // x,y is the centre
rectMode(CORNER); // x,y is top-left (default)
rectMode(CORNERS); // x,y is top-left, third/fourth args are bottom-right
Similarly for ellipses:
ellipseMode(CENTER); // default — x,y is centre
ellipseMode(CORNER); // x,y is top-left of the bounding box
Rounded rectangles
Pass a fifth argument to rect() for rounded corners:
rect(50, 50, 200, 100, 16); // all corners rounded 16px
rect(50, 200, 200, 100, 16, 16, 0, 0); // top corners only
Arcs
// arc(x, y, w, h, startAngle, stopAngle, mode)
arc(300, 250, 150, 150, 0, PI, OPEN); // half circle, open
arc(300, 250, 150, 150, 0, PI, CHORD); // chord line closes it
arc(300, 250, 150, 150, 0, PI, PIE); // pie slice
// Angles use radians: 0 = right, PI/2 = bottom, PI = left, TWO_PI = full circle
// Convert degrees: radians(90) = PI/2
Custom shapes with beginShape()
For any polygon or freeform path, use beginShape() / endShape():
beginShape();
vertex(200, 100);
vertex(300, 50);
vertex(400, 100);
vertex(380, 200);
vertex(220, 200);
endShape(CLOSE); // CLOSE connects the last vertex back to the first
Curved shapes
Use curveVertex() for Catmull-Rom splines (smooth curves through control points):
beginShape();
curveVertex(100, 200); // phantom start point (not drawn)
curveVertex(150, 100);
curveVertex(300, 250);
curveVertex(450, 100);
curveVertex(500, 200);
curveVertex(550, 250); // phantom end point (not drawn)
endShape();
Or bezierVertex() for Bezier curves:
beginShape();
vertex(100, 200);
bezierVertex(150, 50, 350, 50, 400, 200);
endShape();
bezierVertex(cp1x, cp1y, cp2x, cp2y, anchorX, anchorY) — the first four values are control points that pull the curve.
Point and lines
point(x, y); // single pixel (use strokeWeight to make it bigger)
line(x1, y1, x2, y2); // straight line between two points
strokeWeight and strokeCap
strokeWeight(4); // line thickness in pixels
strokeCap(ROUND); // ROUND, SQUARE, or PROJECT (default)
strokeJoin(ROUND); // how line corners join: ROUND, MITER, BEVEL
A composition exercise
Combine shapes to build something recognisable:
function setup() {
createCanvas(400, 400);
noLoop();
background(200, 230, 255); // sky blue
}
function draw() {
// Sun
fill(255, 220, 50);
noStroke();
circle(320, 80, 80);
// Ground
fill(100, 180, 80);
rect(0, 300, 400, 100);
// House body
fill(230, 200, 160);
stroke(150);
strokeWeight(1);
rect(120, 200, 160, 100);
// Roof
fill(180, 80, 80);
noStroke();
triangle(100, 200, 200, 120, 300, 200);
// Door
fill(100, 70, 40);
rect(178, 250, 44, 50, 4, 4, 0, 0);
// Window
fill(180, 220, 255);
stroke(100);
strokeWeight(1);
rect(130, 215, 35, 35, 2);
rect(235, 215, 35, 35, 2);
}
Key takeaways
rect(x, y, w, h)— top-left corner by default; userectMode(CENTER)to changeellipse(x, y, w, h)andcircle(x, y, d)— centred by default- Arcs take start/stop angles in radians and an optional mode (OPEN, CHORD, PIE)
beginShape()/endShape(CLOSE)lets you draw any polygoncurveVertex()andbezierVertex()create smooth curves inside shapesstrokeWeight(),strokeCap(), andstrokeJoin()control line appearance