Skip to content

Commit

Permalink
Only capture pointer when a certain threshold is exceeded
Browse files Browse the repository at this point in the history
Only invoke window.move() once every 5ms to prevent performance issues
  • Loading branch information
ratatoeskr666 committed Aug 5, 2023
1 parent 05f279c commit d2cb4ac
Showing 1 changed file with 35 additions and 7 deletions.
42 changes: 35 additions & 7 deletions src/api/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ export function setDraggableRegion(domElementOrId: string | HTMLElement): Promis
domElementOrId : document.getElementById(domElementOrId);
let initialClientX: number = 0;
let initialClientY: number = 0;
let absDragMovementDistance: number = 0;
let isPointerCaptured = false;
let lastMoveTimestamp = performance.now();

if (!draggableRegion) {
return reject({
Expand All @@ -122,19 +125,44 @@ export function setDraggableRegion(domElementOrId: string | HTMLElement): Promis

draggableRegions.set(draggableRegion, { pointerdown: startPointerCapturing, pointerup: endPointerCapturing });

async function onPointerMove(evt: PointerEvent) {
await move(
evt.screenX - initialClientX,
evt.screenY - initialClientY
);
async function onPointerMove(evt: PointerEvent) {

if (isPointerCaptured) {

const currentMilliseconds = performance.now();
const timeTillLastMove = currentMilliseconds - lastMoveTimestamp;
// Limit move calls to 1 per every 5ms - TODO: introduce constant instead of magic number?
if (timeTillLastMove < 5) {
// Do not execute move more often than 1x every 5ms or performance will drop
return;
}

// Store current time minus the offset
lastMoveTimestamp = currentMilliseconds - (timeTillLastMove - 5);

await move(
evt.screenX - initialClientX,
evt.screenY - initialClientY
);

return;
}

// Add absolute drag distance
absDragMovementDistance = Math.sqrt(evt.movementX * evt.movementX + evt.movementY * evt.movementY);
// Only start pointer capturing when the user dragged more than a certain amount of distance
// This ensures that the user can also click on the dragable area, e.g. if the area is menu / navbar
if (absDragMovementDistance >= 10) { // TODO: introduce constant instead of magic number?
isPointerCaptured = true;
draggableRegion.setPointerCapture(evt.pointerId);
}
}

function startPointerCapturing(evt: PointerEvent) {
if (evt.button !== 0) return;
initialClientX = evt.clientX;
initialClientY = evt.clientY;
draggableRegion.addEventListener('pointermove', onPointerMove);
draggableRegion.setPointerCapture(evt.pointerId);
draggableRegion.addEventListener('pointermove', onPointerMove);
}

function endPointerCapturing(evt: PointerEvent) {
Expand Down

0 comments on commit d2cb4ac

Please sign in to comment.