HumanBreak/src/plugin/use.ts

134 lines
3.5 KiB
TypeScript
Raw Normal View History

2022-11-14 17:11:23 +08:00
export default function init() {
2022-11-19 11:30:14 +08:00
return { useDrag, useWheel, useUp, isMobile };
2022-11-14 17:11:23 +08:00
}
2022-11-19 11:30:14 +08:00
type DragFn = (x: number, y: number, e: MouseEvent | TouchEvent) => void;
type DragMap = [
(e: MouseEvent) => void,
(e: TouchEvent) => void,
((e: MouseEvent) => void)?,
((e: TouchEvent) => void)?
];
const dragFnMap = new Map<DragFn, DragMap>();
/**
*
*/
export const isMobile = matchMedia('(max-width: 600px)').matches;
2022-11-14 17:11:23 +08:00
/**
*
* @param ele
* @param fn x y和鼠标事件或点击事件
* @param ondown
* @param global
*/
export function useDrag(
ele: HTMLElement,
2022-11-19 11:30:14 +08:00
fn: DragFn,
ondown?: DragFn,
onUp?: (e: MouseEvent | TouchEvent) => void,
2022-11-14 17:11:23 +08:00
global: boolean = false
) {
let down = false;
ele.addEventListener('mousedown', e => {
down = true;
if (ondown) ondown(e.clientX, e.clientY, e);
});
ele.addEventListener('touchstart', e => {
down = true;
if (ondown) ondown(e.touches[0].clientX, e.touches[0].clientY, e);
});
const target = global ? document : ele;
2022-11-19 11:30:14 +08:00
const mouseFn = (e: MouseEvent) => {
2022-11-14 17:11:23 +08:00
if (!down) return;
2022-11-19 11:30:14 +08:00
fn(e.clientX, e.clientY, e);
};
const touchFn = (e: TouchEvent) => {
2022-11-14 17:11:23 +08:00
if (!down) return;
2022-11-19 11:30:14 +08:00
fn(e.touches[0].clientX, e.touches[0].clientY, e);
};
const mouseUp = (e: MouseEvent) => {
if (!down) return;
onUp && onUp(e);
down = false;
};
const touchUp = (e: TouchEvent) => {
if (!down) return;
onUp && onUp(e);
down = false;
};
target.addEventListener(
'mouseup',
mouseUp as EventListenerOrEventListenerObject
);
target.addEventListener(
'touchend',
touchUp as EventListenerOrEventListenerObject
);
dragFnMap.set(fn, [mouseFn, touchFn, mouseUp, touchUp]);
target.addEventListener(
'mousemove',
mouseFn as EventListenerOrEventListenerObject
);
target.addEventListener(
'touchmove',
touchFn as EventListenerOrEventListenerObject
);
}
/**
*
* @param fn
*/
export function cancelGlobalDrag(fn: DragFn): void {
const fns = dragFnMap.get(fn);
dragFnMap.delete(fn);
if (!fns)
throw new ReferenceError(
'The drag function to be canceled does not exist.'
);
document.removeEventListener('mousemove', fns[0]);
document.removeEventListener('touchmove', fns[1]);
document.removeEventListener('mouseup', fns[0]);
document.removeEventListener('touchend', fns[1]);
2022-11-14 17:11:23 +08:00
}
/**
*
* @param ele
* @param fn
*/
export function useWheel(
ele: HTMLElement,
fn: (x: number, y: number, z: number, e: WheelEvent) => void
): void {
ele.addEventListener('wheel', e => {
fn(e.deltaX, e.deltaY, e.deltaZ, e);
});
}
2022-11-16 23:01:23 +08:00
/**
2022-11-19 11:30:14 +08:00
*
* @param ele
* @param fn
2022-11-16 23:01:23 +08:00
*/
2022-11-19 11:30:14 +08:00
export function useUp(ele: HTMLElement, fn: DragFn): void {
ele.addEventListener('mouseup', e => {
fn(e.clientX, e.clientY, e);
});
ele.addEventListener('touchend', e => {
fn(e.touches[0].clientX, e.touches[0].clientY, e);
});
}