diff --git a/src/views/SwipeView.vue b/src/views/SwipeView.vue index fb9c210..5202b9c 100644 --- a/src/views/SwipeView.vue +++ b/src/views/SwipeView.vue @@ -43,7 +43,7 @@
-
+
@@ -242,10 +242,18 @@ const swipeThreshold = 80; // Минимальное расстояние для const cardStyle = ref({}); const swipeAngle = 12; // Угол наклона карты при свайпе (в градусах) const isPanning = ref(false); + +// Для touch событий const touchStartX = ref(0); const touchStartY = ref(0); -const touchCurrentX = ref(0); -const touchCurrentY = ref(0); +const touchEndX = ref(0); +const touchEndY = ref(0); + +// Для mouse событий +const isDragging = ref(false); +const dragStartX = ref(0); +const dragStartY = ref(0); +const dragOffset = ref({ x: 0, y: 0 }); // Вычисляемые свойства const currentUserToSwipe = computed(() => { @@ -306,21 +314,26 @@ const prevPhoto = (userId) => { } }; -// Обработчики жестов для vue3-touch-events -const startSwipe = (event) => { +// Обработчики touch событий +const startTouch = (event) => { isPanning.value = true; touchStartX.value = event.touches[0].clientX; touchStartY.value = event.touches[0].clientY; + + // Сбросить конечные точки + touchEndX.value = 0; + touchEndY.value = 0; }; -const moveSwipe = (event) => { - if (!isPanning.value) return; +const moveTouch = (event) => { + if (!isPanning.value || !touchStartX.value) return; const currentX = event.touches[0].clientX; const currentY = event.touches[0].clientY; - touchCurrentX.value = currentX; - touchCurrentY.value = currentY; + // Сохраняем текущую позицию + touchEndX.value = currentX; + touchEndY.value = currentY; const diffX = currentX - touchStartX.value; const diffY = currentY - touchStartY.value; @@ -344,18 +357,16 @@ const moveSwipe = (event) => { transition: 'none' }; - // Предотвращаем скролл страницы при горизонтальном свайпе - if (Math.abs(diffX) > Math.abs(diffY)) { - event.preventDefault(); - } + // Блокируем скролл страницы при горизонтальном свайпе + event.preventDefault(); } }; -const endSwipe = () => { +const endTouch = (event) => { if (!isPanning.value) return; isPanning.value = false; - const diffX = touchCurrentX.value - touchStartX.value; + const diffX = touchEndX.value - touchStartX.value; // Проверяем, достаточно ли было смещение для действия if (Math.abs(diffX) > swipeThreshold) { @@ -389,19 +400,88 @@ const endSwipe = () => { // Сбрасываем значения touchStartX.value = 0; touchStartY.value = 0; - touchCurrentX.value = 0; - touchCurrentY.value = 0; + touchEndX.value = 0; + touchEndY.value = 0; }; -const handleSwipe = (direction) => { - // Эта функция будет вызываться при обнаружении свайпа v-touch:swipe - // Можем использовать для дополнительной обработки - console.log('Swipe detected:', direction); +// Обработчики mouse событий +const startDrag = (event) => { + isDragging.value = true; + dragStartX.value = event.clientX; + dragStartY.value = event.clientY; + + // Сброс смещения + dragOffset.value = { x: 0, y: 0 }; + + // Добавляем слушатели событий мыши на document + document.addEventListener('mousemove', moveDrag); + document.addEventListener('mouseup', endDrag); }; -const handleCardTap = (event) => { - // Обрабатываем обычный тап по карточке, если нужно - // Например, можно открыть полную информацию о пользователе +const moveDrag = (event) => { + if (!isDragging.value) return; + + const currentX = event.clientX; + const currentY = event.clientY; + + dragOffset.value = { + x: currentX - dragStartX.value, + y: currentY - dragStartY.value + }; + + // Определяем направление свайпа для индикаторов + if (Math.abs(dragOffset.value.x) > Math.abs(dragOffset.value.y)) { + if (dragOffset.value.x > 20) { + swipeDirection.value = 'right'; + } else if (dragOffset.value.x < -20) { + swipeDirection.value = 'left'; + } else { + swipeDirection.value = null; + } + + // Применяем небольшой поворот для естественности + const rotate = dragOffset.value.x * 0.05; + + // Точное следование за курсором + cardStyle.value = { + transform: `translateX(${dragOffset.value.x}px) rotate(${rotate}deg)`, + transition: 'none' + }; + } +}; + +const endDrag = () => { + if (!isDragging.value) return; + + // Проверяем, достаточно ли было смещение для действия + if (Math.abs(dragOffset.value.x) > swipeThreshold) { + // Если перетаскивание было достаточно большим, выполняем действие лайка/пропуска + if (dragOffset.value.x > 0) { + cardStyle.value = { + transform: `translateX(120%) rotate(${swipeAngle}deg)`, + transition: 'transform 0.3s ease' + }; + setTimeout(() => handleLike(), 300); + } else { + cardStyle.value = { + transform: `translateX(-120%) rotate(-${swipeAngle}deg)`, + transition: 'transform 0.3s ease' + }; + setTimeout(() => handlePass(), 300); + } + } else { + // Если перетаскивание небольшое, возвращаем карточку в исходное положение + cardStyle.value = { + transform: 'none', + transition: 'transform 0.3s ease' + }; + swipeDirection.value = null; + } + + // Сбрасываем состояние и удаляем слушатели + isDragging.value = false; + document.removeEventListener('mousemove', moveDrag); + document.removeEventListener('mouseup', endDrag); }; // Основные функции @@ -569,7 +649,9 @@ onMounted(() => { }); onUnmounted(() => { - // Здесь можно выполнить очистку, если необходимо + // Удаляем обработчики мыши при размонтировании компонента + document.removeEventListener('mousemove', moveDrag); + document.removeEventListener('mouseup', endDrag); }); // Следим за изменениями в списке предложений