Real-time cursor
The problem
Section titled “The problem”You want to show in one tab where another tab’s cursor is — for example, for a collaborative demo within the same browser session — but mousemove fires dozens of events per second. Emitting one for every movement would needlessly flood the channel.
The solution
Section titled “The solution”Use Tabus’s throttle option to limit the actual sending frequency to, say, ~60fps (16ms), taking advantage of the fact that throttling always emits the last value (trailing edge).
import { Tabus } from "tabus-js";
type CursorEvents = { cursor: { x: number; y: number };};
const bus = new Tabus<CursorEvents>("canvas", { throttle: 16 });
// Emit this tab's cursor positionwindow.addEventListener("mousemove", (e) => { bus.emit("cursor", { x: e.clientX, y: e.clientY });});
// Draw the other tabs' cursorconst remoteCursor = document.getElementById("remote-cursor")!;
bus.on("cursor", ({ x, y }) => { remoteCursor.style.transform = `translate(${x}px, ${y}px)`;});
window.addEventListener("beforeunload", () => bus.destroy());Why it works
Section titled “Why it works”- Without
throttle, everymousemovewould emit immediately, generating excessive cross-tab traffic. - With
throttle: 16, the first position of each burst is emitted right away (leading edge) and the rest are dropped until the window expires, at which point the last known position is emitted automatically (trailing edge) — the remote cursor keeps looking smooth without flooding messages. bus.destroy()cancels any pending trailing send, so no “stale” position arrives after the tab closes.
Next step
Section titled “Next step”See Throttling for the full detail of the leading + trailing edge strategy.
