I came across an article comparing three JS libraries for drawing in WEB
Paper.js ,
Processing.js and
Raphael.js . I think it will be interesting not only to me.
Before you start drawing anything in the browser, ask yourself about the following three things:

- Do you need support for older browsers?
If the answer is yes , then the only choice is Raphaƫl. It supports browsers up to IE 7 and Firefox 3. Raphaƫl even has limited support for IE 6, despite the fact that some of the base technologies for the library cannot be implemented in this browser.
- Do you need support for Android?
Android does not support SVG, so you have to use Paper.js or Processing.js. There are rumors that Android 4 will support SVG, but most modern Android devices will no longer support it.
- Is your drawing interactive?
Raphaƫl and Paper.js focus on interacting with the elements drawn by clicking on the mouse, dragging and tapping. Processing.js does not support any object level events, therefore it is quite difficult to handle the user's movements in it. Processing.js can draw cool animations on your homepage, and Raphaƫl and Paper.js are more suitable for interactive applications.
Paper.js, Processing.js and Raphaƫl are currently leading libraries for drawing on the Web. There are also a couple of newbies, whose popularity is growing, and of course you can always use Flash, but this trio works well with HTML5 and has the widest support among browser manufacturers.
Choosing the most appropriate framework can determine the success of your project. This article will describe the advantages and disadvantages of each library and provide enough information to make the right choice.
')
All the code in this article is Open Source and is available on a
demo page created specifically to support this article.
General characteristics
| Paper.js | Processing.js | Raphaƫl |
---|
Technology | Tag canvas | Tag canvas | Svg |
Tongue | PaperScript | Processing script | Javascript |
Browsers with | IE 9 | IE 9 | IE 7 |
Mobile browsers | Yes | Yes | IOS only |
Model | Vector and raster | Raster | Stock vector |
Kernel file size | 56 KB | 64 KB | 20 KB |
All use only JavaScript, but each of the frameworks implement their own approach. Raphaƫl is written directly in JavaScript, but Paper.js uses PaperScript, and Processing.js uses its own language. All of them are supported in Firefox, Chrome and Safari, the only problem with Internet Explorer is Paper.js and Processing.js using the canvas tag and therefore require a minimum of IE 9.
PaperScript is an extension of the JavaScript language that allows you to write code that does not pollute the global namespace. This reduces the likelihood of conflicts in JavaScript. PaperScript also directly supports mathematical primitives, such as
Point and
Size : You can add two points together, as if they are simple numbers.
Processing.js is based on a framework called
Processing , which uses a Java Virtual Machine to run. You define int and float instead of var, and you can also use Java-style inheritance. Despite the fact that the script is more like Java in Processing.js, it is still JavaScript and does not require more Java-specific things.
Using any of the three libraries won't be a problem if you are familiar with JavaScript.
Let's start
To start importing each library. In each case, this process is somewhat different.
We connect Paper.js
Paper.js defines the type of script as text / paperscript and the ID of the target canvas element on which we will draw.
<head> <script src="paper.js" type="text/javascript" charset="utf-8"></script> <script type="text/paperscript" canvas="paperCircle" src="paper_circle.pjs" id="script"></script> </head> <body> <canvas id="paperCircle" class="canvas" width="200" height="200" style="background-color: white;"></canvas> </body>
We connect Processing.js
Processing.js uses the data-processing-sources attribute of the canvas tag for initialization. The author used the .java extension for the script with the Processing file so that his code editor correctly displays the syntax highlighting. Other authors may use the .pde or .pjs extensions. As you prefer.
<head> <script src="processing.js" type="text/javascript" charset="utf-8"></script> </head> <body> <canvas width="200" height="200" class="canvas" data-processing-sources="processing_circle.java"></canvas> </body>
Connecting Raphaƫl
Raphaƫl connects like any other javascript file. It works well with
jQuery's ready function and with all other JS frameworks.
<head> <script src="raphael-min.js" type="text/javascript" charset="utf-8"></script> <script src="raphael_circle.js" type="text/javascript" charset="utf-8"></script> </head>
Now we are ready to drawObject Oriented Drawing
Both Paper.js and Raphaƫl use an object-oriented approach to the drawing process: You draw a circle and get a Circle object. Processing.js just draws a circle and returns nothing. The following code illustrates how this happens. Let's start with a 100 by 100 circle in the center of the screen.

Paper.js:
var circle = new Path.Circle(new Point(100, 100), 10); circle.fillColor = '#ee2a33';
Raphaƫl:
var paper = Raphael('raphaelCircle', 200, 200); var c = paper.ellipse(100, 100, 10, 10); c.attr({'fill': '#00aeef', 'stroke': '#00aeef'});
Processing.js:
void setup() { size(200, 200); } void draw() { background(#ffffff); translate(100, 100); fill(#52b755); noStroke(); ellipse(0, 0, 20, 20); }
Each piece of code draws the same circle. The difference is what you can do with it later.
Paper.js creates a circle as a
path object. We can save it and change it later. In Paper.js, circle.fillColor = 'red'; draws a circle in red, and circle.scale (2) makes it twice as large.
Raphaƫl, like Paper.js, implements an object-oriented model. In Raphaƫl, we can change the color of our circle using circle.attr ('fill', 'red'); and resize it by writing circle.scale (2, 2) ;. The main idea is that the circle is an object to the properties of which we can access later.
Processing.js does not use objects; The
ellipse () function does not return a value. As soon as we draw a circle using Processing.js, it becomes part of the image being created, as in ordinary ink drawing on paper; This is not a separate object, which can be changed properties. To change the color, we need to draw the same circle, but a different color over the first one.
When we call the
fill () function, the color changes for all primitives displayed below. After calling the
translate () and
fill () functions, all the shapes will be painted green.
Since functions change everything at once, we can easily get completely unexpected effects. You call a harmless function and suddenly everything turns green! Processing.js provides the
pushMatrix () and
popMatrix () functions to isolate the changes, but you still need to remember to call them.
The lack of objects in Processing.js means that complex images are processed much faster. Paper.js and Raphaƫl store links to all the drawn objects, which increases the amount of memory consumed and slows down the application noticeably in complex graphics. Processing.js does not contain references to created objects, as a result, each part of the figure takes up very little memory. The object approach is justified if you want to access the object later, otherwise it is a waste of resources. Paper.js makes it possible to avoid unnecessary memory consumption where it is not needed; for this,
Symbol is used to rasterize the object, but of course you need to plan everything in advance so that the application runs fast enough.
Different approaches define the whole style of working with libraries. Of course, this also affects how you work with animation.Make them move
The rotation of the circles is not too spectacular, so let the square rotate around the circle.

Animation in Processing.js
Processing.js supports animation using the
setup () and
draw () functions, like this:
float angle = 0.0; void setup() { size(200, 200); frameRate(30); } void draw() { background(#ffffff); translate(100, 100); fill(#52b755); noStroke(); ellipse(0, 0, 20, 20); rotate(angle); angle += 0.1; noFill(); stroke(#52b755); strokeWeight(2); rect(-40, -40, 80, 80); }
The setup function is called when the application starts. We say Processing.js with a frequency of 30 frames per second, as a result, our draw () function will be called 30 times per second. This number may seem high, but itās normal if we want a smooth animation.
The draw () function first fills the entire canvas with one color; it will paint over all that remains of the previous frame. This is the main feature of Processing.js: we do not manipulate objects, so we have to clear everything that remains from the previous frame.
Next, we move the focus to the point 100,100. This positions the drawing 100 pixels to the left and 100 pixels from the top of the canvas for all drawing operations, until we change the coordinates. Next, we change the previous value of the angle of inclination. This value increases with each frame causing the square to rotate. And the last step is to display the square using the
fill and
rect functions.
Usually the rotate () function of Processing.js operates with
radians instead of
degrees . Therefore, each time we increase the angle by 0.2, rather than a larger value, for example 3. This is one of many cases in software drawing when we need trigonometry.
Paper.js Animation
In Paper.js, simple animation is easier to implement than in Processing.js, using the constant rectangle object:
var r; function init() { var c = new Path.Circle(new Point(100, 100), 10); c.fillColor = '#ee2a33'; var point = new Point(60, 60); var size = new Size(80, 80); var rectangle = new Rectangle(point, size); r = new Path.Rectangle(rectangle); r.strokeColor = '#ee2a33'; r.strokeWidth = 2; } function onFrame(event) { r.rotate(3); } init();
We use the state of our square as an object, and Paper.js controls drawing on the screen. With each frame we rotate it little by little. Paper.js manages all the transformations, so we donāt have to redraw everything manually at the beginning of each frame or monitor the current value of the rotation angle or worry about not hitting other objects.
Raphaƫl Animation
The animation on Raphaƫl is written in standard JavaScript, i.e. Raphaƫl does not define any special functions for personnel management. Instead, we use the normal setInterval () function.
var paper = Raphael('raphaelAnimation', 200, 200); var c = paper.ellipse(100, 100, 10, 10); c.attr({ 'fill': '#00aeef', 'stroke': '#00aeef' }); var r = paper.rect(60, 60, 80, 80); r.attr({ 'stroke-width': 2, 'stroke': '#00aeef' }); setInterval(function() { r.rotate(6); }, 33);
Raphaƫl is similar to Paper.js in its object-oriented approach. We have a square, and we call its
rotate () method. So we can rotate the square using just a few lines of code.
Interaction
Raphaƫl reveals its advantages when it comes to adding interactivity to a drawing. It provides an event model similar to the usual for JavaScript, allowing you to easily detect mouse clicks, the start of dragging or touching the user. Let's add a square response to a mouse click.

Interaction in Raphaƫl
var paper = Raphael('raphaelInteraction', 200, 200); var r = paper.rect(60, 60, 80, 80); r.attr({'fill': '#00aeef', 'stroke': '#00aeef'}); var clicked = false; r.click(function() { if (clicked) { r.attr({'fill': '#00aeef', 'stroke': '#00aeef'}); } else { r.attr({'fill': '#f00ff0', 'stroke': '#f00ff0'}); } clicked = !clicked; });
The click () function in Raphaƫl works like in jQuery, and it can be hung on any object. Having received a click event, changing the color of the square is not a problem. Raphaƫl has additional functions to support dragging, moving the cursor over an object, and all other events that are available in JavaScript.
Interaction in Paper.js
Paper.js goes a different way to serve the interaction tasks, but itās also pretty simple:
var hitOptions = { fill: true, tolerance: 5 }; function init() { var point = new Point(60, 60); var size = new Size(80, 80); var rectangle = new Rectangle(point, size); r = new Path.Rectangle(rectangle); r.fillColor = '#ee2a33'; } function onMouseUp(event) { var hitResult = project.hitTest(event.point, hitOptions); if (hitResult && hitResult.item) { if (hitResult.item.clicked) { hitResult.item.fillColor = '#ee2a33'; } else { hitResult.item.fillColor = '#f00ff0'; } hitResult.item.clicked = !hitResult.item.clicked; } } init();
Paper.js works with a cursor using a concept called ā
hit testing. ā The click point is calculated from the current coordinates of the cursor and the library gets the object located there. The settings allow you to configure the program's behavior: you can specify such things as: how close the cursor should be in order for the object to be counted as a click, whether the object is all its internal space or only an edge. We can apply this click detection to any object (or group of objects) in Paper.js.
The Paper.js team also added an object approach similar to Raphaƫl just a few weeks ago (as of February 2012). Events should appear in the next version.
Interaction in Processing.js
In Processing.js, mouse click detection is quite confusing. Object style is not supported, so we must rely mainly on our own strength.
float bx; float by; int bs = 20; boolean bover = false; boolean clicked = false; void setup() { size(200, 200); bx = width/2.0; by = height/2.0; noStroke(); fill(#52b755); frameRate(10); } void draw() { background(#ffffff);
As soon as Processing.js draws a square, it forgets about it. When we click on a square, we want it to change its color, but the script does not know this, so we must do all the calculations ourselves. The draw () function determines the position of the cursor and calculates whether it lies within our square.
For one square, the code is not so terrible, but for example for a circle you will need to read Pr
2 each time. And more complex shapes, such as ovals, curves, and complex shapes, will require even more mathematics.
No clear winner
Each framework has its own advantages. Each library provides opportunities for creating cool demos and even more cool applications.
Benefits of Paper.js
Paper.js is great for manipulating complex shapes. It can rotate, twist and transform any object in hundreds of different methods. This makes it possible to modify objects using gestures. The new
Google Music Tour , makes the color lines move to the music, showing how this library copes with complex changes to simple shapes.

Another wow factor in Paper.js is support for
raster graphics . Paper.js can completely change the way in which images are displayed ā for example, turning them into
spirals or
cubed sheets (Q * bert boards) .
Benefits of Processing.js
Processing.js' main advantage is its speed, which allows you to create complex animations even on weak machines.
There are a lot of examples, also an excellent example of the smoothness of animation on Processing.js is used on the
Ricardo SƔnchez website.

Water-cutting tails and floating bodies of fish look very natural. Processing.js allows you to achieve this simply by using curves and customizable animations.
Processing.js also supports complex effects on elements, such as shading, lighting, and 3-D transformations. If you want to quickly create complex animations on the canvas, then Processing.js is the best choice.
Benefits of Raphaƫl
One of the best features of Raphaƫl is to support Internet Explorer 7 and 8. If your application needs to support older browsers, then Raphaƫl is the only choice.
Another important advantage of Raphaƫl is its company. Raphaƫl is older than Paper.js and Processing.js, and so he had more time to create a gallery of examples, a tutorial, and descriptions of common problems and ways to solve them. It has built-in support for
easing ,
animation, transformations, and event handlers, which we saw in the interactive example; he also has his own library for
creating graphs .

Raphaƫl also has a great variety of tools.
Instruments
If you worked with Flash, the lack of tools for these libraries will upset you. Many frameworks allow you to edit SVG images, but none of them provide a drag-and-drop way to create applications.
Here are some simple tools, but they may be considered as evidence of the very possibility to create such programs, rather than stand-alone applications. Adobe is working on a program called
Edge , but it still has a lot to go to become a normal tool.
If you want to drag and drop, then Web animation is not for you. At the moment, creating animations in this area is more like programming video games. Writing code to display a circle is more difficult than just clicking and dragging a shape from the palette, this gives many advantages when creating more complex applications.
Let's create something more complicated.
So, we looked at a few simple examples, got acquainted with the advantages and disadvantages of each platform, and understood in which case which one is better suited. Each library has its own pros and cons, but still based on only primitive examples it is rather difficult to judge them.
For comparison, each library were drawn several gears. Each of which consists of two circles, with a set of teeth around the outer circle.

When all surfaces are filled with one color, the figure looks like a gear.

The gear will rotate a little on each frame of the animation. The main gear will set the speed, and all the rest will rotate depending on it. Gears will be located, interlock and rotate each other based on a crazy amount of trigonometry. Place them on the same canvas and you will get a complicated gear system.



Well, it was not really Raphaƫl. The rotation function does not work in Raphaƫl as it does in Paper.js and Processing.js. Raphaƫl does not support rotation around a fixed point. Instead, the gear teeth repaint independently each time and fly around through the air instead of spinning around the center. The only way the author can imagine it can be done is to draw the entire gear and rotate it, but there is too much math there than he would like to bring. If someone wants to try to implement it yourself, welcome, this is Open Source.
The future of drawing on the web
We play with every new technology we have mastered: we hope that it will solve many of our problems and this will pay back investments in its study. Technologies are gaining and losing popularity, but many factors are involved, for example, support for manufacturers or business requirements. The future of our industry is often a guessing game.
Today, Flash does not look like the best technology to learn. Flash has great development tools, years of accumulated development experience, and a big society, but even Adobe is leaving him.
There is a similar situation with SVG. Browsers support it, but do not pay too much attention.
Each browser manufacturer is constantly working to increase the
canvas rendering speed, to get the possibility of using hardware acceleration and better support such libraries as Paper.js and Processing.js. All A-class mobile browsers support
canvas , and their developers are constantly working to improve the quality of this support.
Upd.Sam Dmitry Baranovskiy in the comments to the original article challenged the following statements of its author:
Raphaƫl does not support rotation around a fixed point. - Supports
Raphaƫl does not define any special functions for personnel management - - Defines
He also assured that Raphaƫl even works in IE 6