123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // Composables
- import { useToggleScope } from "../../composables/toggleScope.mjs";
- import { useVelocity } from "../../composables/touch.mjs"; // Utilities
- import { computed, onBeforeUnmount, onMounted, onScopeDispose, shallowRef, watchEffect } from 'vue';
- // Types
- export function useTouch(_ref) {
- let {
- el,
- isActive,
- isTemporary,
- width,
- touchless,
- position
- } = _ref;
- onMounted(() => {
- window.addEventListener('touchstart', onTouchstart, {
- passive: true
- });
- window.addEventListener('touchmove', onTouchmove, {
- passive: false
- });
- window.addEventListener('touchend', onTouchend, {
- passive: true
- });
- });
- onBeforeUnmount(() => {
- window.removeEventListener('touchstart', onTouchstart);
- window.removeEventListener('touchmove', onTouchmove);
- window.removeEventListener('touchend', onTouchend);
- });
- const isHorizontal = computed(() => ['left', 'right'].includes(position.value));
- const {
- addMovement,
- endTouch,
- getVelocity
- } = useVelocity();
- let maybeDragging = false;
- const isDragging = shallowRef(false);
- const dragProgress = shallowRef(0);
- const offset = shallowRef(0);
- let start;
- function getOffset(pos, active) {
- return (position.value === 'left' ? pos : position.value === 'right' ? document.documentElement.clientWidth - pos : position.value === 'top' ? pos : position.value === 'bottom' ? document.documentElement.clientHeight - pos : oops()) - (active ? width.value : 0);
- }
- function getProgress(pos) {
- let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
- const progress = position.value === 'left' ? (pos - offset.value) / width.value : position.value === 'right' ? (document.documentElement.clientWidth - pos - offset.value) / width.value : position.value === 'top' ? (pos - offset.value) / width.value : position.value === 'bottom' ? (document.documentElement.clientHeight - pos - offset.value) / width.value : oops();
- return limit ? Math.max(0, Math.min(1, progress)) : progress;
- }
- function onTouchstart(e) {
- if (touchless.value) return;
- const touchX = e.changedTouches[0].clientX;
- const touchY = e.changedTouches[0].clientY;
- const touchZone = 25;
- const inTouchZone = position.value === 'left' ? touchX < touchZone : position.value === 'right' ? touchX > document.documentElement.clientWidth - touchZone : position.value === 'top' ? touchY < touchZone : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - touchZone : oops();
- const inElement = isActive.value && (position.value === 'left' ? touchX < width.value : position.value === 'right' ? touchX > document.documentElement.clientWidth - width.value : position.value === 'top' ? touchY < width.value : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - width.value : oops());
- if (inTouchZone || inElement || isActive.value && isTemporary.value) {
- start = [touchX, touchY];
- offset.value = getOffset(isHorizontal.value ? touchX : touchY, isActive.value);
- dragProgress.value = getProgress(isHorizontal.value ? touchX : touchY);
- maybeDragging = offset.value > -20 && offset.value < 80;
- endTouch(e);
- addMovement(e);
- }
- }
- function onTouchmove(e) {
- const touchX = e.changedTouches[0].clientX;
- const touchY = e.changedTouches[0].clientY;
- if (maybeDragging) {
- if (!e.cancelable) {
- maybeDragging = false;
- return;
- }
- const dx = Math.abs(touchX - start[0]);
- const dy = Math.abs(touchY - start[1]);
- const thresholdMet = isHorizontal.value ? dx > dy && dx > 3 : dy > dx && dy > 3;
- if (thresholdMet) {
- isDragging.value = true;
- maybeDragging = false;
- } else if ((isHorizontal.value ? dy : dx) > 3) {
- maybeDragging = false;
- }
- }
- if (!isDragging.value) return;
- e.preventDefault();
- addMovement(e);
- const progress = getProgress(isHorizontal.value ? touchX : touchY, false);
- dragProgress.value = Math.max(0, Math.min(1, progress));
- if (progress > 1) {
- offset.value = getOffset(isHorizontal.value ? touchX : touchY, true);
- } else if (progress < 0) {
- offset.value = getOffset(isHorizontal.value ? touchX : touchY, false);
- }
- }
- function onTouchend(e) {
- maybeDragging = false;
- if (!isDragging.value) return;
- addMovement(e);
- isDragging.value = false;
- const velocity = getVelocity(e.changedTouches[0].identifier);
- const vx = Math.abs(velocity.x);
- const vy = Math.abs(velocity.y);
- const thresholdMet = isHorizontal.value ? vx > vy && vx > 400 : vy > vx && vy > 3;
- if (thresholdMet) {
- isActive.value = velocity.direction === ({
- left: 'right',
- right: 'left',
- top: 'down',
- bottom: 'up'
- }[position.value] || oops());
- } else {
- isActive.value = dragProgress.value > 0.5;
- }
- }
- const dragStyles = computed(() => {
- return isDragging.value ? {
- transform: position.value === 'left' ? `translateX(calc(-100% + ${dragProgress.value * width.value}px))` : position.value === 'right' ? `translateX(calc(100% - ${dragProgress.value * width.value}px))` : position.value === 'top' ? `translateY(calc(-100% + ${dragProgress.value * width.value}px))` : position.value === 'bottom' ? `translateY(calc(100% - ${dragProgress.value * width.value}px))` : oops(),
- transition: 'none'
- } : undefined;
- });
- useToggleScope(isDragging, () => {
- const transform = el.value?.style.transform ?? null;
- const transition = el.value?.style.transition ?? null;
- watchEffect(() => {
- el.value?.style.setProperty('transform', dragStyles.value?.transform || 'none');
- el.value?.style.setProperty('transition', dragStyles.value?.transition || null);
- });
- onScopeDispose(() => {
- el.value?.style.setProperty('transform', transform);
- el.value?.style.setProperty('transition', transition);
- });
- });
- return {
- isDragging,
- dragProgress,
- dragStyles
- };
- }
- function oops() {
- throw new Error();
- }
- //# sourceMappingURL=touch.mjs.map
|