Infinite drawing app

Link: https://q8wq5.csb.app/

Source: yjs-multiplayer-drawing-app - CodeSandbox

Any tips on the code much appreciated!

9 Likes

Looks great!

In case you like observables you might like https://github.com/YousefED/reactive-crdt to reduce a lot of boilerplate.

Experience is super slick (digging into your repos = aha, that why the drawing is nice and natural). Love the user colored stroke until letting go, then blending together. Perhaps it wouldn’t hurt to let us put mouse over a given user’s dot in upper left, then recolorize the drawings that person made? Option to scale/scroll to past drawings– or forced to live in the moment? As usecase, could imagine fun when talking on the phone (once having hashed room IDs) to co-doodle at same time in a volatile way?

Hey @steveruizok,

Thank you so much for creating this!

I’m sorry, I’ve been absent from this forum for a while now. This looks great! I think this is a beautiful implementation for collaborative drawing (both the code and the drawings).

There are a couple of places where you could be more efficient with creating transactions. E.g.

    doc.transact(() => {
      yLine.set("id", id);
      yLine.set("points", yPoints);
      yLine.set("userColor", user.color);
      yLine.set("isComplete", false);
    });

    rCurrentLine.current = yLine;

    yLines.push([yLine]); // this could be included in the transaction as well

The UndoManager basically tracks locally-created transactions and allows you to undo/redo them. When you create two transactions for the same thing, you might run into weird undo-redo issues.

In the above code, yLines.push(..) creates a separate transaction. Now you have two transactions / changes that are tracked as individual properties on the undo-manager.

Well… in this case it works out because yLine is not yet attached to the document and the first transaction doesn’t produce any changes. I just wanted to showcase how the UndoManager and transactions work together.

Btw, you can also choose to filter changes that you don’t want to be able to undo. In this case, you change the origin of the transaction. e.g. doc.transact(() => {..}, 'my custom origin'). By default UndoManager only tracks unspecified origins.

I love tldraw. I think if you specify more granular ‘change’ events in tldraw (e.g. whenever a point was added) then there could be a similarly efficient binding to Yjs. I would be happy to collaborate with you on that.

Cheers,
Kevin