Processing Starter Article 6

Color & Style

Control color using RGB and HSB modes, work with transparency, store colors in variables, and blend colors smoothly with lerpColor().

⏱ 13 min processing color RGB HSB fill stroke style

How Processing Handles Color

Color in Processing is defined numerically. Every function that affects color takes numbers as arguments — no hex codes, no CSS color names (unless you convert them). The two main systems are RGB (Red, Green, Blue) and HSB (Hue, Saturation, Brightness). Processing defaults to RGB.

RGB Color Mode

In RGB mode, colors are defined by three values: red, green, and blue. By default each channel ranges from 0 to 255.

fill(255, 0, 0);      // pure red
fill(0, 255, 0);      // pure green
fill(0, 0, 255);      // pure blue
fill(255, 255, 0);    // yellow (red + green)
fill(255, 0, 255);    // magenta (red + blue)
fill(0, 255, 255);    // cyan (green + blue)
fill(255, 255, 255);  // white
fill(0, 0, 0);        // black
fill(128, 128, 128);  // mid gray

A single argument is shorthand for equal R, G, and B — a grayscale value:

fill(200);   // light gray — same as fill(200, 200, 200)
fill(0);     // black
fill(255);   // white

Transparency (Alpha)

Add a fourth argument to any color function to control transparency. This is called the alpha channel:

fill(255, 0, 0, 255);  // fully opaque red
fill(255, 0, 0, 128);  // half-transparent red
fill(255, 0, 0, 30);   // nearly invisible red

Alpha ranges from 0 (completely transparent) to 255 (completely opaque), matching the other channels.

Transparency is powerful for layering. By drawing shapes with low alpha in draw() without clearing the background, you create a trail or accumulation effect:

void setup() {
  size(500, 500);
  background(0);
}

void draw() {
  // No background() call — let shapes accumulate

  fill(255, 150, 0, 20);  // very transparent orange
  noStroke();
  ellipse(mouseX, mouseY, 60, 60);
}

Move your mouse around. The translucent circles stack up, building intensity where you linger.

fill(), stroke(), and background()

These three functions set the color used for subsequent drawing operations:

fill(r, g, b);           // color used for shape interiors
fill(r, g, b, a);        // with alpha
stroke(r, g, b);         // color used for shape outlines and lines
stroke(r, g, b, a);      // with alpha
background(r, g, b);     // fills entire canvas — ignores alpha
void draw() {
  background(30, 30, 50);     // dark blue background

  stroke(200, 200, 255);      // light blue outline
  strokeWeight(2);
  fill(100, 50, 200, 180);    // semi-transparent purple fill

  ellipse(width / 2, height / 2, 200, 200);
}

strokeWeight()

Controls line thickness in pixels. Applies to outlines of shapes and to line() and point():

strokeWeight(1);   // hairline (default)
strokeWeight(4);   // medium
strokeWeight(10);  // thick

Storing Colors in Variables

Use the color data type to store a color value:

color sky = color(135, 206, 235);
color grass = color(34, 139, 34);
color sun = color(255, 220, 50);

void draw() {
  background(sky);

  fill(grass);
  noStroke();
  rect(0, height * 0.7, width, height * 0.3);  // ground

  fill(sun);
  ellipse(width * 0.8, height * 0.15, 80, 80);
}

You can also extract individual channels from a color:

color c = color(180, 100, 50);
float r = red(c);    // 180.0
float g = green(c);  // 100.0
float b = blue(c);   // 50.0
float a = alpha(c);  // 255.0 (fully opaque)

lerpColor() for Smooth Blending

lerpColor(c1, c2, amount) blends between two colors. The amount argument is a value from 0.0 (fully the first color) to 1.0 (fully the second color):

color cold = color(0, 100, 255);   // blue
color warm = color(255, 80, 0);    // orange

void draw() {
  background(20);

  // Use mouse x to blend from cold to warm
  float t = mouseX / float(width);   // t goes 0.0 to 1.0 across the canvas
  color blended = lerpColor(cold, warm, t);

  fill(blended);
  noStroke();
  ellipse(width / 2, height / 2, 200, 200);
}

lerpColor() is essential for smooth color transitions in animations. You’ll also see lerp() — the same concept but for single numbers — used constantly:

float lerp(float start, float stop, float amount)

HSB Color Mode

RGB is intuitive for mixing light, but it’s awkward when you want to “make this color slightly warmer” or “cycle through all the hues.” For that, HSB mode is far more natural.

Switch to HSB with colorMode():

colorMode(HSB, 360, 100, 100);

The three arguments after HSB define the range for each channel:

  • H (Hue): 0–360, representing the color wheel (0 = red, 120 = green, 240 = blue, 360 = red again)
  • S (Saturation): 0–100, from gray (0) to fully saturated (100)
  • B (Brightness): 0–100, from black (0) to full brightness (100)

Hue Cycling for Rainbow Effects

HSB mode makes it trivial to cycle through the rainbow:

void setup() {
  size(600, 200);
  colorMode(HSB, 360, 100, 100);
  noStroke();
}

void draw() {
  background(0, 0, 10);  // near-black in HSB

  for (int x = 0; x < width; x++) {
    float hue = map(x, 0, width, 0, 360);  // 0 to 360 across width
    float hueShift = (hue + frameCount) % 360;  // animate the shift
    fill(hueShift, 90, 95);
    rect(x, 0, 1, height);
  }
}

This draws the full spectrum animated — each column gets a hue based on its x position, shifted by frameCount to make it scroll.

Combining HSB with fill()

When HSB mode is active, ALL color functions use the new system:

colorMode(HSB, 360, 100, 100);

fill(0, 80, 90);    // bright red
fill(120, 70, 85);  // medium green
fill(200, 50, 60);  // muted teal

Switching back to RGB:

colorMode(RGB, 255);

You can switch between modes mid-sketch if you need to — but it’s clearer to pick one and stick with it.

noFill() and noStroke()

These remove the fill or stroke entirely until you call fill() or stroke() again:

noFill();    // shapes are hollow — only outline drawn
noStroke();  // no outline — only fill drawn

A Complete Color Example

This sketch draws concentric rings with hues that rotate over time, demonstrating HSB, lerpColor, and alpha together:

void setup() {
  size(500, 500);
  colorMode(HSB, 360, 100, 100, 100);  // last 100 = alpha range
  noStroke();
}

void draw() {
  fill(0, 0, 8, 20);  // dark, semi-transparent bg creates trail
  rect(0, 0, width, height);

  int rings = 12;
  for (int i = rings; i > 0; i--) {
    float t = float(i) / rings;
    float hue = (frameCount * 0.5 + t * 120) % 360;
    float sat = 80;
    float bri = map(t, 0, 1, 40, 100);
    float diameter = t * 400;

    fill(hue, sat, bri, 70);
    ellipse(width / 2, height / 2, diameter, diameter);
  }
}

Run this and watch the color rings pulse and shift. The frameCount * 0.5 term slowly advances the hue base, making the whole composition rotate through the spectrum over time.

In the next tutorial, you’ll learn to declare variables in Java, animate values over time, and build a complete bouncing ball sketch from scratch.