You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.7 KiB
75 lines
1.7 KiB
4 years ago
|
import { watch, Ref } from 'vue';
|
||
4 years ago
|
|
||
|
const SMOOTH_PTG = 14 / 15;
|
||
|
|
||
4 years ago
|
export default function useMobileTouchMove(
|
||
|
inVirtual: Ref<boolean>,
|
||
|
listRef: Ref<Element | undefined>,
|
||
|
callback: (offsetY: number, smoothOffset?: boolean) => boolean,
|
||
|
) {
|
||
4 years ago
|
let touched = false;
|
||
|
let touchY = 0;
|
||
|
|
||
4 years ago
|
let element: HTMLElement | null = null;
|
||
4 years ago
|
|
||
|
// Smooth scroll
|
||
4 years ago
|
let interval: any = null;
|
||
4 years ago
|
|
||
4 years ago
|
const cleanUpEvents = () => {
|
||
|
if (element) {
|
||
|
element.removeEventListener('touchmove', onTouchMove);
|
||
|
element.removeEventListener('touchend', onTouchEnd);
|
||
|
}
|
||
|
};
|
||
4 years ago
|
|
||
4 years ago
|
const onTouchMove = (e: TouchEvent) => {
|
||
4 years ago
|
if (touched) {
|
||
|
const currentY = Math.ceil(e.touches[0].pageY);
|
||
|
let offsetY = touchY - currentY;
|
||
|
touchY = currentY;
|
||
|
|
||
|
if (callback(offsetY)) {
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
|
||
|
// Smooth interval
|
||
|
clearInterval(interval);
|
||
|
interval = setInterval(() => {
|
||
|
offsetY *= SMOOTH_PTG;
|
||
|
|
||
|
if (!callback(offsetY, true) || Math.abs(offsetY) <= 0.1) {
|
||
|
clearInterval(interval);
|
||
|
}
|
||
|
}, 16);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const onTouchEnd = () => {
|
||
|
touched = false;
|
||
|
|
||
|
cleanUpEvents();
|
||
|
};
|
||
|
|
||
4 years ago
|
const onTouchStart = (e: TouchEvent) => {
|
||
4 years ago
|
cleanUpEvents();
|
||
|
|
||
|
if (e.touches.length === 1 && !touched) {
|
||
|
touched = true;
|
||
|
touchY = Math.ceil(e.touches[0].pageY);
|
||
|
|
||
4 years ago
|
element = e.target as HTMLElement;
|
||
|
element!.addEventListener('touchmove', onTouchMove);
|
||
|
element!.addEventListener('touchend', onTouchEnd);
|
||
4 years ago
|
}
|
||
|
};
|
||
|
|
||
|
watch(inVirtual, val => {
|
||
4 years ago
|
listRef.value.removeEventListener('touchstart', onTouchStart);
|
||
4 years ago
|
cleanUpEvents();
|
||
|
clearInterval(interval);
|
||
4 years ago
|
if (val) {
|
||
|
listRef.value.addEventListener('touchstart', onTouchStart);
|
||
4 years ago
|
}
|
||
|
});
|
||
|
}
|