Skip to content

Commit 4641c4f

Browse files
committed
added multiple user cursors
1 parent e512aa8 commit 4641c4f

File tree

1 file changed

+59
-37
lines changed

1 file changed

+59
-37
lines changed

app/src/components/main/Canvas.tsx

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { RootState } from '../../redux/store';
1515
import { combineStyles } from '../../helperFunctions/combineStyles';
1616
import renderChildren from '../../helperFunctions/renderChildren';
1717
import { emitEvent, getSocket } from '../../helperFunctions/socket';
18-
import { GiBoba } from "react-icons/gi";
18+
import { GiBoba } from 'react-icons/gi';
1919

2020
function Canvas(props: {}): JSX.Element {
2121
const state = useSelector((store: RootState) => store.appState);
@@ -24,44 +24,62 @@ function Canvas(props: {}): JSX.Element {
2424
const userName = useSelector((store: RootState) => store.roomSlice.userName);
2525
const userList = useSelector((store: RootState) => store.roomSlice.userList);
2626

27-
//-------mouse tracking-------
27+
//-------cursors tracking-------
2828
console.log('canvas is rendered');
2929

30-
//remote cursor data
31-
const [remoteCursor, setRemoteCursor] = useState({
32-
x: 0,
33-
y: 0,
34-
remoteUserName: '',
35-
isVisible: false
36-
});
30+
const [remoteCursors, setRemoteCursors] = useState([]);
3731

3832
const debounceSetPosition = debounce((newX, newY) => {
3933
//emit socket event every 500ms when cursor moves
4034
if (userList.length > 1)
4135
emitEvent('cursorData', roomCode, { x: newX, y: newY, userName });
42-
}, 100);
36+
}, 300);
4337

4438
const handleMouseMove = (e) => {
4539
debounceSetPosition(e.clientX, e.clientY);
4640
};
4741

4842
const socket = getSocket();
4943
if (socket) {
50-
// console.log('setting up socket listener');
5144
socket.on('remote cursor data from server', (remoteData) => {
52-
setRemoteCursor((prevState) => {
53-
// check if the received data is different from the current state
54-
if (prevState.x !== remoteData.x || prevState.y !== remoteData.y) {
55-
return {
45+
setRemoteCursors((prevState) => {
46+
//check if received cursor data is from an existing user in the room
47+
const cursorIdx = prevState.findIndex(
48+
(cursor) => cursor.remoteUserName === remoteData.userName
49+
);
50+
51+
//[{x,y,remoteUserName, isVisible}, {...}, {...}]
52+
//existing user
53+
if (cursorIdx >= 0) {
54+
//check if cursor position has changed
55+
if (
56+
prevState[cursorIdx].x !== remoteData.x ||
57+
prevState[cursorIdx].y !== remoteData.y
58+
) {
59+
//update existing user's cursor position
60+
const updatedCursors = [...prevState];
61+
updatedCursors[cursorIdx] = {
62+
...prevState[cursorIdx],
63+
x: remoteData.x,
64+
y: remoteData.y
65+
};
66+
return updatedCursors;
67+
} else {
68+
//return previous state if no change
69+
return prevState;
70+
}
71+
} else {
72+
//new user: add new user's cursor
73+
return [
5674
...prevState,
57-
x: remoteData.x,
58-
y: remoteData.y,
59-
remoteUserName: remoteData.userName,
60-
isVisible: true
61-
};
75+
{
76+
x: remoteData.x,
77+
y: remoteData.y,
78+
remoteUserName: remoteData.userName,
79+
isVisible: true
80+
}
81+
];
6282
}
63-
// if data is the same, return the previous state to prevent re-render
64-
return prevState;
6583
});
6684
});
6785
}
@@ -233,21 +251,25 @@ function Canvas(props: {}): JSX.Element {
233251
>
234252
{renderChildren(currentComponent.children)}
235253

236-
{remoteCursor.isVisible && (
237-
<div
238-
className="remote-cursor"
239-
style={{
240-
position: 'absolute',
241-
left: remoteCursor.x + 'px',
242-
top: remoteCursor.y - 68 + 'px',
243-
//cursor style
244-
fontSize: '40px',
245-
color: '#46c0a5'
246-
}}
247-
>
248-
{<GiBoba />}
249-
{remoteCursor.remoteUserName}
250-
</div>
254+
{remoteCursors.map(
255+
(cursor, idx) =>
256+
cursor.isVisible && (
257+
<div
258+
key={idx}
259+
className="remote-cursor"
260+
style={{
261+
position: 'absolute',
262+
left: cursor.x + 'px',
263+
top: cursor.y - 68 + 'px',
264+
//cursor style
265+
fontSize: '40px',
266+
color: '#46c0a5'
267+
}}
268+
>
269+
{<GiBoba />}
270+
{cursor.remoteUserName}
271+
</div>
272+
)
251273
)}
252274
</div>
253275
);

0 commit comments

Comments
 (0)