Natural Systems in a Web Browser

A few nights ago, I plugged in a brand new projector into my laptop. After playing a simulation against a wall for a few minutes, I adjusted the unit and inadvertently cast the projected image on the floor. Out of nowhere my cat ran in and began to pounce on the dancing sprites as they swept across the carpet. She was fully convinced our bedroom had been invaded by colorful, bouncing insects and was doing her best to catch one.

I’ve spent the better part of a decade trying to code natural looking movement in a web browser. What I was witnessing felt like a huge victory. My feline QA team was hard at work batting down digital fireflies while I thought about the threshold of belief. What were the compelling qualities of the system I created that convinced her these targets were real enough to attack?

I’m not the first person to consider how we perceive our natural world and how we distinguish imitators. In ‘Vehicles: Experiments in Synthetic Psychology,’ Italian neuroscientist Valentino Braitenberg examines the fine line between accepting a natural versus designed system. It turns out, humans are pretty easy. It doesn’t take much for us to recognize natural movement. We’re fine tuned to a combination of special qualities. Add a few simple rules together and we’re more than ready to suspend our disbelief.

I define a natural system as a sum of forces acting on autonomous agents. The system contains a collection of independent objects that follow rules designed simulate the natural world. The rules are the key. How do we build and execute instructions in a web browser with enough realism that it throws a house cat into a spasm?

Why web browsers make this difficult

Before we start, it’s worth understanding why browsers make this a difficult task. Moving forward, we’re going to lean heavily on JavaScript and DOM manipulation. JavaScript and the DOM are built on an event model. Users do things. Browsers respond. We want the reverse. Right out of the gate we’ll animate objects at a lifelike 60 frames per second with no end in sight.

Browsers also juggle multiple tasks with competing priority. As much as we’d like it, they do not allocate all of their resources to rendering graphics. There’s a network to manage. It is a web browser after all. While we’ll attempt to focus the browser’s attention on drawing our system, we’ll never divert it from other system-level distractions.

Luckily, browsers have made a few advancements to overcome these hurdles. As we construct our framework, we’ll make use of the requestAnimationFrame API to optimize our frame rate. We’ll take advantage of hardware acceleration for an added boost. We’ll use vector math and model our system after a sum of forces. Finally, we’ll incorporate physical input via accelerometers for added realism.

The Big Picture

Our framework’s architecture will take a cue from procedural drawing programs like Processing. When we draw procedurally, we repeat two steps in a loop. First, we run a step function that calculates changes in our objects’ properties. Second, we translate those changes into style properties and render a new frame. If we manage to do it fast enough, we create a beautiful natural looking simulation.

At a high level, we’ll separate the system into three main components, System, World and Item. We’ll also build out some utilities and a Vector class to make our life easier. Ready to get started?

Our Project

To begin, we need to organize our project as a simple web page. Create a folder called SimpleSim with an index.html file. Also create a blank file called main.css and a blank file called simplesim.js. After this first step, we’ll do almost all our work in the simplesim.js file.

We will also make use of Modernizr to detect if our browser supports css transforms. More on that later. For now, download the latest Modernizr and place it in your project folder. To save on file size, if you’d like to create a custom build of Modernizr, select ‘2D Transforms’ and ‘3D Transforms’ as configuration options.