47 lines
2.2 KiB
JavaScript
47 lines
2.2 KiB
JavaScript
(function(root,factory){
|
|
const api=factory();
|
|
if(typeof module==='object'&&module.exports)module.exports=api;
|
|
root.BendGestureCoordinator=api;
|
|
})(typeof globalThis!=='undefined'?globalThis:this,function(){
|
|
'use strict';
|
|
|
|
const DEFAULT_PRECEDENCE=Object.freeze({
|
|
wheel:10,
|
|
pan:20,
|
|
pinch:30,
|
|
reaction:40,
|
|
minimap:50,
|
|
draw:60,
|
|
dialog:70
|
|
});
|
|
|
|
function createGestureCoordinator(precedence=DEFAULT_PRECEDENCE){
|
|
const owners=new Map(),listeners=new Set();let revision=0;
|
|
const priority=owner=>Number(precedence[owner])||0;
|
|
const snapshot=()=>Object.freeze({revision,owners:Object.freeze(Object.fromEntries(owners))});
|
|
const notify=(change)=>{revision++;const state=snapshot();for(const listener of listeners)listener(state,change)};
|
|
const claim=(pointerId,owner,{replace=false}={})=>{
|
|
if(pointerId==null||!owner)return false;const key=String(pointerId),next=String(owner),current=owners.get(key);
|
|
if(current===next)return true;
|
|
if(current&&!replace&&priority(next)<=priority(current))return false;
|
|
owners.set(key,next);notify(Object.freeze({type:current?'transfer':'claim',pointerId:key,owner:next,previous:current||null}));return true;
|
|
};
|
|
const release=(pointerId,owner=null,reason='complete')=>{
|
|
if(pointerId==null)return false;const key=String(pointerId),current=owners.get(key);
|
|
if(!current||owner!=null&¤t!==String(owner))return false;
|
|
owners.delete(key);notify(Object.freeze({type:'release',pointerId:key,owner:current,reason}));return true;
|
|
};
|
|
const cancelAll=(reason='cancelled')=>{for(const[key,owner]of[...owners]){owners.delete(key);notify(Object.freeze({type:'release',pointerId:key,owner,reason}))}};
|
|
return Object.freeze({
|
|
claim,
|
|
release,
|
|
cancelAll,
|
|
owner:pointerId=>pointerId==null?null:owners.get(String(pointerId))||null,
|
|
owns:(pointerId,owner)=>owners.get(String(pointerId))===String(owner),
|
|
snapshot,
|
|
subscribe(listener){if(typeof listener!=='function')throw new TypeError('Listener must be a function');listeners.add(listener);return()=>listeners.delete(listener)}
|
|
});
|
|
}
|
|
|
|
return Object.freeze({DEFAULT_PRECEDENCE,createGestureCoordinator});
|
|
});
|