Collaborative drawings made with LiaScript
- André Dietrich
- Article
- August 6, 2024
In this article we will explore how to create a collaborative drawing canvas (in other words a whiteboard) using LiaScript’s internal publish -subscribe mechanisms. This feature will allows multiple users to interact with the same LiaScript course in real-time, enabling collaborative drawing and marking, as demonstrated in the following video.
1. Publish-Subscribe (How does it work?)
The publish-subscribe (pub-sub) pattern is a messaging paradigm where messages are sent by publishers to specific topics without the publisher knowing who, if anyone, will receive the message. Subscribers, on the other hand, express interest in one or more topics and receive messages that are published to those topics. This decouples the components of a system, allowing them to interact without direct communication.
The global LIA
object, that can be accessed in any LiaScript course, provides a pub-sub mechanism at LIA.classroom
that becomes active when a new classroom is established, with the following features:
Connection Status:
// true if connection to a classroom has been established LIA.classroom.connected;
This property indicates whether there is an active connection to the classroom.
Event Listeners for Connection and Disconnection:
// creates a callback on a connection LIA.classroom.on("connect", () => { console.log("you are now connected"); }); // callback for the disconnection LIA.classroom.on("disconnect", () => { console.log("you are now disconnected"); });
These lines set up event listeners that trigger specific actions (callbacks) when the connection status changes. When a classroom connection is established or disconnected. Use this to update the UI or perform other actions based on the connection status.
Publishing Messages:
// publish some data on a topic LIA.classroom.publish("testing-topic", { data: "Hello World" });
This line demonstrates the publisher side of the pub-sub pattern. The
publish
method sends a message containing{ data: "Hello World" }
to the specified topic ("testing-topic"
). The message has to be defined in a valid JSON format. Any subscribers to this topic will receive this message.Subscribing to Messages:
// subscribe to all messages of a topic const subID = LIA.classroom.subscribe("testing-topic", (message) => { console.log("received", message); });
Here, a subscription is created for the topic
"testing-topic"
. When any message is published to this topic, the provided callback function is executed, logging the received message. Thesubscribe
method returns a subscription ID (subID
) which is used to manage the subscription.Unsubscribing from Messages:
// do not receive messages anymore LIA.classroom.unsubscribe(subID);
This line shows how to stop receiving messages from a topic. By passing the subscription ID (
subID
) to theunsubscribe
method, the subscription is canceled, and no further messages for that topic will be received.
Summary
- Publish: Send a message to a topic without knowing who will receive it.
- Subscribe: Express interest in a topic to receive messages published to that topic.
- Unsubscribe: Cancel the subscription to stop receiving messages from a topic.
- Connection Management: Handle connection events to know when connected or disconnected from the messaging system.
2. Building a collaborative canvas
Within the header of this document we have defined some global helper functions, that will be used by the script and can also be used by others. Setting persistency to true
will ensure that the canvas and page is not destroyed, when another slide is visited.
The code below demonstrates the basic publish-subscribe principles in action. It creates a canvas
element, which will be used for drawing. It does also contain a background-image. The script therefor access the canvas and adds a click event listener, which records the mouse position and draws a dot at that position. This dot is also added to a set of dots.
Using sets as a data structure ensures that each dot is unique, and the drawing is not duplicated and most of all, we can merge the dots of all users without having to worry about conflicts.
You can try this example out by clicking onto the following button. Simply change the name of the room and click onto connect. Then copy the new URL into another or a couple of other browsers and start clicking. You will see that all drawings are synchronized in real-time.
Try this example3. Creating a reusable LiaScript component
Copy and pasting the entire code-snippets over and over again is tedious, too complicated and generates a lot of redundancy. Therefore, we had created a reusable LiaScript document that can be included in any LiaScript course. You can find it at:
https://github.com/LiaTemplates/CollaborativeDrawing
The code looks like follows. As you can see, we have moved all script-definitions into separate @macros
. Which allows us to inject the associated script and canvas tags into any LiaScript course and configure it appropriately.
For every macro a uiniqe set of ids and topics are generated, so that multiple instances of the same component can run in parrallel without interfering with each other. See therefor the last section in the code below.
Importing the component
The following example shows, what is needed to import the component into any LiaScript course. The @import
directive is used to include the content of the specified URL into the current document. This will create a Markdown file, that can can make use of the imported macros.
You can modify the following code, recompile it, and share your example by clicking onto:
Menu
-> Share course via : data-URI
after opening the link in LiaScript, click onto:
Share
-> Classroom
-> Select a backend
-> Add a room name
-> Connect
or checkout the first video…
…
Leave us a comment ;-) …