HumanBreak/src/plugin/use.ts
2024-04-22 23:08:46 +08:00

172 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { tip } from './utils';
export default function init() {
return { useDrag, useWheel, useUp, isMobile };
}
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 let isMobile = matchMedia('(max-width: 600px)').matches;
let alerted = false;
window.addEventListener('resize', () => {
requestAnimationFrame(() => {
isMobile = matchMedia('(max-width: 600px)').matches;
checkMobile();
});
});
checkMobile();
function checkMobile() {
if (isMobile && !alerted) {
tip(
'info',
'手机端建议使用新版APP或者自带的浏览器进行游玩并在进入游戏后开启游戏内的全屏设置游玩'
);
alerted = true;
}
}
/**
* 向一个元素添加拖拽事件
* @param ele 目标元素,当为全局拖拽时,传入数组表示所有元素共用一个全局拖拽函数
* @param fn 拖拽时触发的函数传入x y和鼠标事件或点击事件
* @param ondown 鼠标按下时执行的函数
* @param global 是否全局拖拽,即拖拽后鼠标或手指离开元素后是否依然视为正在拖拽
*/
export function useDrag(
ele: HTMLElement | HTMLElement[],
fn: DragFn,
ondown?: DragFn,
onup?: (e: MouseEvent | TouchEvent) => void,
global: boolean = false
) {
const touchFn = (e: TouchEvent) => {
fn(e.touches[0].clientX, e.touches[0].clientY, e);
};
const mouseFn = (e: MouseEvent) => {
fn(e.clientX, e.clientY, e);
};
const mouseUp = (e: MouseEvent) => {
const ele = global ? document : e.target;
if (ele) {
(ele as HTMLElement).removeEventListener('mousemove', mouseFn);
}
onup && onup(e);
};
const touchUp = (e: TouchEvent) => {
const ele = global ? document : e.target;
if (ele) {
(ele as HTMLElement).removeEventListener('touchmove', touchFn);
}
onup && onup(e);
};
const md = (e: MouseEvent) => {
const ele = global ? document : e.target;
if (ele) {
(ele as HTMLElement).addEventListener('mousemove', mouseFn);
}
if (ondown) ondown(e.clientX, e.clientY, e);
};
const td = (e: TouchEvent) => {
const ele = global ? document : e.target;
if (ele) {
(ele as HTMLElement).addEventListener('touchmove', touchFn);
}
if (ondown) ondown(e.touches[0].clientX, e.touches[0].clientY, e);
};
if (ele instanceof Array) {
ele.forEach(v => {
v.addEventListener('mousedown', md);
v.addEventListener('touchstart', td);
});
} else {
ele.addEventListener('mousedown', md);
ele.addEventListener('touchstart', td);
}
const target = global ? document : ele;
if (target instanceof Array) {
target.forEach(v => {
v.addEventListener('mouseup', mouseUp);
v.addEventListener('touchend', touchUp);
});
} else {
target.addEventListener('mouseup', mouseUp as EventListener);
target.addEventListener('touchend', touchUp as EventListener);
}
dragFnMap.set(fn, [mouseUp, touchUp]);
}
/**
* 去除一个全局拖拽函数
* @param fn 要去除的函数
*/
export function cancelGlobalDrag(fn: DragFn): void {
const fns = dragFnMap.get(fn);
dragFnMap.delete(fn);
if (!fns) return;
document.removeEventListener('mouseup', fns[0]);
document.removeEventListener('touchend', fns[1]);
}
/**
* 当触发滚轮时执行函数
* @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);
});
}
/**
* 当鼠标或手指松开时执行函数
* @param ele 目标元素
* @param fn 当鼠标或手指松开时执行的函数
*/
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);
});
}
/**
* 当鼠标或手指按下时执行函数
* @param ele 目标元素
* @param fn 当鼠标或手指按下时执行的函数
*/
export function useDown(ele: HTMLElement, fn: DragFn): void {
ele.addEventListener('mousedown', e => {
fn(e.clientX, e.clientY, e);
});
ele.addEventListener('touchstart', e => {
fn(e.touches[0].clientX, e.touches[0].clientY, e);
});
}