This commit is contained in:
Professional 2025-05-23 18:17:31 +07:00
parent 324f7d95df
commit 2c452f9f20

View File

@ -43,7 +43,7 @@
<div class="container">
<div class="swipe-area" ref="swipeArea">
<!-- Swipeable Card Container -->
<div class="card-stack-container" v-touch:swipe="handleSwipe">
<div class="card-stack-container">
<div
v-for="(user, index) in visibleUsers"
:key="user._id"
@ -55,10 +55,10 @@
'swiping-right': swipeDirection === 'right' && index === 0
}"
:style="index === 0 ? cardStyle : {}"
v-touch:start="index === 0 ? startSwipe : null"
v-touch:moving="index === 0 ? moveSwipe : null"
v-touch:end="index === 0 ? endSwipe : null"
@click="handleCardTap"
@touchstart="index === 0 ? startTouch($event) : null"
@touchmove="index === 0 ? moveTouch($event) : null"
@touchend="index === 0 ? endTouch($event) : null"
@mousedown="index === 0 ? startDrag($event) : null"
>
<!-- Photo Section -->
<div class="card-photo-section">
@ -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);
});
// Следим за изменениями в списке предложений