In this tutorial, we will guide you through adding real-time mouse pointers to a web application using SuperViz. Real-time mouse pointers are essential for collaborative applications, allowing users to see each other's cursor movements and interactions on a shared screen. We'll also add an optional video huddle feature for enhanced collaboration.

We'll demonstrate how to use SuperViz to implement real-time mouse pointers in a JavaScript application. Although we'll use a <canvas> element for rendering shared content, the real-time mouse pointers component is versatile and can be used with other HTML elements as well. This flexibility allows developers to integrate real-time pointers in a variety of web application contexts, providing a dynamic and interactive experience similar to collaborative platforms like Google Docs or Figma. Let's get started!

Prerequisite

To follow this tutorial, you will need a SuperViz account and a developer token. If you already have an account and a developer token, you can move on to the next step.

Create an account

To create an account, go to https://dashboard.superviz.com/register and create an account using either Google or an email/password. It's important to note that when using an email/password, you will receive a confirmation link that you'll need to click to verify your account.

Retrieving a Developer Token

To use the SDK, you’ll need to provide a developer token, as this token is essential for associating SDK requests with your account. You can retrieve both development and production SuperViz tokens from the dashboard..
Copy and save the developer token, as you will need it in the next steps of this tutorial.

Step 1: Set Up Your Application

To begin, you'll need to set up a new project where we will integrate the SuperViz packages for real-time mouse pointers and video collaboration.

1. Create a New Project

First, create a new application using Vite with TypeScript.

1
npm create vite@latest mouse-pointers-demo -- --template react-ts
2
cd mouse-pointers-demo

2. Install SuperViz Packages

Next, install the required SuperViz packages which will enable us to add real-time mouse pointer and video features to our application.

1
npm install @superviz/room @superviz/collaboration @superviz/video uuid
  • @superviz/room: Core package for creating and managing SuperViz rooms.
  • @superviz/collaboration: Contains components for collaboration features, including mouse pointers.
  • @superviz/video: Provides video conferencing functionality.
  • uuid: A library for generating unique identifiers, useful for creating unique participant IDs.

3. Configure tailwind

In this tutorial, we'll use the Tailwind css framework. First, install the tailwind package.

1
npm install -D tailwindcss postcss autoprefixer
2
npx tailwindcss init -p

We then need to configure the template path. Open tailwind.config.js in the root of the project and insert the following code.

1
/** @type {import('tailwindcss').Config} */
2
export default {
3
content: [
4
"./index.html",
5
"./src/**/*.{js,ts,jsx,tsx}",
6
],
7
theme: {
8
extend: {},
9
},
10
plugins: [],
11
}

Then we need to add the tailwind directives to the global CSS file the src/index.css.

1
@tailwind base;
2
@tailwind components;
3
@tailwind utilities;

4. Set Up Environment Variables

Create a .env file in your project root and add your SuperViz developer key. This key will be used to authenticate your application with SuperViz services.

1
VITE_SUPERVIZ_API_KEY=YOUR_SUPERVIZ_DEVELOPER_KEY

Step 2: Implement the Main Application

In this step, we'll implement the main application logic to initialize SuperViz and handle real-time mouse pointers with an optional video huddle feature.

1. Import Required Packages

Open src/App.tsx and replace its contents with the following code. Let's start with importing all necessary components:

1
import { createRoom, ParticipantEvent, Room } from "@superviz/room";
2
import { v4 as generateId } from "uuid";
3
4
import { useCallback, useEffect, useState, useRef } from "react";
5
import { MousePointers } from "@superviz/collaboration";
6
import { VideoEvent, VideoHuddle } from "@superviz/video";
7
8
// SuperViz developer token ::
9
const DEVELOPER_TOKEN = import.meta.env.VITE_SUPERVIZ_API_KEY;

Explanation:

  • createRoom, ParticipantEvent, Room: From SuperViz room package for creating and managing rooms.
  • MousePointers: Component from SuperViz collaboration package for showing mouse pointers.
  • VideoEvent, VideoHuddle: From SuperViz video package for implementing video conferencing.
  • React hooks: For managing state and component lifecycle.
  • DEVELOPER_TOKEN: Environment variable for your SuperViz API key.

2. Create the App Component

Next, implement the main App component with state management:

1
const App = () => {
2
// States ::
3
const [participantJoined, setParticipantJoined] = useState(false);
4
const [huddleStarted, setHuddleStarted] = useState(false);
5
6
const roomRef = useRef<Room | null>(null);

Explanation:

  • participantJoined: State to track when the local participant has joined the room.
  • huddleStarted: State to track when the video huddle has started.
  • roomRef: Ref to store the room instance for later use.

3. Initialize SuperViz Room and Mouse Pointers

Add the initialization function that will create the room and add the mouse pointers component:

1
// Initialize ::
2
const initialize = useCallback(async () => {
3
try {
4
const room = await createRoom({
5
developerToken: DEVELOPER_TOKEN,
6
roomId: "ROOM_ID",
7
participant: {
8
id: generateId(),
9
name: "Name " + Math.floor(Math.random() * 10),
10
},
11
group: {
12
id: "GROUP_ID",
13
name: "GROUP_NAME",
14
},
15
});
16
17
// Store the room instance in the ref
18
roomRef.current = room;
19
20
room.subscribe(ParticipantEvent.MY_PARTICIPANT_JOINED, () =>
21
setParticipantJoined(true)
22
);
23
24
const mousePointers = new MousePointers("canvas");
25
room.addComponent(mousePointers);
26
} catch (error) {
27
console.error("Error initializing SuperViz Room:", error);
28
}
29
}, []);
30
31
useEffect(() => {
32
initialize();
33
}, [initialize]);

Explanation:

  • initialize: Async function that sets up the SuperViz room and mouse pointers.
  • createRoom: Creates a room with the specified configuration.
  • room.subscribe: Listens for when the local participant joins the room and updates state.
  • MousePointers: Creates a new instance that will track mouse movements on the canvas element.
  • room.addComponent: Adds the mouse pointers to the room for real-time collaboration.
  • useEffect: Calls the initialize function when the component mounts.

4. Implement Video Huddle Functionality

Add the function to start a video huddle for enhanced collaboration:

1
const startHuddle = async () => {
2
const video = new VideoHuddle({
3
participantType: "host",
4
});
5
6
video.subscribe(VideoEvent.MY_PARTICIPANT_JOINED, () =>
7
setHuddleStarted(true)
8
);
9
10
// Use the room instance from the ref
11
if (roomRef.current) {
12
roomRef.current.addComponent(video);
13
}
14
};

Explanation:

  • startHuddle: Function to create and start a video huddle when called.
  • VideoHuddle: Creates a new video component with the local user as the host.
  • video.subscribe: Listens for when the local participant joins the video huddle and updates state.
  • roomRef.current.addComponent: Adds the video component to the room for real-time video communication.

5. Render the User Interface

Finally, add the render function to display the canvas and video huddle button:

1
return (
2
<div className="w-full h-full bg-gray-200 flex items-center justify-center flex-col relative">
3
<canvas id="canvas" className="w-full h-full"></canvas>
4
5
{participantJoined && !huddleStarted && (
6
<button
7
className="bg-[#6210cc] text-white px-5 py-3 text-xs rounded-lg absolute top-5 left-5 z-10"
8
onClick={startHuddle}
9
>
10
START VIDEO HUDDLE
11
</button>
12
)}
13
</div>
14
);
15
};
16
17
export default App;

Explanation:

  • Canvas Element: A <canvas> element that serves as the shared space where mouse pointers will be tracked.
  • Conditional Button: A button that appears only when the participant has joined but the video huddle hasn't started.
  • onClick Handler: Calls the startHuddle function when the button is clicked.

Step 3: Understanding the Application Structure

Here's a quick overview of how the application components work together:

  1. Room Creation and Management
    • The application creates a SuperViz room when it loads.
    • It subscribes to events from the room to track when participants join.
  2. Mouse Pointers
    • The MousePointers component tracks cursor movements on the canvas.
    • It renders other participants' cursors in real-time on the canvas element.
  3. Video Huddle
    • Optionally, participants can start a video huddle for face-to-face communication.
    • The video huddle enhances collaboration alongside mouse pointer tracking.

Step 4: Running the Application

1. Start the Application

To run your application, use the following command in your project directory:

1
npm run dev

This command will start the development server and open your application in the default web browser.

2. Test the Application

  • Real-Time Mouse Pointers: Open the application in multiple browser windows or tabs to simulate multiple participants and verify that mouse movements are displayed in real-time for all users.
  • Video Huddle Feature: Click the "START VIDEO HUDDLE" button in one window to start a video conference and verify that other participants can join the conference.
  • Collaborative Interaction: Test how mouse pointers and video conferencing work together to create a complete collaborative environment.

Summary

In this tutorial, we implemented real-time mouse pointers and an optional video huddle feature in a web application using SuperViz. We used the @superviz/room package to create and manage the room, the @superviz/collaboration package for mouse pointers, and the @superviz/video package for video conferencing. This setup provides a powerful foundation for collaborative applications where users need to see each other's interactions and communicate in real-time.

Feel free to explore the full code and further examples in the GitHub repository for more details.