HTML5 Canvas Art

This is a little bit of a follow-along HTML5 procedural canvas pixel art tutorial. It makes for wild websites with instant load times using math instead of massive libraries like threejs.

Canvas Intro

Procedural art is art that has been created with a system instead of by hand. No not like AI! The system is the art itself, in this case derived from math functions.

You can find examples on the gallery page of my website, but first we need to get a canvas set up and display math functions on it. To start off, I'm going to establish some functions; toPixel(x), getPoint(x), and animate().

Added:



// Edit these values!
const pixel = 
const height = 
const period = 
const canvas = document.querySelector("canvas")
const context = canvas.getContext('2d')

function toPixel(x) {
    return pixel * Math.round(x / pixel)
}

function toPoint(x) {
    const value = Math.sin(x / period) * height
    return value + height
}

function animate() {
    const width = canvas.width
    for (let x = 0; x < width; x++) {
        context.fillRect(toPixel(x), toPixel(toPoint(x)), pixel, pixel)
    }

    requestAnimationFrame(animate)
}

animate()
            


Animation

Cool! But how do we make it oscillate? We can simply add a counter to the animation loop. With this new dynamic counter, add it to both shift and act as a coefficient to our sine function.

Added:



// Edit these values!
const pixel = 
const height = 
const period = 
const canvas = document.querySelector("canvas")
const context = canvas.getContext('2d')

const speed = 
let counter = 0

function toPixel(x) {
    return pixel * Math.round(x / pixel)
}

function toPoint(x) {
    const value = Math.sin((x * frequency) / period) * height * Math.sin(counter / (8 * pixel))
    return value + height
}

function animate() {
    counter += speed

    const width = canvas.width
    for (let x = 0; x < width; x++) {
        context.fillRect(toPixel(x), toPixel(toPoint(x + counter)), pixel, pixel)
    }

    requestAnimationFrame(animate)
}

animate()
            


More Sine

Now we have a good looking animation, as a little bonus we can add some fancy stuff. Frequency behaves strangely when working with pixels, you may have noticed at period = +- 1 our wave goes wild, but what about when -1 < period < 1?

Added:



// Edit these values!
const pixel = 
const height = 
const period = 
const canvas = document.querySelector("canvas")
const context = canvas.getContext('2d')

const speed = 
let counter = 0

const frequency = 

function toPixel(x) {
    return pixel * Math.round(x / pixel)
}

function toPoint(x) {
    const value = Math.sin((x * frequency) / period) * height * Math.sin(counter / (8 * pixel))
    return value + height
}

function animate() {
    counter += speed

    const width = canvas.width
    for (let x = 0; x < width; x++) {
        context.fillRect(toPixel(x), toPixel(toPoint(x + counter)), pixel, pixel)
    }

    requestAnimationFrame(animate)
}

animate()
            


Donezo

Thats about it for this tutorial on canvas art. You can make anything I made in the gallery using this and a little self discovery (hint: interpolate the cursor position with canvas edges to get cool stretches), but I will a make some more advanced tutorial for how to get the cool cursor effects and stuff later.