Welcome to the blog.

Creating a Canvas Swarm with JavaScript

Swarms are so hot right now. At least, we think so. Just a few months ago, we launched a site with this particle effect, and wanted to share how we went about creating it.

For this project, we needed to visually represent thousands of individual voices uniting as one. So we came up with the idea of using a mass of speech bubbles in animated chaos, finding order by cycling through a set of user-defined iconography. Rather taking a thousand words to explain, how about I just show you?


Our swarm is based on transparent PNGs, chosen so we’d only have to check the alpha channel to get the data for generating our particles. Using JavaScript, we load the image onto a temporary canvas, grab every opaque pixel location with getImageData(), and produce a map of individual swarm particles in the shape of the image.

This gives us plenty of particle locations — too many, in fact, to create a suitable swarm. So we incorporate Shape’s spread property that downscales the map by a spread factor to reduce the number of particles, then re-enlarges it again to yield a sparser collection of particles in the coordinate space of the original shape’s size.

Swarm Particle Diagram

Here’s how to initialise a swarm shape from an image:

shapes = new ShapesCollection();

shapes.add('circle', new Shape({
	src : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAY...',
	width: 500,
	height: 500,
	offset : {
		x : 650,
		y : 550
	spread : 20

This example uses a data URI, but in the live version we set up the CMS so they could upload the images themselves. As long as they used transparent PNGs, our solution would keep on trucking, and the new swarm shapes would automatically appear on their site.

Animation is handled with a Renderer object that manages the run-loop encompassing the four main phases of operation:

  • Clearing the canvas
  • Updating particle (speech bubble) positions
  • Drawing onto the canvas
  • Setting up for the next iteration of the run-loop

Each particle calculates its own position at any time based on whether any active tweens exist in its queue. Tweens are an encapsulation of from-and-to locations, a duration, and an easing function to handle the transition.

var tween = new Tween({
	to : new Point(to_x, to_y),
	easing : 'easeOutQuad',
	duration : 1000,
	repeat : false

 * 	piece is an instance of BubblePiece with a built-in orbiting jitter function 

//Optionally replace all previous tweens by clearing beforehand

Alongside motion tweening, we include a custom Jitter function to calculate the position of particles at any point in time. This gets particles to loiter around once it reaches the target location, adding life and suspense to the animation. By slightly varying the jitter speed of each particle, we achieved a semi-random motion effect that more closely emulates a real life swarm.

Putting all of this together gets us to the final masterpiece.

Hope you enjoyed this demo. We’re happy with how our animation turned out, and the client loved it. If you want to play with the code yourself, feel free to check it out it on github.


Like this post? Keep up with us on Twitter and Instagram.


person hit in the face by a flying newspaper (aka. the popups experience)

Are popups still a good idea?

7 November 2016 Author: Sandy Lim

Go on. Ask any internet user how they feel about popups. You may learn some new swear words. And yet, when the business case for UX is stronger than ever, many brands still default to popups...

Read Article
Dear Developer

Dear Developer. Love, Designer.

20 August 2015 Author: Kylie Timpani

Last month, a tweet by Yesenia Perez-Cruz, Senior Designer at Vox Media, caught my eye. Her tweet asked what seemed like a simple question:   I see an abundance of articles about how designers can make developers lives...

Read Article
Jumping into the vortex

Investing in design

29 February 2016 Author: Jay Hollywood

The value of design in today’s world is unprecedented. It impacts everything around us, from business to culture and how we interact with each other. Good design can deliver better experiences, make our lives easier and...

Read Article