Canvas Drawing using PubSub - React
When in a meeting, it can be very handy to draw and share your views with all the collaborators. To achieve this, you can develop a drawing board shared in real-time using the publish-subscribe mechanism. If you are not familiar with the PubSub mechanism and the usePubSub hook
, you can follow this guide.
Implementing Canvas Drawing
To implement the Canvas Drawing feature, you need to use a third-party library that provides an easy solution for drawing and rendering on the canvas.
- First install all the dependencies.
npm i "@shawngoh87/react-sketch-canvas"
- With the dependencies installed, make a new
Canvas
component which will be placed in theMeetingView
component, and also add a basic canvas to it.
It is presumed that you are familiar with the basics of setting up a VideoSDK meeting, thus we have not provided Meeting Initialiser code in this guide.
import { ReactSketchCanvas } from "@shawngoh87/react-sketch-canvas";
const MeetingView = () => {
return (
<div>
<WhiteboardView />
</div>
);
};
const WhiteboardView = () => {
//Define a refernce for the canvas
const canvasRef = useRef();
//Define the props required by the canvas element used
const canvasProps = {
width: "100%",
height: "500px",
backgroundImage:
"https://upload.wikimedia.org/wikipedia/commons/7/70/Graph_paper_scan_1600x1000_%286509259561%29.jpg",
preserveBackgroundImageAspectRatio: "none",
strokeWidth: 4,
eraserWidth: 5,
strokeColor: "#000000",
canvasColor: "#FFFFFF",
allowOnlyPointerType: "all",
withViewBox: false,
};
return (
<div>
//Adding the actual canvas object
<ReactSketchCanvas ref={canvasRef} {...canvasProps} />
</div>
);
};
- With this, your canvas is ready for drawing. If you draw something on your board, other participants won't be able to see those drawings yet. To share your drawings with others, use the
usePubSub
hook. Get thepublish()
method from theusePubSub
hook for the topicWHITEBOARD
to send your drawings to all the participants in the meeting.
- The data you need to send to all the participants is the strokes you are drawing, so you will send a stringified JSON to everyone in the message.
import { usePubSub } from "@videosdk.live/react-sdk";
const WhiteboardView = () => {
//.. other declarations
const { publish } = usePubSub("WHITEBOARD");
// This callback from the canvas component will give us the stroke json we need to share
const onStroke = (stroke, isEraser) => {
// We will be setting the `persist:true` so that all the strokes
// are available for the participants who have recently joined
publish(JSON.stringify(stroke), { persist: true });
};
return (
<div>
<ReactSketchCanvas ref={canvasRef} onStroke={onStroke} {...canvasProps} />
</div>
);
};
- Even after publishing, the drawings won't appear to other participants because they need to redraw the strokes received from others. This involves handling the
onMessageReceived
event and theonOldMessagesReceived
event.
-
The data received in these events will be a
stringified JSON
, which needs to be parsed before drawing. -
Additionally, to avoid redrawing the strokes created by the local participant, an extra check is implemented to determine whether the stroke was drawn by the local participant or not.
import { useMeeting,usePubSub } from "@videosdk.live/react-sdk";
const WhiteboardView = () => {
//.. other declarations
const { localParticipant } = useMeeting();
const { publish } = usePubSub("WHITEBOARD", {
onMessageReceived: (message) => {
//Check if the stroke is from remote participant only
if (message.senderId !== localParticipant.id) {
canvasRef.current.loadPaths(JSON.parse(message.message));
}
},
onOldMessagesReceived: (messages) => {
messages.map((message) => {
canvasRef.current.loadPaths(JSON.parse(message.message));
});
},
});
//This callback from the canvas component will give us the stroke json we need to share
const onStroke = (stroke, isEraser) => {
...
};
return (
<div>
<ReactSketchCanvas ref={canvasRef} onStroke={onStroke} {...canvasProps} />
</div>
);
};
Here is a video showcasing the canvas drawing feature after its implementation.
API Reference
The API references for all the methods and events utilized in this guide are provided below.
Got a Question? Ask us on discord