All posts

From canvas to code: my site’s animation, stroke by stroke

How I painted a sunset in JavaScript, then took it apart into pixels, characters and code. The technical choices behind racinepilote.com’s first animation.

  1. Canvas
  2. Scan
  3. Signs
  4. Code

Right above, there’s a painting. A sunset over a lake, with hills and three birds. It paints itself, then gets scanned, turns into characters and ends up as source code. The code runs and gives the painting back. It was this site’s home page at launch. The current home page takes the idea further: the whole page is a canvas that gets digitized as you scroll.

I wanted an image that says who I am without me having to write it. I spent years in the visual arts before I opened my first code editor. The animation tells that trip in twenty seconds.

A brush is a handful of lines

There’s no image file in the animation. Everything is drawn while you watch, with the browser’s Canvas API.

A brush stroke starts as a few control points. I join them with a Catmull-Rom curve, then resample it every 3.5 pixels. Each stroke gets between 3 and 26 bristles. Each bristle is a line offset from the centre, with its own tint and opacity.

The detail that changes everything: every bristle runs out of paint at a different spot. One stops at 70% of the stroke, another goes all the way. That’s the dry-brush look you see on a real canvas. Without it, the result looks like vector art.

The canvas itself is noise. A beige base, thousands of tiny colour shifts and a few horizontal and vertical fibres. Enough for the eye to believe it.

Painting in the right order

A painter doesn’t do the sky after the hills. So I kept the studio order: the sky from top to bottom, a cross pass to break the bands, the sun in a spiral, the far hills then the near ones, the lake, the reflections. The birds and the signature come last.

The hills are painted in wide horizontal strokes, clipped by the shape of the ridge. Then a thinner stroke goes over the ridge to break the line that’s too clean. That’s exactly what I’d do with a real brush.

Scanning is averaging

When the painting is done, a scan line comes down. Behind it, the canvas becomes an 80 by 50 grid. Each cell takes the average colour of the pixels it covers. I get that average by shrinking the image in two steps and letting the browser do the math.

Then each cell becomes a character. The brighter the cell, the denser the character: a dot for the dark sky, an @ for the heart of the sun. It’s the old ASCII art trick, with colour on top.

The characters know where to go

The switch to code is my favourite part. The painting.js file that appears at the end holds almost 500 visible characters. The grid has 4,000. I match each character of the code to a grid cell in reading order, so the top of the painting becomes the top of the file.

Each character follows a Bézier curve to its spot, changes shape halfway and takes on its syntax colour. Cells with nowhere to go fade out and drop a little. The code colours come from the painting: the orange of the keywords is the sun.

Fast, even with a painting that paints itself

An animation like this can wreck a site’s speed. It only starts once the page has loaded and the browser has idle time. It stops as soon as it leaves the screen or the tab is hidden. The linen texture is computed at half resolution, then scaled up. And if your system asks for reduced motion, you see the final image right away and you choose when to play it.

The site is built with Astro, compiled to static pages and served by Cloudflare. It’s the same approach I use at Radiko for small businesses.

What it says about me

I’m an artist who learned to code, and the two never really split. When I build a site for a business, I still think in composition, light and contrast. The difference is that my brush compiles.

If you want that kind of attention on your business website, head to Radiko (the site is in French). And if you’re curious how I went from the studio to the editor, my journey is here.