Week 10: Media, Drawing & Animation

To Do This Week

Explore the front-end modules this week and next. By the end of Week 11 you will have tried five techniques you can combine in your two Front-End Module Projects.

Keep a running list of combination ideas as you go.


Front-End Module Projects (10% + 10%)

Complete two independent projects after exploring the course’s front-end modules. Each project must combine at least two of the following:

The projects should demonstrate creative intent rather than merely showing that a feature works. These are small ways to play with techniques that can lead toward your final project.

Minimum Requirements for Each Project

Using AI

You may use AI to research and test out your ideas. What I will be covering in class is just a basic understanding of the different techniques. You will have to do some research and experimentation on your own. Once you are reading to build your projects, use the JS Mentor Metapromptto build logic steps and write the script with JS syntax. Document what AI contributed and how you evaluated, changed, and extended the generated material. Include chat URLs in your script comments.


Monday: Audio/Video, SVG & Canvas Drawing

Audio and video: you control

The <audio> and <video> hold media, like a recorded sound, a song, or a film clip. JavaScript drives playback: play(), pause(), currentTime, volume, loop. It also listens for events like ended, timeupdate, or canplay.

Use it when the content is recorded media and the interaction is about when and how it plays. Examples: a custom video player, a sound that triggers on click, a story that moves to the next clip when one ends, ambient audio that fades as the user scrolls.

SVG: interactive vector graphics

SVG (Scalable Vector Graphics) describes shapes in markup, such as <circle>, <rect>, and <path>. Each shape is a real element in the DOM, just like a <div>. You can select it, give it a class, style it with CSS, and attach event listeners to it. To change it, you change an attribute (setAttribute('r', 40)) and the browser redraws it for you. Because it's vector, it stays sharp at any size.

SVG projects often start in Illustrator. Put each part you want to make interactive on its own layer, and give it a simple name like door or left-eye. When you export with File > Export > Export As > SVG and set Object IDs to Layer Names, each layer becomes a <g id="..."> group in the code. Paste that SVG code directly into your HTML instead of linking it with <img>. Then JavaScript can select each layer by its id, like document.querySelector('#door'), and make it respond to clicks, hovers, or animation.

Canvas: drawing & painting

A <canvas> is a blank grid of pixels. You draw on it with JavaScript commands like fillRect(), arc(), and drawImage(). Once something is drawn, the canvas forgets it was a "shape." There is only paint. There are no elements to select or move, so to animate you clear the canvas and redraw everything, usually many times per second with requestAnimationFrame().

Use it when you have lots of things moving at once, or you want to work at the pixel level. Examples: particle systems, generative art, games, drawing and painting tools, visual effects and filters on images or video frames, simulations with hundreds or thousands of objects.


HTML5 Audio & Video

Sound and moving image are often the fastest way to give a project mood. They also combine easily with everything else this week: a click on an SVG shape plays a sound, a video drives a canvas, a game event triggers a sound effect.

There are two ways to get audio or video into your page. You can write the element in your HTML and grab it with JavaScript, or you can create it entirely in JavaScript. Once you have it, the controls are the same either way.

Audio with JavaScript

<!-- Option 1: element in the HTML -->
<audio id="chime" src="chime.mp3"></audio>

const chime = document.getElementById('chime');
// Option 2: create it in JavaScript (nothing needed in the HTML)
const chime = new Audio('chime.mp3');
// Either way, control it the same:
chime.play();           // play it
chime.pause();          // pause it
chime.currentTime = 0;  // rewind to the start (so it can retrigger)
chime.volume = 0.5;     // 0 to 1
chime.loop = true;      // repeat

Audio made with new Audio() never appears on the page. That's fine for sound effects and background audio you trigger with code. If you want visible play/pause controls, put an <audio controls> element in the HTML instead.

Video with JavaScript

<!-- Option 1: element in the HTML -->
<video id="clip" src="clip.mp4" muted playsinline></video>

const clip = document.getElementById('clip');
// Option 2: create it in JavaScript
const clip = document.createElement('video');
clip.src = 'clip.mp4';
clip.muted = true;
clip.playsInline = true;
document.body.appendChild(clip);  // add it to the page so it can be seen
// Either way, control it the same:
clip.play();
clip.pause();
clip.playbackRate = 0.5;   // slow motion (2 = double speed)
clip.currentTime = 10;     // jump to 10 seconds

// Run code as the video plays
clip.addEventListener('timeupdate', () => {
  console.log(clip.currentTime + ' / ' + clip.duration);
});

// Run code when it finishes
clip.addEventListener('ended', () => {
  console.log('done');
});

Unlike audio, a video has to be added to the page with appendChild() to be seen. Creating it in JavaScript is useful when the video depends on what the user does, like loading a different clip based on a choice.

Demos:

Tips and Resources:


Canvas: JS Drawing

Setting Up

<canvas id="myCanvas" width="600" height="600"></canvas>

const c = document.getElementById('myCanvas');
const ctx = c.getContext('2d');   // the drawing toolkit

Important: CSS width and height only change the display size. The drawing size comes from the width and height attributes on the <canvas> tag. If CSS stretches a 600 × 600 canvas to 800px, your drawing commands still use 600 × 600 coordinates.

Basic Drawing Methods

Drawing Circles and Arcs

Mouse Position on the Canvas

c.addEventListener('mousemove', (e) => {
  const rect = c.getBoundingClientRect(); // canvas position on the page
  const mx = e.clientX - rect.left;       // mouse x inside the canvas
  const my = e.clientY - rect.top;        // mouse y inside the canvas
  drawFace(mx, my);                       // redraw with new values
});

Demos


SVG (Scalable Vector Graphics) and JS

From Illustrator to JavaScript

  1. Name your layers clearly in Illustrator before exporting. Layer names become ids.
  2. Export as SVG and open the SVG code.
  3. Paste the <svg> block into your HTML.
  4. Check that the ids match what you expect, then select them with getElementById().

Mouse Position on the Canvas

c.addEventListener('mousemove', function (e) {
  const mx = e.offsetX;  // mouse x inside the canvas
  const my = e.offsetY;  // mouse y inside the canvas
  drawFace(mx, my);      // redraw with new values
});

Demos

SVG + JavaScript Resources

Compare: open the SVG Smiley and the Canvas Smiley side by side. Both make the pupils follow the mouse with the same constrainPupil() math. SVG moves two circles with setAttribute(). Canvas clears and repaints the whole face on every mouse move.


Wednesday: Canvas Animation & p5.js

Canvas Animation

Canvas animation is drawing frame by frame. Each frame you clear the canvas, update values (position, size, color), and redraw. Repeat that many times per second and you get motion.

The Animation Loop

let x = 0;        // position
let speed = 2;    // velocity: how far it moves each frame

function animate() {
  ctx.clearRect(0, 0, c.width, c.height);  // 1. clear

  x += speed;                               // 2. update
  if (x > c.width || x < 0) speed *= -1;   //    bounce at the edges

  ctx.beginPath();                          // 3. draw
  ctx.arc(x, 300, 20, 0, 2 * Math.PI);
  ctx.fill();

  requestAnimationFrame(animate);           // 4. repeat
}

animate();

Demos


Generative Art

Generative visual art is digital art made with algorithms. The artist sets the rules and the starting point; the computer follows those rules and produces the final piece, often a little different every time it runs.

GENERATIVE ART: Art created using autonomous processes

AUTONOMOUS PROCESS: A process not under direct human control

Vera Molnár

Vera Molnár (1924–2023) was a Hungarian-French artist and one of the earliest pioneers of computer-based art. In the late 1960s she began using computers to explore geometric forms through small, methodical variations. Her series show how a simple rule plus a little randomness can produce real aesthetic complexity.

Vera Molnar example


p5.js

p5.js is the JavaScript version of Processing, a programming language created in 2001 by Casey Reas and Ben Fry at the MIT Media Lab. They designed Processing to teach coding to artists and designers, with a focus on visual results rather than software engineering. In 2013, artist Lauren Lee McCarthy started p5.js to bring that approach to the web. The names in p5.js, like setup(), draw(), and background(), come straight from Processing, so Processing tutorials and books mostly carry over.

p5.js is a JavaScript library that makes Canvas drawing and animation simpler. It runs the animation loop for you and adds tools for randomness and noise. Paste each example into the p5.js editor, press play, then change the numbers.

Using p5.js on Your Own Page

The p5.js editor loads the library for you. On your own webpage, you have to load it yourself. Add a link to the p5.js library at the bottom of your page, just before your own script, whether that's a <script> block or a link to your sketch file. The library has to come first, because your sketch uses functions like setup(), draw(), and circle() that p5.js provides. You don't need to create a <canvas> element; createCanvas() makes one for you.

  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
  <script src="sketch.js"></script>
</body>

1. setup() and draw()

function setup() {          // runs once at the start
  createCanvas(600, 400);   // make a canvas 600 wide, 400 tall
}

function draw() {           // runs over and over, about 60 times per second
  background(20);           // fill the canvas with a dark gray
  fill(255, 120, 80);       // set the color for the next shapes (orange)
  circle(300, 200, 100);    // draw a circle
  rect(50, 50, 80, 80);     // draw a rectangle
}

setup() runs once. draw() repeats every frame. It replaces the requestAnimationFrame() loop you wrote yourself in plain Canvas.

Explore in the editor: change values and see results.


2. Animating with frameCount

function setup() {
  createCanvas(600, 400);
}

function draw() {
  background(20);
  circle(frameCount, 200, 40);   // x position = the frame number
}

frameCount is a built-in variable that counts how many times draw() has run: 1, 2, 3, 4… It works as a clock. Here it becomes the circle's x position, so the circle moves one pixel to the right every frame. Once it passes the edge of the canvas, it keeps going and disappears.

Why redraw background() every frame? It wipes the previous frame. Comment it out and see what happens.

Explore in the editor: change values and see results.


3. Responding to the mouse with map()

function setup() {
  createCanvas(600, 400);
}

function draw() {
  let shade = map(mouseX, 0, width, 0, 255);
  background(shade);
  fill(255 - shade);          // the opposite shade, so the circle stays visible
  circle(mouseX, mouseY, 50);
}

mouseX and mouseY are built-in variables that hold the mouse position on the canvas.

This map() is not the array .map() you already know. It is a p5.js math function with the same name. It converts a number from one range to another:

map(value, fromLow, fromHigh, toLow, toHigh)

The mouse can be anywhere from 0 to 600 (width), but a color only goes from 0 to 255. map() translates between the two scales:

Explore in the editor: change values and see results.


4. random(): scatter

function setup() {
  createCanvas(600, 400);
  background(20);             // background only once, so circles pile up
}

function draw() {
  noStroke();                 // no outline on shapes
  fill(255, 80);              // white, mostly transparent
  let x = random(width);      // any number from 0 to 600
  let y = random(height);     // any number from 0 to 400
  let size = random(5, 40);   // any number from 5 to 40
  circle(x, y, size);
}

Every frame gets brand-new values that have nothing to do with the last ones. The circles jump all over.

Explore in the editor: change values and see results.


5. noise(): drift

function setup() {
  createCanvas(600, 400);
  background(20);
}

function draw() {
  let t = frameCount * 0.01;          // a slowly increasing "time" value
  noStroke();
  fill(255, 80);
  let x = noise(t) * width;           // noise gives 0–1, times 600 = 0–600
  let y = noise(t + 100) * height;    // a different spot in the noise, so y doesn't match x
  let size = noise(t + 200) * 40;     // 0–40
  circle(x, y, size);
}

noise(t) always returns a number between 0 and 1. Unlike random(), the same t always gives the same answer, and nearby t values give nearby answers. If t moves forward in small steps, the output changes smoothly. Multiplying by width stretches the 0–1 result across the canvas.

Examples 4 and 5 draw the same thing. The only difference is random() vs. noise(). Run them side by side. What mood does each one have?

Note: p5.js arc(x, y, w, h, start, stop) uses width and height; Canvas arc(x, y, radius, start, end) uses a radius.

Explore in the editor: change values and see results.


Two Kinds of Chance: random() vs. noise()

random() gives a new, unrelated value each time. Things jump, flicker, and scatter.

Example of random() output

noise() (Perlin noise) gives values that change gradually. Things drift, flow, and breathe, like clouds, water, or terrain.

Example of noise() output

Images from Amy Goodchild’s What is Generative Art. Try it yourself: random() vs noise().


Terms to Play with in AI

Ask AI for a p5.js sketch using one or two of these terms. Then change the rules and values yourself. A simple pattern: “Write a p5.js sketch that uses [term] and noise() to create [mood].”


Going Deeper

My Sketches and Demos

Learning and Inspiration