Spaces:
Running
Running
import { createClient } from "https://cdn.skypack.dev/@liveblocks/client"; | |
let PUBLIC_KEY = "pk_test_L8JkCoBm0bYACwp5oOJQsj2n"; | |
let roomId = "javascript-live-cursors"; | |
overrideApiKeyAndRoomId(); | |
if (!/^pk_(live|test)/.test(PUBLIC_KEY)) { | |
console.warn( | |
`Replace "${PUBLIC_KEY}" by your public key from https://liveblocks.io/dashboard/apikeys.\n` + | |
`Learn more: https://github.com/liveblocks/liveblocks/tree/main/examples/javascript-live-cursors#getting-started.` | |
); | |
} | |
const client = createClient({ | |
publicApiKey: PUBLIC_KEY, | |
}); | |
const room = client.enter(roomId, { initialPresence: { cursor: null } }); | |
const cursorsContainer = document.getElementById("cursors-container"); | |
const text = document.getElementById("text"); | |
room.subscribe("my-presence", (presence) => { | |
const cursor = presence?.cursor ?? null; | |
text.innerHTML = cursor | |
? `${cursor.x} × ${cursor.y}` | |
: "Move your cursor to broadcast its position to other people in the room."; | |
}); | |
/** | |
* Subscribe to every others presence updates. | |
* The callback will be called if you or someone else enters or leaves the room | |
* or when someone presence is updated | |
*/ | |
room.subscribe("others", (others, event) => { | |
switch (event.type) { | |
case "reset": { | |
// Clear all cursors | |
cursorsContainer.innerHTML = ""; | |
for (const user of others.toArray()) { | |
updateCursor(user); | |
} | |
break; | |
} | |
case "leave": { | |
deleteCursor(event.user); | |
break; | |
} | |
case "enter": | |
case "update": { | |
updateCursor(event.user); | |
break; | |
} | |
} | |
}); | |
// get mouse position relative to an element | |
function getMousePosition(event, element) { | |
const rect = element.getBoundingClientRect(); | |
return { | |
x: event.clientX - rect.left, | |
y: event.clientY - rect.top, | |
}; | |
} | |
// Get mouse position related to a transform and a scale | |
// function getMousePosition(event, transform, scale) { | |
// console.log(scale); | |
// const rect = event.target.getBoundingClientRect(); | |
// const x = (event.offsetX - transform.x) / scale; | |
// const y = (event.offsetY - transform.y) / scale; | |
// return { x, y }; | |
// } | |
document.addEventListener("pointermove", (e) => { | |
e.preventDefault(); | |
// const { offsetX, offsetY, clientX, clientY } = e; | |
// console.log(offsetX, offsetY, clientX, clientY); | |
// console.log(getMousePosition(e, board)); | |
room.updatePresence({ | |
cursor: getMousePosition(e, board), | |
}); | |
}); | |
document.addEventListener("pointerleave", (e) => { | |
room.updatePresence({ cursor: null }); | |
}); | |
const COLORS = ["#DC2626", "#D97706", "#059669", "#7C3AED", "#DB2777"]; | |
// Update cursor position based on user presence | |
function updateCursor(user) { | |
const cursor = getCursorOrCreate(user.connectionId); | |
if (user.presence?.cursor) { | |
cursor.style.transform = `translateX(${user.presence.cursor.x}px) translateY(${user.presence.cursor.y}px)`; | |
cursor.style.opacity = "1"; | |
} else { | |
cursor.style.opacity = "0"; | |
} | |
} | |
function getCursorOrCreate(connectionId) { | |
let cursor = document.getElementById(`cursor-${connectionId}`); | |
if (cursor == null) { | |
cursor = document.getElementById("cursor-template").cloneNode(true); | |
cursor.id = `cursor-${connectionId}`; | |
cursor.style.fill = COLORS[connectionId % COLORS.length]; | |
cursorsContainer.appendChild(cursor); | |
} | |
return cursor; | |
} | |
function deleteCursor(user) { | |
const cursor = document.getElementById(`cursor-${user.connectionId}`); | |
if (cursor) { | |
cursor.parentNode.removeChild(cursor); | |
} | |
} | |
/** | |
* This function is used when deploying an example on liveblocks.io. | |
* You can ignore it completely if you run the example locally. | |
*/ | |
function overrideApiKeyAndRoomId() { | |
const query = new URLSearchParams(window?.location?.search); | |
const apiKey = query.get("apiKey"); | |
const roomIdSuffix = query.get("roomId"); | |
if (apiKey) { | |
PUBLIC_KEY = apiKey; | |
} | |
if (roomIdSuffix) { | |
roomId = `${roomId}-${roomIdSuffix}`; | |
} | |
} | |