mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-13 18:32:20 +02:00
Squash Odysseus development history
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/** Shared lifecycle guard for frame-style pointer interactions. */
|
||||
|
||||
export function createDirectManipulationSession({
|
||||
name = 'interaction',
|
||||
getContext = () => null,
|
||||
isContextCurrent = () => true,
|
||||
onCancel = () => {},
|
||||
} = {}) {
|
||||
let active = null;
|
||||
let nextId = 1;
|
||||
|
||||
const pointerMatches = event => {
|
||||
if (!active || active.pointerId == null || event?.pointerId == null) return true;
|
||||
return active.pointerId === event.pointerId;
|
||||
};
|
||||
|
||||
const releaseCapture = session => {
|
||||
if (!session?.captureTarget || session.pointerId == null) return;
|
||||
try { session.captureTarget.releasePointerCapture(session.pointerId); } catch {}
|
||||
};
|
||||
|
||||
const contextIsCurrent = () => active && isContextCurrent(active.context, active.data);
|
||||
|
||||
function begin(event, data = {}, options = {}) {
|
||||
if (active) cancel('restarted');
|
||||
const pointerId = Number.isFinite(event?.pointerId) ? event.pointerId : null;
|
||||
const captureTarget = options.captureTarget || null;
|
||||
active = {
|
||||
id: nextId++,
|
||||
name,
|
||||
pointerId,
|
||||
captureTarget,
|
||||
context: getContext(),
|
||||
data,
|
||||
};
|
||||
if (captureTarget && pointerId != null) {
|
||||
try { captureTarget.setPointerCapture(pointerId); } catch {}
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
function update(event, callback) {
|
||||
if (!active || !pointerMatches(event)) return false;
|
||||
if (!contextIsCurrent()) {
|
||||
cancel('stale-context');
|
||||
return false;
|
||||
}
|
||||
callback?.(active.data, active);
|
||||
return true;
|
||||
}
|
||||
|
||||
function commit(event, callback) {
|
||||
if (!active || !pointerMatches(event)) return false;
|
||||
if (!contextIsCurrent()) {
|
||||
cancel('stale-context');
|
||||
return false;
|
||||
}
|
||||
const completed = active;
|
||||
active = null;
|
||||
releaseCapture(completed);
|
||||
callback?.(completed.data, completed);
|
||||
return true;
|
||||
}
|
||||
|
||||
function cancel(reason = 'cancelled') {
|
||||
if (!active) return false;
|
||||
const cancelled = active;
|
||||
active = null;
|
||||
releaseCapture(cancelled);
|
||||
onCancel(cancelled.data, reason, cancelled);
|
||||
return true;
|
||||
}
|
||||
|
||||
return {
|
||||
begin,
|
||||
update,
|
||||
commit,
|
||||
cancel,
|
||||
get active() { return active; },
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user