Menu Search
Jump to the content X X

Today, too many websites are still inaccessible. In our new book Inclusive Design Patterns, we explore how to craft flexible front-end design patterns and make future-proof and accessible interfaces without extra effort. Hardcover, 312 pages. Get the book now →

How To Create Web Animations With Paper.js

The Web is just starting to use animation well. For years, animated GIFs and Flash ruled. Text moved and flashed, but it was never seamless. Animations had boxes around them like YouTube videos. HTML5 canvas changes everything about Web animation.

The canvas element makes it possible to integrate drawings and animations with the rest of your page. You can combine them with text and make animations interactive. This drawing mechanism is powerful, but very low-level.

Animations get more power and need less coding when you combine the canvas tag with higher-level libraries such as Paper.js61. This article introduces HTML5 animation2 and walks you through creating an animation of dandelion seeds blowing in the wind.

Neat Is Easy, But Messy Is Hard Link

Computers love clean. They make spreadsheets, do statistics and plot multivariate curves; they always color inside the lines.

In the real world, even simple things are messy. Leaves falling from trees, water splashing — all the little interactions around us feel simple because we’re used to them; but little bursts of wind are actually messy and unpredictable.

For this article, we’ll animate dandelion seeds blowing in the breeze.

Dandelions are tricky because we all know what they look like: we’ve touched them and blown their seeds off. Commonplace objects produce instant recognition and feelings. I don’t have to tell you what dandelions are — you just know. Dandelions are a chaos of seeds piled on top of each other.


(Image: Arnoldius4)

Our dandelion animation will never reproduce the complexity of the real thing, and it will work better if we don’t try: make it too close to real and it will feel funny. Instead, we’ll create a stylized dandelion that makes the right impression without all of the details.


Paper.js Link

Drawing simple shapes with the canvas tag, without any special drawing libraries, is easy. Create your canvas:

<canvas id="canvas" width="300" height="300"></canvas>

Then add a little JavaScript.

// Get our canvas
var canvas = $('#canvas')[0].getContext("2d");

// Draw a circle
canvas.arc(100, 100, 15, 0, Math.PI*2, true);

// Close the path

// Fill it in


Cheat sheets for canvas show you the basics, but when you get into more serious drawing, you’ll want a higher-level library, such as Paper.js61.

Paper.js is a JavaScript library for drawings and animations. It’s based largely on Scriptographer7, a scripting language for Adobe Illustrator8. You can write JavaScript with Paper.js9, but most of the time you’ll be working with a JavaScript variant called PaperScript.

Paper.js calls itself “The Swiss Army Knife of Vector Graphics Scripting10,” and the “vector11” part is important.

There are two basic types of graphics, vectorized12 and rasterized13. Rasterized graphics are like the pictures you take with your camera: big rectangles with maps denoting the color of each pixel. Enlarge them and you’ll get blurry dots.

Vector graphics are like connect-the-dots pictures: they’re sets of lines and shapes that give instructions on how to draw the image at any size. Using vector graphics, you can make an image of the letter Z really big and it will still look sharp. If you turned it into a rasterized graphic by taking a picture of it and then blowing it up, the letter would get all blurry.

Vector graphics libraries are perfect for animation because they make resizing, rotating and moving objects easy. They’re also much faster, because the program has instructions for drawing each object instead of needing to figure it out.

The Paper.js examples page14 shows some of the amazing things you can do with vectorized graphics.

The dandelion is a complete functioning example, and you can see it all running on the example page15. You can also change the code by clicking the “Edit” button, see your changes live, and copy and paste the code to your own website. Over the course of the article, we’ll explain each part of the code in turn, but please note that in order to run the code yourself, you will need to head over to the example page and copy and paste it to your own environment.

Drawing Our Dandelion Link

The first step is to import our JavaScript and PaperScript files.

<script src="paper.js" type="text/javascript" charset="utf-8"></script>
<script type="text/paperscript" canvas="canvas" src="dandelion.pjs" id="script"></script>

The PaperScript code for running the animation is declared as text/paperscript. Now we’re ready to start drawing.

The first part of our dandelion is the stem. The stem is the green arc, with a circle on the top for the bulb. We’ll make both shapes with a path16, a list of shapes, points and lines that the browser is instructed to display.

Paths are the basic building blocks of animation. They render lines, curves and polygons. You can also fill them in to make complex shapes. Our path looks like this:

var path = new Path();
path.strokeColor = '#567e37';
path.strokeWidth = 5;

var firstPoint = new Point(0, 550);

var throughPoint = new Point(75, 400);
var toPoint = new Point(100, 250);
path.arcTo(throughPoint, toPoint);

Our path is an arc, so it needs three points: the start, the end and a midpoint to arc through. Three points are enough to define any arc we need. The arcTo function draws the line between them. The path item also supports styling information, such as stroke color and stroke width; #567e37 and 5 will make our arcing line green and thick. Paper.js supports the same color definitions as CSS.

We can add a few more items to make it all easier to see:

path.fullySelected = true;

var circle = new Path.Circle(throughPoint, 5);
circle.fillColor = '#CC0000';

Fully selecting the path will display some lines to show us the arc; the red circle shows us where the through point is.


The stem ends with a circle to show the bulb of the flower and give us a place to attach all of the seeds. Circles are much easier in Paper.js than in direct canvas.

var bulb = new Path.Circle(toPoint, 10);
bulb.fillColor = '#567e37';

One line of code draws our circle, one more makes it green, and now we’re ready to add our seeds.

Drawing The Seeds Link

Each seed has a bulb, a little stem and a wispy part on top.


(Image: Hmbascom18)

Our seed starts with a small oval for the bulb and an arc for the stem. The oval is a rectangle with rounded corners:

var size = new Size(4, 10);
var rectangle = new Rectangle(p, size);
var bottom = new Path.Oval(rectangle);
bottom.fillColor = '#d0aa7b';

The seed stem is another arc, but this one is much thinner than the flower stem:

var stem = new Path();
stem.strokeColor = '#567e37';
stem.strokeWidth = 1;
stem.add(new Point(p.x + 2, p.y));

var throughPoint = new Point(p.x + 4, p.y - height / 2);
var toPoint = new Point(p.x + 3, p.y - height);
stem.arcTo(throughPoint, toPoint);

The wisps are more arcs with a circle at the end of each line. Each seed has a random number of wisps that start at the top of the stem arc and curve out in different directions. Randomness makes them look a little bit messy and thus more natural. Each seed gets a random number of wisps, between 4 and 10.

for (var i = 0; i < random(4, 10); i++) {
    path = new Path();
    path.strokeColor = '#fff3c9';
    path.strokeWidth = 1;

    var p1 = new Point(p.x, p.y);
    path.add(new Point(p1.x + 2, p1.y + 2));

    // Each flutter extends a random amount up in the air
    var y = random(1, 5);

    // We draw every other stem on the right or the left so they're
    // spaced out in the seed.
    if (i % 2 == 0) {
        throughPoint = new Point(p1.x + random(1, 3), p1.y - y);
        toPoint = new Point(p1.x + random(5, 35), p1.y - 20 - y);
    } else {
        throughPoint = new Point(p1.x - random(1, 3), p1.y - y);
        toPoint = new Point(p1.x - random(5, 35), p1.y - 20 - y);

    path.arcTo(throughPoint, toPoint);

    // Now we put the circle at the tip of the flutter.
    circle = new Path.Circle(toPoint, 2);
    circle.fillColor = '#fff3c9';

Now that we’ve drawn the seed, we need to manage it; later, we’ll want to move and rotate it. The seed is made up of a lot of parts, and we don’t want to have to manage each one separately. Paper.js has a nice group19 object. Groups associate a set of objects together so that we can manipulate them all at once.

var group = new Group();
group.addChild(stem); = group;

The last step is to package our seed into a reusable object called Seed. We add all of the code we’ve been writing to a new function with the name Seed and add a function to create the initial variables. This example calls that function create, but you can name it anything you want.

function Seed() {

    this.create = function (/*Point*/ p, /*boolean*/ shortStem) {

The create function draws the seed at the specified Point20, and the shortStem boolean tells us whether this is a short stem. We’ll look at short-stemmed seeds a little later.

These types of functions don’t work as constructors21 in JavaScript, but are supported in PaperScript.

var seed = new Seed()
seed.create(new Point(100, 100), false);

Our seeds will look like this when we draw them:


The Seed object draws our random dandelion seeds. Now we can add them to our flower.

Adding A Little Chaos Link

The seeds will look better when we space them out around the circle of our dandelion bulb to feel like a halo of seeds. The bulb is a circle, and the circle is a path, so we can get each point on the path.

var bulb = new Path.Circle(toPoint, 10); bulb.fillColor = '#567e37';

var angle = 360 / bulb.length;
var seeds = [];

for (var i = 0; i < bulb.length; i++) {
    var seed = new Seed()

    // Rotate each seed so that it points out from the bulb
    seed.rotate(i * angle);

This will make a circle of seeds around the bulb but leave a space in the middle. We’ll add a few more seeds to fill in the center. We’re giving the center seeds short stems so that they show the white of the wisps more than the beige of the stems.

for (var i = 0; i < 18; i++) {
    var seed = new Seed()
    var point = new Point(toPoint.x + random(-3, 3),
                          toPoint.y + random(-3, 3));
    seed.create(new Point(toPoint), true);
    seed.rotate(random(0, 360));

The seeds in the middle will bunch randomly and make our dandelion look nicely messy. Now we can make them blow off.

Animating The Seeds Link

Wind pushes seeds in complex patterns, and two seeds will never blow off the same way. We want to make them look real, so we’ll need a little more randomness.

Reproducing real wind is much too complicated, so we’ll make the seeds float off in a random-looking pattern. Each seed is assigned a random point on the right side of the screen as a final destination:

this.dest = new  Point(1800, random(-300, 1100));

The rotateMove function pushes each seed toward its destination point and rotates it. We can work with our Seed object as a group to rotate and move it with one function.

this.rotateMove = function(/*int*/ angle) {
    if ( < 850 && < 650) {
        var vector = this.dest -; += vector / 150;

        this.angle += angle;;
    } else {
        this.isOffScreen = true

This function will move the seed until it’s off the screen. Calling rotateMove for each frame of our animation will make the seed float across the screen.

Paper.js gives us an easy way to make animations with the onFrame function; when we implement onFrame, Paper.js will call it for every frame of our animation. With each frame, we iterate over each seed and move it across the screen.

function onFrame(event) {
    for (var i = 0; i < seedCount; i++) {
        if (!seeds[i].isOffscreen()) {
            seeds[i].rotateMove(random(2, 4));

The seeds slide and rotate a little closer to the destination point with each frame of the animation. Starting all of the seeds at the same point and ending them far apart makes them space out nicely as they move.


We don’t want all of the seeds to fall off at once, so we’ll use a timer to make them drift away.

function start() {
    var id = setInterval(function() {
        if (seedCount === seeds.length) {
    }, 1000);

The timer waits for one second before releasing the next seed, giving our dandelion a nice floaty feel.

Some green grass and blue sky as a background image for our canvas puts it all into context. Now we have a dandelion with seeds floating on the breeze.


See the dandelion running here23. You can edit and run the source code as part of the animation or download it from the dandelion GitHub page24.

Paper.js In The Real World Link

Paper.js has some impressive examples and a nice coding model, but you should know a few gotchas before using it on your website.

It Doesn’t Work In Old Browsers Link

All Paper.js drawings use the canvas tag and require HTML5. This means that you need Internet Explorer 9+, Firefox 4+, Safari 5+ or Chrome. If your website must support older browsers, then you won’t be able to use canvas.

There’s no way around this requirement; if you need older browsers, you’re out of luck. As the Paper.js website says, “Let’s go forward!25.”

Performance Can Be Slow Link

Paper.js can make a browser grind to a halt even if the browser supports HTML5. Pixar renders Buzz and Woody on giant server farms — all you get is your user’s cheap MacBook.

Not only are laptops slower than server clusters, but browsers make things worse by rendering the canvas tag with the CPU26 instead of the GPU27. Games like Halo and Rage take advantage of the graphics processor on your video card to render rocket launchers and mutants. The CPU is less efficient with graphics, so the same computer that handles complex video games smoothly can make floating dandelion seeds look slow and jerky.

Make sure to test all of your animations with slower hardware, and watch the CPU usage. Use groups to minimize the calculations, and be very careful about what you do in each invocation of the onFrame function.

Mobile Devices Are Slower Link

Mobile performance is even worse. Most mobile devices support canvas, but they are mostly too slow to render canvas animations well. Even more powerful devices, like the iPad 2, can’t handle the dandelion seeds smoothly.

It Doesn’t Support Object-Level Events Link

Other drawing libraries, such as SVG (see below), support object-level mouse and keyboard events. Those events make it easy to respond when a path or a polygon is clicked, hovered over or touched.

The canvas tag doesn’t support object-level events. Paper.js has some basic functionality for hit testing28, but it’s very low-level. You can listen for mouse29 and keyboard30 events on the whole canvas, but you’ll need to handle mapping those events to individual controls.

What About SVG? Link

The SVG31 (Scalable Vector Graphics) specification was defined over 10 years ago, but came to the forefront with support libraries such as Raphaël.js, which make it easy to generate SVG images with JavaScript. SVG is powerful, works well for smaller images, and is supported all the way back to Internet Explorer 7 with conversion to VML32 (Vector Markup Language). SVG is the best choice if you need to support older browsers.

The real issues with SVG are speed, future support and mobile devices. Every browser maker is actively working on making canvas faster. Safari 5 already offers hardware acceleration with the GPU for canvas, and the rest are working on it. SVG is also unsupported on Android devices.

There’s a growing community around canvas, the new technology that vendors are focusing on. They’re adding new features, fixing bugs and making it better every day.

Other Canvas Drawing Libraries Link

Paper.js isn’t the only option for canvas. Processing.js33, from the creator of jQuery34, ports the Processing35 programming language to JavaScript. It supports animations and has many examples36.

The three.js37 engine supports canvas and the WebGL38 library, and it focuses more on 3-D drawings. Google Dart39 will also support canvas with built-in rendering objects.

Paper.js is a mature library with a very supportive community on the Paper.js Google Group40 and many impressive and well-documented examples. Check out some of the amazing things people are doing with it.

More Paper.js Examples Link

Our dandelion is just the beginning. Below are a few other impressive animations written in Paper.js.

Where’s your Paper.js amazingness?


Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47

↑ Back to top Tweet itShare on Facebook


Zack Grossbart is an engineer, designer, and author. He's a founding member of the Spiffy UI project, the architect of the WordPress Editorial Calendar, and a Consulting Engineer with NetIQ. Zack began loading DOS from a floppy disk when he was five years old. He first worked professionally with computers when he was 15 and started his first software company when he was 16. Zack lives in Cambridge, Massachusetts with his wife and daughter.

  1. 1

    Utterly sweet. Well done.

  2. 2

    It’s look like raphael.js, except that raphael.js works in old browsers

    You can thake a look at the green skillgauge in this page :

  3. 3

    Anthony Alexander

    November 23, 2011 10:12 am

    even more powerful devices like the ipad2.. lol. macfag detected.

    jquery is finished
    canvas is caput
    flash is dead

    i did this stuff years ago, and im still shocke dhow far behind the cutting edge is.

    • 4

      I guess you are talking about Flash. Yes, this kind of animations were possible in Flash quite some time back. However HTML5 has the big advantage of being open source and community driven, which again does have some disadvantages; but in the long run it benefits everyone.

  4. 5

    Just a little update…

    The article mentions that there are no object level events in PaperJS. The Paper team has been working hard to add that feature and it looks like they’ll have it working in the next release. Thanks guys.


  5. 6

    Can you really call any method that involves writing code to draw a circle easy?
    I’m pretty sure I’ve used software that can draw circles with a single click.

    …runs slow on mobile devices and strains the CPU? Will this be banned from IOS?

    Until tools appear that allow artists to visually draw and animate, the canvas tag is almost worthless.

  6. 10

    Before I rant… I appreciate the time you put into this.
    I also enjoy coding to get a task done , so know that you have to , put your mind into things like this.

    But I have to say.

    utter NONSENSE…..Drawing …. via code.
    Basic animations(moving.x moving.y) good.
    Particle systems and visualizing mathematical functions. great.
    A really instant way to create art ? bull
    Ignore all the tools , and previous triumphs. eSpecially pen and paper.

    What next ? Typing via code ? ( but our os tool does that already)

    *The dandelion animation is CRAP … ( it lacks artist interpretation )
    Any animation TOOL can do it much easier ,better ,faster and without the need to code.
    It has it’s own github page .. LMAO. ( that does show how Concept-ey it really is)

    This is the same sorta stupid crap that people used to do with flash preloaders.
    Useless waste of time and annoying .

    The flash container unfortunately , really is years ahead.
    Articles like this prove it.

  7. 12

    “all you get is your user’s cheap MacBook.”

    What does this mean? Is there a specific reason why “MacBook” is mentioned rather than “computer”? Are you saying that paper.js grinds only MacBooks to a halt or is the grinding universal to all computer types?

    • 13

      Zack Grossbart

      November 23, 2011 1:21 pm

      Sorry for the confusion. There’s nothing special about Macs when it comes to PaperJS. I just meant that you need to think about slower computers than yours.

      • 14

        Thanks Zack but I already knew the answer to those three rhetorical questions. I was raising a point on journalistic neutrality. For most folk, “Macbook” != “computer”. In fact, one is a subset of the other. The specification implies a differentiation. I’d have the same grievance had you had used the term “PC” instead of “Macbook”. Thanks for acknowledging my comment but it’s pretty much redundant without amending the article accordingly.

  8. 16

    Looks like crap on my IPad 2.

  9. 17

    Nice work, well done, thank you. But would it be possible to code the animation a bit closer to real life? I think the seeds do not rotate over and over again – may be one rotation after the first blow. As I have observed, they glide through the air like hanging on a parachute…

  10. 18

    Nice . Beautiful .
    just the stuff i was looking for …

  11. 19

    Nice article.Thank you for sharing.

  12. 20

    Its not that paper.js is weak, its that the example is half baked.
    You could program fuzzy logic to have things sway in the wind and look nice and realistic, but this site published the article as is, or had no idea of previous quality animations in flash.

    That said Flash was doing some crazy stuff in the past that paper.js has no chance of catching up to soon. Maybe.

  13. 21

    nice, neat and all – but I, who spent many years with Flash, am frustrated to see how people think they can now do stuff “better” with HTML5.

    This example is like Flash 10 years ago. People want to be “new” and “up to date” and use the latest things but don’t relaize how they step back in computer-history – thanks to apple btw.

    Yes hate me

    • 22

      agreed..protesting flash in all aspects of content creation is a blind thing. this article looks like catching the nose through back of the head.

  14. 23

    I have to agree, this is pretty useless…

    I thought people hated flash because of stuff like this… Overanimated websites that compromise user experience for the sake of doing something fancy. Turns out now, people start doing the exact same stuff with html5 with even more effort…. Great!

    Also, try Swiffy for Flash… pretty sure you could do this in there in about 15 minutes (with all the convenience of the Flash authoring environment) and then export it to html….

  15. 24

    I agree with the above posts. If this is what we’re left with, then we should be on our knees begging Adobe for forgiveness.

    Flash should have been worked into mobile devices by hook or by crook.

    This is like the stone age of web animation. I’ve never seen a regression of such magnitude in technology.

    So it goes…


  16. 25

    SVG is far more accessible than Canvas! (which isn’t at all)

  17. 26

    Sorry but this is a pile of doo doo.

    You might praise at the fact you are competent at making things move around just by using code, but you are completely forgetting about the visual impact and smoothness of movement.

    High-end flash developers have always done it right.

    You might be a flash hater, but just compare what 2advanced have done compared the crap displayed above. In terms of visual animation, mobile should either have flash, or have something totally different than the web. That thing in this article just makes flash look like a rockstar.

  18. 28

    I love how every new html5 demo gets applause by the masses, but in 2003 this was even possible without code, and smoother. The name was ‘flash’ or something like that, can’t remember.

  19. 29


    November 24, 2011 2:13 pm

    You are wrong about SVG support on Android. Android 4 do.

  20. 30

    This is unbelievable. The most interesting part is able to draw animations using the codes. Html 5 is supporting many potential things. Thanks for sharing.


↑ Back to top