Extend Cursor-API to show local cursors

This commit is contained in:
Daniel Hammerschmidt 2025-09-17 03:54:13 +02:00
parent 4dd16ad9d8
commit b5b7ebe734
1 changed files with 16 additions and 10 deletions

View File

@ -41,14 +41,15 @@ export default class Cursor {
}; };
} }
attach(target) { attach(target, { showLocalCursor } = {}) {
if (this._target) { if (this._target) {
this.detach(); this.detach();
} }
this._target = target; this._target = target;
this._showLocalCursor = !!showLocalCursor;
if (useFallback) { if (useFallback || this._showLocalCursor) {
document.body.appendChild(this._canvas); document.body.appendChild(this._canvas);
const options = { capture: true, passive: true }; const options = { capture: true, passive: true };
@ -58,7 +59,7 @@ export default class Cursor {
this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options); this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options);
} }
this.clear(); this.clear({ localCursor: showLocalCursor });
} }
detach() { detach() {
@ -66,7 +67,7 @@ export default class Cursor {
return; return;
} }
if (useFallback) { if (useFallback || this._showLocalCursor) {
const options = { capture: true, passive: true }; const options = { capture: true, passive: true };
this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options); this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options);
this._target.removeEventListener('mouseleave', this._eventHandlers.mouseleave, options); this._target.removeEventListener('mouseleave', this._eventHandlers.mouseleave, options);
@ -81,9 +82,9 @@ export default class Cursor {
this._target = null; this._target = null;
} }
change(rgba, hotx, hoty, w, h) { change(rgba, hotx, hoty, w, h, { localCursor } = {}) {
if ((w === 0) || (h === 0)) { if ((w === 0) || (h === 0)) {
this.clear(); this.clear({ localCursor });
return; return;
} }
@ -101,7 +102,8 @@ export default class Cursor {
ctx.clearRect(0, 0, w, h); ctx.clearRect(0, 0, w, h);
ctx.putImageData(img, 0, 0); ctx.putImageData(img, 0, 0);
if (useFallback) { if (useFallback || this._showLocalCursor) {
this._target.style.cursor = localCursor ?? 'none';
this._updatePosition(); this._updatePosition();
} else { } else {
let url = this._canvas.toDataURL(); let url = this._canvas.toDataURL();
@ -109,8 +111,12 @@ export default class Cursor {
} }
} }
clear() { clear({ localCursor } = {}) {
this._target.style.cursor = 'none'; // whilst dragging the viewport and changes to the remote cursor
// are made the target might be detached
if (this._target) {
this._target.style.cursor = localCursor ?? 'none';
}
this._canvas.width = 0; this._canvas.width = 0;
this._canvas.height = 0; this._canvas.height = 0;
this._position.x = this._position.x + this._hotSpot.x; this._position.x = this._position.x + this._hotSpot.x;
@ -122,7 +128,7 @@ export default class Cursor {
// Mouse events might be emulated, this allows // Mouse events might be emulated, this allows
// moving the cursor in such cases // moving the cursor in such cases
move(clientX, clientY) { move(clientX, clientY) {
if (!useFallback) { if (!useFallback && !this._showLocalCursor) {
return; return;
} }
// clientX/clientY are relative the _visual viewport_, // clientX/clientY are relative the _visual viewport_,