Rendering remote user cursor

I understand that Yjs nicely provides awareness and presence information. If you are writing a editor-binding, how do you approach the “rendering” of cursors of remote users?

I am working on a Slatejs binding (for purely education). Would you introduce a html span element with a specific css class that resembles a cursor, around the character where the remote user cursor is, in the text render method?

Or are there different practical approaches followed here?

I appreciate if someone can shed the light.

I’ve implemented remote cursors for PRSM and have some tips, although PRSM is a whiteboard-like editor, not a text editor. The cursors for PRSM are indeed HTML elements - DIVs in fact rather than SPANs, although this makes no practical difference. The remote user send an object through the awareness mechanism that includes the user’s name and relative x,y cursor coordinates (since the user’s web page may be zoomed in or out compared with the remote user’s, absolute coordinates will not work). However, you need a throttling mechanism because if several users send awareness data for every mouse movement, the clients will become overwhelmed with data. I use 200 ms, i.e. a coordinate pair is sent no more than once every 200 ms. Also, to give an impression of smooth movement of the remote cursor, the cursor DIV is moved using a CSS transformation, rather than just instantaneously moving the DIV form one location to the next. One also has to think about what to do with the cursor when the remote user goes offline. Using these ideas, I have tested that PRSM will support at least 20 concurrent users’ cursors (and possibly many more - I ran out of patience after setting up 20 PCs!). I hope this helps; let me know if it would be useful to have more detail.

Thanks @micrology for a comprehensive response. You said “relative x, y cursor coordinates”. Can you elaborate what are they relative to?

In the case of characters in a text editor, the cursor position will reference the character ID. If a particular character changes its position because of inserts or deletes of characters before it, then the cursor automatically moves. In your “whiteboard editor”, what’s the equivalent of a character ID?

I assume the answer to both the questions above is “just plain x, y coordinates in a grid”?

Also, PRSM seems cool. I wonder if Yjs is the canonical data model behind your whiteboard, or if you had to write a binding in order to map the data between the whiteboard model and the Yjs model.

In PRSM, a user can zoom in or out of the map (i.e. the displayed arrangement of boxes and links). What I meant by ‘relative’ is that the remote user’s mouse cursor coordinates need to be sent relative to the cursor’s position in the map, not to the browser window. In a text editor, by using the character position, you’ve automatically avoided this issue.

PRSM’s data model is a pair of maps, one that holds data about the nodes (the ‘boxes’) and one that holds data about the links (this is a slight simplification; it actually uses Datasets). Changes to these are copied to a pair of yjs maps and vice versa.

2 Likes

Thanks. That was useful micrology.

I wonder if anyone else has any insight to provide on how to render cursors of remote users in a “text editor”, going back to the first post I made on this thread.

Hi @vowor, this is a very generic question, so I really don’t know what to say. Generally, you transform Yjs’ relative positions to slate-based positions and render them using spans or whatever. Y.RelativePosition - Yjs Docs

I don’t know how to do that specifically with Slate.