Skip to content

unsortedlove/creative-coding-for-noise-makers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Creative Coding for Noise Makers

Beginner friendly workshop exploring live coding visuals and audio. We'll use p5.js and Hydra for visuals (via P5 Live), and Strudel for live-coded music.


Program

Intro

  • What is Unsorted
  • What is creative coding
  • p5.js, Hydra, Strudel. What they are and why we use them

Audio

We'll use Strudel — a live coding environment for music, running entirely in the browser.


Video

p5.js

p5.js is a JavaScript library for creative coding, with a focus on making coding accessible for artists and beginners.

Basic setup

Every p5.js sketch has two main functions: setup() runs once at the start, and draw() runs in a loop, roughly 60 times per second.

function setup() {
  createCanvas(windowWidth, windowHeight); // the canvas fills the whole window
  background(20); // dark grey background
}

function draw() {
  // everything you draw goes here
}

createCanvas() · background()

Basic shapes

p5.js gives you simple functions to draw shapes. Coordinates start at the top-left corner: x goes right, y goes down.

line(0, 0, width, height); // diagonal line corner to corner

rect(100, 100, 200, 150); // rectangle at x:100, y:100, 200 wide, 150 tall
// rectMode(CENTER); // uncomment to draw rectangles from their center

ellipse(width / 2, height / 2, 120, 120); // circle in the center of the canvas

triangle(300, 100, 250, 200, 350, 200); // triangle with three corner points

line() · rect() · ellipse() · triangle() · rectMode()

Fill, stroke & colors

Control how shapes look with fill (inside color), stroke (outline color), and strokeWeight (outline thickness). Colors can be greyscale (one value), RGB (three values), or include alpha for transparency (four values).

fill(255, 0, 100); // bright pink fill
stroke(255); // white outline
strokeWeight(3); // 3px outline

rect(50, 50, 100, 100);

noFill(); // no fill, outline only
stroke(0, 200, 255); // cyan outline
ellipse(250, 150, 80, 80);

noStroke(); // no outline, fill only
fill(255, 200, 0, 150); // yellow, semi-transparent
ellipse(200, 120, 100, 100);

fill() · noFill() · stroke() · noStroke() · strokeWeight()

Mouse interaction

Use the mouse to make your sketches interactive. p5.js tracks the mouse position every frame.

// mouseX — current x position of the mouse
// mouseY — current y position of the mouse
// pmouseX, pmouseY — mouse position from the previous frame

line(mouseX, mouseY, pmouseX, pmouseY); // a simple drawing program!

// map() converts a value from one range to another
let brushSize = map(mouseX, 0, width, 2, 30);
strokeWeight(brushSize);

mouseX · mouseY · pmouseX · map() · strokeWeight()

Variables

Variables let you store and reuse values. Use let to declare them.

let speed = 3; // a whole number
let position = 12.5; // a decimal number
let label = "hello"; // text
let visible = true; // true or false — useful as a toggle
let points = [10, 20, 30, 40]; // an array — a list of values

let xPos = 0; // declared outside draw() so it persists between frames

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0);
  let size = 60; // declared inside draw() — resets every frame
  rect(xPos, height / 2, size, size);

  xPos += speed; // xPos increases each frame — the rectangle moves right
}
Noise

noise() generates smooth, organic random values — great for natural-looking movement.

let t = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0, 20); // slight trail effect
  let x = noise(t) * width;
  let y = noise(t + 100) * height;
  ellipse(x, y, 30, 30);
  t += 0.01; // smaller increments = smoother movement
}

noise() · random()

Advanced topics

Once you're comfortable with the basics, try these:

Random

random() gives you a surprise value every time it's called. Think of it like rolling a die, but you get to pick the range. It's the easiest way to make your sketches feel alive and unpredictable, because no two frames will ever look the same.

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0, 20); // slightly transparent black — leaves ghost trails
  let x = random(width);
  let y = random(height);
  let size = random(5, 40);
  fill(random(255), random(255), random(255), 180);
  noStroke();
  ellipse(x, y, size, size); // a new random circle every frame
}

random()

Conditionals

An if/else statement is like asking a question in your code: if something is true, do this, else, do that. It's how you make your sketch react to what's happening, like a ball bouncing off the edges of the canvas instead of flying off into the void.

let x = 200;
let speed = 3; // how many pixels the ball moves each frame

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background(0);
  fill(255);
  noStroke();
  ellipse(x, 200, 50, 50);

  x = x + speed; // move the ball

  // if the ball hits either edge, reverse direction
  if (x > width || x < 0) {
    speed = speed * -1; // this makes it bounce back
  }
}

if/else

For loops & grids

A loop lets you do something many times without writing it out over and over. Instead of placing 100 circles by hand, you tell the computer "start here, end there, and repeat." Nest two loops together: one for rows, one for columns — and you get a grid with just a few lines of code.

function setup() {
  createCanvas(windowWidth, windowHeight);
  noLoop(); // only draw once — this is a static pattern
}

function draw() {
  background(0);
  noStroke();
  let spacing = 40; // distance between each circle

  for (let x = spacing / 2; x < width; x = x + spacing) {
    for (let y = spacing / 2; y < height; y = y + spacing) {
      let d = dist(x, y, width / 2, height / 2); // distance from center
      let size = map(d, 0, 300, 30, 5); // bigger near the center
      fill(map(d, 0, 300, 255, 50), 100, 200);
      ellipse(x, y, size, size);
    }
  }
}

for · dist() · map()


Hydra

Hydra is a live coding video synthesizer that runs in the browser. Think analog video synthesis, but with code.

Key concepts
  • Sources noise(), voronoi(), osc(), plus external sources (webcam, screen, p5 canvas)
noize(3,.5).out()

voronoi(3,.5).out()

osc(5,.5,1).out()
  • Geometry rotate(), scale(), pixelate(), kaleid() to transform visuals
noize(3,.5)
.rotate(2,.3)
.out()

voronoi(3,.5)
.scale(-1.15)
.out()

noize(3,.5)
.pixelate(30,4)
.out()

osc(5,.5,1)
.kaleid(8)
.out()
  • Modulate modulate(), modulateScale() use one texture to distort another
osc(3,.5,2)
.modulate(noize(3), .2)
.out(o0)

osc()
.modulateScalee(osc(3,.5,2), .2)
.out(o0)
  • Blend blend(), add(), mult() combine layers together
//blend
osc(5,.5,1)
.blend(noize(3,.5), 2.2)
.out()

//add
noize(5,.5,1)
.add(osc(3,.5)1, 0.2)
.out()

//blend
osc(5,.5,1)
.mult(osc(5,.25,1),.3)
.out()
  • Color contrast(), thresh() colorize and modulate
//contrast
osc(3,.5,2)
.contrast(5.4)
.out()

//thresh
noise(3,0.1)
.thresh(.05,0.04)
.out()
  • Audio a.fft[] to make visuals react to sound input
fft = Array(0)
osc()
.modulate(noise(3),()=>a.fft[0])
.out(o0)
  • p5 → Hydra feed your p5.js canvas into Hydra as a source for further processing

  • strudel → p5 feed your strudel composition to p5.js canvas for further processing

// strudel
$: sound("bd hh*8 bd*4 hh*4")
	.dec(.2).delay(.4)
	// .color("cyan magenta yellow")
	.p5live(() => {
		// console.log(hap)
		// filter for bd and sd events
		if(hap.s == 'bd') {
			bd = 1
		}

		if(hap.s == 'hh') {
			sd = 1
		}
	})

// hush() // silence everything above it
// strudel

// store some global vars
var bd = 0, sd = 0

function setup() {
	createCanvas(windowWidth, windowHeight)
}

function draw() {
	clear()

	strudel.hide(1) // 0 to show
	
	ellipse(width / 2 + 100, height / 2, bd * 200)
	ellipse(width / 2 - 100, height / 2,sd * 200)
	bd = ease(.2, bd, .02)
	sd = ease(0, sd, .05)
}
// sandbox
s0.initP5()
P5.hide()

// src(s0)
// .modulate(noize(3,.2))
// .out(o0)

noize(5,()=>effectH)
.thresh(0.5,.07)
.out(o0)

//()=>effectH

// sandbox



// strudel
$: sound("bd hh*2 bd*4 hh*2")
	.dec(.2).delay(.4)
	// .color("cyan magenta yellow")
	.p5live(() => {
		// console.log(hap)
		// filter for bd and sd events
		if(hap.s == 'bd') {
			bd = 1
		}

		if(hap.s == 'hh') {
			sd = 1
		}
	})

// hush() // silence everything above it
// strudel

// store some global vars
var bd = 0, sd = 0

let effectH

function setup() {
	createCanvas(windowWidth, windowHeight)
}

function draw() {
	clear()

	strudel.hide(1) // 0 to show
	
	ellipse(width / 2 + 100, height / 2, bd * 200)
	ellipse(width / 2 - 100, height / 2,sd * 200)
	bd = ease(.2, bd, .02)
	sd = ease(0, sd, .05)
	
	effectH = map(bd,0.6,1.3,0.01,0.03)
	console.log(effectH)
}

About

Workshop for noise makers

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors