From 324f7d95df6020d53f757de1728e9ea2d77032c8 Mon Sep 17 00:00:00 2001 From: Professional Date: Fri, 23 May 2025 18:11:37 +0700 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D1=81=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D0=BA=D0=B8=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 60 +++++++++++++--------------- package.json | 4 +- src/main.js | 17 +++----- src/views/SwipeView.vue | 86 +++++++++++++++++++++++++++-------------- 4 files changed, 91 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc36e84..a137206 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,10 +22,10 @@ "mongoose": "^8.14.3", "multer": "^1.4.5-lts.2", "socket.io-client": "^4.8.1", + "swiper": "^11.0.7", "vue": "^3.5.13", - "vue-hammer": "^0.2.0", "vue-router": "^4.5.1", - "vue-swipe": "^2.4.0" + "vue3-touch-events": "^4.1.8" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", @@ -4150,15 +4150,6 @@ "dev": true, "license": "ISC" }, - "node_modules/hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -6395,6 +6386,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swiper": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.7.tgz", + "integrity": "sha512-oPJCwdcjFMw3SoBM7AdB1RJzjT7JaE4Mg7TWceTmJ/i2OtF8L01Ct+5eOf48nG3trgR0wXFekWdfnTdl0eg6Pg==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -6875,15 +6885,6 @@ } } }, - "node_modules/vue-hammer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/vue-hammer/-/vue-hammer-0.2.0.tgz", - "integrity": "sha512-u/J/TniXJAI/0cL2t3y+ZsEflw7sBl6cWhdlO0qToCDvKN31gaxxBMzZokhJ/SFzI5p2EGO8g0bmXWkbG10rVw==", - "license": "MIT", - "dependencies": { - "hammerjs": "^2.0.4" - } - }, "node_modules/vue-router": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", @@ -6899,14 +6900,11 @@ "vue": "^3.2.0" } }, - "node_modules/vue-swipe": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/vue-swipe/-/vue-swipe-2.4.0.tgz", - "integrity": "sha512-0N5gOED0XF/KsyeF7mT+52J2hGdnHx47xiBbVlZjCxzOyLHWX03W2/G4VhC7bvlMZO7kMt9I/rMPwKZhmk1XTQ==", - "license": "MIT", - "dependencies": { - "wind-dom": "0.0.3" - } + "node_modules/vue3-touch-events": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vue3-touch-events/-/vue3-touch-events-4.2.0.tgz", + "integrity": "sha512-DgZJo8/QE72ilEDJ5+01SJ2JH7Aj55k0PidGLDU1jHewIG3GOW25azFuDsJ6nIXrfN8kMXBRR8PDx0GuNbIXhw==", + "license": "MIT" }, "node_modules/webidl-conversions": { "version": "4.0.2", @@ -7016,12 +7014,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wind-dom": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wind-dom/-/wind-dom-0.0.3.tgz", - "integrity": "sha512-TlL8trn5lguxKs2O9smpnWC8Ti8rvWP1p7A+k+0DKP9mPRwFzYuijebE1I5BbbklAoBlBS1nwT8ng2DZI51tQg==", - "license": "MIT" - }, "node_modules/workbox-background-sync": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz", diff --git a/package.json b/package.json index 9bef6c5..4ca4003 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "multer": "^1.4.5-lts.2", "socket.io-client": "^4.8.1", "vue": "^3.5.13", - "vue-hammer": "^0.2.0", "vue-router": "^4.5.1", - "vue-swipe": "^2.4.0" + "vue3-touch-events": "^4.1.8", + "swiper": "^11.0.7" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", diff --git a/src/main.js b/src/main.js index 215af48..9fd1aa7 100644 --- a/src/main.js +++ b/src/main.js @@ -1,28 +1,23 @@ import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; -import { useAuth } from './auth'; // 1. Импортируем useAuth -import { VueHammer } from 'vue3-hammer'; -import VueSwipe from 'vue-swipe'; - -// Импорт стилей Bootstrap +import { useAuth } from './auth'; +import Vue3TouchEvents from 'vue3-touch-events'; import 'bootstrap/dist/css/bootstrap.min.css'; // Создаем приложение const app = createApp(App); -// Регистрируем библиотеки для улучшенного свайпа -app.use(VueHammer); -app.component('swipe', VueSwipe.Swipe); -app.component('swipe-item', VueSwipe.SwipeItem); +// Подключаем библиотеку для обработки свайпов и жестов +app.use(Vue3TouchEvents); // Используем роутер app.use(router); -// 2. Получаем экземпляр нашего auth "стора" +// Получаем экземпляр нашего auth "стора" const { fetchUser } = useAuth(); -// 3. Асинхронная самовызывающаяся функция для инициализации +// Асинхронная самовызывающаяся функция для инициализации (async () => { try { await fetchUser(); // Пытаемся загрузить пользователя по токену из localStorage diff --git a/src/views/SwipeView.vue b/src/views/SwipeView.vue index ca8ac82..fb9c210 100644 --- a/src/views/SwipeView.vue +++ b/src/views/SwipeView.vue @@ -42,12 +42,9 @@
- - +
+
@@ -160,8 +158,8 @@

{{ user.bio || 'Нет описания.' }}

- - +
+
@@ -244,6 +242,10 @@ const swipeThreshold = 80; // Минимальное расстояние для const cardStyle = ref({}); const swipeAngle = 12; // Угол наклона карты при свайпе (в градусах) const isPanning = ref(false); +const touchStartX = ref(0); +const touchStartY = ref(0); +const touchCurrentX = ref(0); +const touchCurrentY = ref(0); // Вычисляемые свойства const currentUserToSwipe = computed(() => { @@ -304,47 +306,61 @@ const prevPhoto = (userId) => { } }; -// Обработчики жестов для Hammer.js -const onPan = (event) => { +// Обработчики жестов для vue3-touch-events +const startSwipe = (event) => { isPanning.value = true; + touchStartX.value = event.touches[0].clientX; + touchStartY.value = event.touches[0].clientY; +}; + +const moveSwipe = (event) => { + if (!isPanning.value) return; - // Получаем смещение по x и y - const deltaX = event.deltaX; - const deltaY = event.deltaY; + const currentX = event.touches[0].clientX; + const currentY = event.touches[0].clientY; + + touchCurrentX.value = currentX; + touchCurrentY.value = currentY; + + const diffX = currentX - touchStartX.value; + const diffY = currentY - touchStartY.value; // Определяем направление свайпа для индикаторов - if (Math.abs(deltaX) > Math.abs(deltaY)) { - if (deltaX > 20) { + if (Math.abs(diffX) > Math.abs(diffY)) { + if (diffX > 20) { swipeDirection.value = 'right'; - } else if (deltaX < -20) { + } else if (diffX < -20) { swipeDirection.value = 'left'; } else { swipeDirection.value = null; } // Применяем небольшой поворот для естественности - const rotate = deltaX * 0.05; + const rotate = diffX * 0.05; // Применяем точное смещение к карточке, она следует за пальцем 1 к 1 cardStyle.value = { - transform: `translateX(${deltaX}px) rotate(${rotate}deg)`, + transform: `translateX(${diffX}px) rotate(${rotate}deg)`, transition: 'none' }; - } - - // Блокируем скролл страницы при горизонтальном свайпе - if (Math.abs(deltaX) > Math.abs(deltaY)) { - event.srcEvent.preventDefault(); + + // Предотвращаем скролл страницы при горизонтальном свайпе + if (Math.abs(diffX) > Math.abs(diffY)) { + event.preventDefault(); + } } }; -const onPanEnd = (event) => { +const endSwipe = () => { + if (!isPanning.value) return; isPanning.value = false; + const diffX = touchCurrentX.value - touchStartX.value; + // Проверяем, достаточно ли было смещение для действия - if (Math.abs(event.deltaX) > swipeThreshold) { + if (Math.abs(diffX) > swipeThreshold) { // Если свайп был достаточно сильным, выполняем соответствующее действие - if (event.deltaX > 0) { + if (diffX > 0) { // Свайп вправо (лайк) cardStyle.value = { transform: `translateX(120%) rotate(${swipeAngle}deg)`, @@ -369,6 +385,18 @@ const onPanEnd = (event) => { }; swipeDirection.value = null; } + + // Сбрасываем значения + touchStartX.value = 0; + touchStartY.value = 0; + touchCurrentX.value = 0; + touchCurrentY.value = 0; +}; + +const handleSwipe = (direction) => { + // Эта функция будет вызываться при обнаружении свайпа v-touch:swipe + // Можем использовать для дополнительной обработки + console.log('Swipe detected:', direction); }; const handleCardTap = (event) => {