When interacting in real time, we can customize the cursor adapter through cursorAdapter
. It can synchronize and display the mouse cursor of other users in the real-time room, so as to achieve similar effects as follows.
You can install and integrate @netless/cursor-tool
directly in the project, and directly synchronize the cursor with the effect shown in the animation in the previous chapter of your project. This is an open source project, you can also get the source of the library from react-whiteboard | GitHub Code.
Open Terminal and execute the following commands in the directory where your project is located to install.
npm
npm install @netless/cursor-tool
yarn
yarn add @netless/cursor-tool
Before joining the room, you can bind @netless/cursor-tool
with the following code.
import {CursorTool} from "@netless/cursor-tool";
var cursorAdapter = new CursorTool();
var userPayload = {
cursorName: "$cursorName", // the user's name displayed on the cursor
avatar: "$avatar_url", // URL address of the user avatar on the cursor
};
whiteWebSdk.joinRoom({
uuid: "$uuid",
roomToken: "$roomToken",
cursorAdapter: cursorAdapter,
userPayload: userPayload,
}).then(function(room) {
// Bind the room object to the cursor adapter
cursorAdapter.setRoom(room);
});
Before starting to play back the video, you can bind @netless/cursor-tool
with the following code.
import {CursorTool} from "@netless/cursor-tool";
var cursorAdapter = new CursorTool();
whiteWebSdk.replayRoom({
uuid: "$uuid",
roomToken: "$roomToken",
cursorAdapter: cursorAdapter,
}).then(function(player) {
// Bind the player object to the cursor adapter
cursorAdapter.setPlayer(player);
});
In addition to using @netless/cursor-tool
to configure a fixed style cursor for the whiteboard, we can also customize the cursor adapter. You only need to define a class
and implement all the methods of the interface CursorAdapter
, you can define the cursor style according to your own business. The definition of CursorAdapter
is as follows.
interface CursorAdapter {
createCursor(memberId: number): CursorDescription;
onAddedCursor?(cursor: Cursor): void;
onRemovedCursor?(cursor: Cursor): void;
onMovingCursor?(cursor: Cursor, positionX: number, positionY: number): void;
}
First, we need to implement the createCursor
method. This method will be called whenever a user with "optional" permission joins the room. We should make this method return an object
to describe the cursor information. The signature of this method is as follows.
createCursor(memberId: number): CursorDescription;
This method will receive a parameter of memberId
, indicating the ID of the user, and return an object of type CursorDescription
, which is defined as follows.
import React from "react";
type CursorDescription = {
// The point the cursor points to is the x-axis coordinate of the entire cursor view (relative to the upper left corner of the view)
readonly x: number;
// The point the cursor points to is the y-axis coordinate of the entire cursor view (relative to the upper left corner of the view)
readonly y: number;
// The width of the cursor view
readonly width: number;
// The height of the cursor view
readonly height: number;
// ReactNode of the initialized view (optional)
readonly reactNode?: React.ReactNode;
}
The user just joins the room, it does not mean that the cursor will be displayed on the whiteboard. Because the user's mouse may be outside the whiteboard, or the cursor logic decides to hide the cursor, or the user does not have a mouse at all. In short, the following methods will call back when the cursor appears, disappears, or moves.
// The cursor appears
onAddedCursor?(cursor: Cursor): void;
// cursor disappears
onRemovedCursor?(cursor: Cursor): void;
// The cursor is moving: (positionX, positionY) represents the coordinate moved to (relative to the position of the upper left corner of the whiteboard view)
onMovingCursor?(cursor: Cursor, positionX: number, positionY: number): void;
These methods can get the Cursor
object. Every user has a unique Cursor
object corresponding to it. You can change the appearance of the cursor by calling its methods. Its definition is as follows.
import React from "react";
interface Cursor {
// User ID, here can also uniquely identify the cursor
readonly memberId: number;
// Dom node corresponding to cursor view
readonly divElement: HTMLDivElement;
// User information corresponding to the cursor
readonly cursorMember: CursorMember;
// The point the cursor points to is the x-axis coordinate of the entire cursor view (relative to the upper left corner of the view)
readonly x: number;
// The point the cursor points to is the y-axis coordinate of the entire cursor view (relative to the upper left corner of the view)
readonly y: number;
// The width of the cursor view
readonly width: number;
// The height of the cursor view
readonly height: number;
// Modify it to monitor changes in user information corresponding to the cursor
onCursorMemberChanged?: (cursorMember: CursorMember) => void;
// Pass in a ReactNode to define the style
setReactNode(reactNode: React.React): void;
// modify specific fields of cursorDescription
setCursorDescription(description: Partial<CursorDescription>): void;
}
// An array composed of 3 to 4 components from 0 to 255, representing the values of R, G, B, and A respectively
type Color = number[];
interface CursorMember {
// The color of the current user's handwriting
readonly color: Color;
// The current user teaching name
readonly appliance: string;
}
The following code can monitor the changes of cursorMember
.
cursor.onCursorMemberChanged = function(cursorMember) {
// Get the changed cursorMember object
};
The following code can cancel the monitoring of cursorMember
changes.
cursor.onCursorMemberChanged = undefined;
The following code can initialize the appearance of the cursor.
var imgDom = document.createElement("img");
imgDom.src = "https://my-domain/to-my-img.png";
imgDom.width = "24px";
imgDom.height = "24px";
cursor.divElement.appendChild(imgDom);
If you use React, you can use JSX syntax in the jsx
(or tsx
) file to change the cursor appearance.
cursor.setReactNode(
<img src="https://my-domain/to-my-img.png"
width={24} height={24}/>
);