Parallel drawing with paper.js

I have an application that draws a widget based on paper.js. Several users can draw at the same time, and changes are transmitted to each other in real time. The problem is that I need to save the changes and display the images while the document is loaded.

A natural solution is to save the commands sent by clients to the database. But reverse images can consist of thousands of commands, and I can have dozens of images. Therefore, when I open a document, getting a list of commands from the server, drawing can take too much time.

Is there a better way to store images and interactions between clients?

Please note that I have a zoom function, so saving a raster is not an option.

UPDATE: If I store an image (e.g. in a BLOB ), it does not understand how to apply the changes made in real time. Transferring an image every time is not the solution I want.

+7
javascript html5 paperjs
source share
4 answers

If you are going to save a picture as an image, you have several possible solutions.

  • Save the item somewhere in the folder and save the directory path + file name in your database
  • Save images to the database as blob . However, Blobs do work really hard with the database.

There are some interesting articles about blob. Like this one from Microsoft.

As expected from common wisdom, objects smaller than 256 KB are best stored in the database, and objects larger than 1 M are best stored in the file system.

Thus, this would be the best solution to save the image to a directory.

You can also export the svg file of the drawn image. ( info ) I do not know if this will help you, but this is my personal experience. And I agree with you that storing thousands of commands in a database is not the best solution. Thus, you may want to take a look at saving images somewhere, but then you will lose the ability to edit the image, if implemented.

Update:

If you do not want to save blob , the best solution would be to "render" the image every time you edit it. This way you can execute all the commands when someone opens a drawing. And just use the latest commands when starting editing.

There are several options for achieving this. As Jimmy Chandra said, firebase would be a good solution. They also provide a tutorial that has everything you want to achieve. (drawing an image using x and y coordinates in real time). Maybe you should take a look at this.

A bit more information about Firebase.

Firebase is a powerful API for storing and synchronizing data in real time.

This is exactly what you want to achieve, I believe. You can try the full tutorial here .

Another option you can consider is nodejs . I have seen people using nodejs for chat systems to send data to all other users. If you can send data, I'm sure you can make an image with it.

In the end, it's up to you which technology you want to use. Therefore, I think that you will have to research several solutions, as I suggested, and ask another question if you have any problems with the integration of this technology.

+2
source share

Is client-side data stored as secondary storage?

With the html5 api file, a copy of all save commands sent by clients to the database may be saved. Therefore, the next time you open the document, the application will display the drawing from the secondary storage, while simultaneously requesting the latest updates on the server, these updates will be added after the secondary storage has finished rendering.

With websockets you can save commands and translate changes to other clients and, therefore, update their drawing with changes in real time.

+1
source share

2 years ago I developed something similar (in a team, closed source).

The first thing to note is that something similar is already permitted by google docs. We read every blog post and article on how they did it, and applied it to the multi-user SVG as a simple editor. So here is what I remember:

Refusing simple commands is the right way. As you wrote, with them you can recreate your images in great detail. You can even precisely answer that the image looked through each programmed time stamp.

Examples of commands may be

 - change color - change color again - draw a line from .. to .. - draw a line from .. to .. - draw a line from .. to .. - draw a line from .. to .. - smooth that line - change color - change Stroke - delete those lines and draw them again ;-) 

Back to the goolge example documents, they save and translate every change to a character (and much more).

Yes, this is a very understandable and verifiable approach, but the request requires a different logical level. You must add a procedure that simplifies these commands for the compressed version (see below)

When a user requests an image, your system searches for the last compressed image and adds single commands that are not included in your compression program.

Compression Procedure:

Make a video of creating a dummy image (similar to what you expect from your users) in your favorite vector editor, you will notice that from 60% to 80% of the teams are useless to the end result.

The target compression program can have the following three steps:

  • In most cases, you will see yourself in a repositioning position, process or move objects, change the color again and again, setting and undoing other parameters, such as stroke thickness. Even deleting a re-set of items. The routine should optimize these commands to directly output the final result. I am sure this will reduce your list of commands to 10% -50% depending on the type of image you are looking for.

  • squeezing teams. The path in the above example is drawn in line segments, it should. Usually you do not know on the first onMouseDown that it will end on the path with 100 segments and 200 handles. But still, like other users, to show the creation process. Add a command to your program that can draw complex things, such as a path. This is not needed in the process of drawing the user. This command can be used to quickly restore full shapes. A path with 100 points and 200 handles can now be made in one team. Before that, you had a list of at least 300 teams.

  • Reorder Commands. Two path elements drawn by two users at the same time are not easy to compress. A simple solution is to sort the commands by element. The process can take 3 minutes to create each shape. Animation will require a real team order so that each of them is developed at the same time, but the final result does not bother. Each shape can be much easier compressed if ordered by element.

Sorry for the long post, hope it helps

+1
source share

I will give a broader answer with architectural recommendations, so I apologize to perfectionists in advance.

I would use nginx and nodejs using websockets as my application layer and use paperjs on my server side via npm https://www.npmjs.com/package/paper

For my persistence level, I would not only use a db cluster ( mysql / mongodb , etc.), but also use redis as a command cache.

Whenever the commands are executed on the canvas, I would save it in redis and broadcast it to all clients via socket.io , and finally, upon completion / saving / exiting, etc. events triggered by any user, I would save it as an image in my db or fs with a link to the path in my db.

Hope this helps.

0
source share

All Articles