From aa47a45a95a368f34363e1a8740638fb50043e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Fri, 27 Feb 2026 20:29:00 +0800 Subject: [PATCH] feat: add touch swipe support for mobile --- src/components/sections/cases-section.tsx | 93 +++++++++++++---------- src/components/sections/news-section.tsx | 85 ++++++++++++--------- src/components/ui/touch-swipe.tsx | 40 +++------- 3 files changed, 112 insertions(+), 106 deletions(-) diff --git a/src/components/sections/cases-section.tsx b/src/components/sections/cases-section.tsx index e34358b..ced3d4e 100644 --- a/src/components/sections/cases-section.tsx +++ b/src/components/sections/cases-section.tsx @@ -7,6 +7,7 @@ import Link from 'next/link'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; +import { TouchSwipe } from '@/components/ui/touch-swipe'; import { CASES } from '@/lib/constants'; import { ArrowRight, Building2, TrendingUp } from 'lucide-react'; @@ -36,48 +37,58 @@ export function CasesSection() {

-
- {featuredCases.map((caseItem, index) => ( - - - -
- -
- - {caseItem.industry} - -
-
- -
- - {caseItem.client} -
-

- {caseItem.title} -

-

- {caseItem.description} -

- {caseItem.results.length > 0 && ( -
- - {caseItem.results[0].value} - {caseItem.results[0].label} + { + // 切换到下一个案例 + }} + onSwipeRight={() => { + // 切换到上一个案例 + }} + className="md:hidden" + > +
+ {featuredCases.map((caseItem, index) => ( + + + +
+ +
+ + {caseItem.industry} +
- )} - - - - - ))} -
+
+ +
+ + {caseItem.client} +
+

+ {caseItem.title} +

+

+ {caseItem.description} +

+ {caseItem.results.length > 0 && ( +
+ + {caseItem.results[0].value} + {caseItem.results[0].label} +
+ )} +
+ + + + ))} +
+ -
- {NEWS.slice(0, 4).map((news, idx) => ( - - - -
- - {news.category} - - - - {news.date} - -
- {news.title} -
- - - {news.excerpt} - - - 阅读更多 - - - -
-
- ))} -
+ { + // 切换到下一页新闻 + }} + onSwipeRight={() => { + // 切换到上一页新闻 + }} + className="md:hidden" + > +
+ {NEWS.slice(0, 4).map((news, idx) => ( + + + +
+ + {news.category} + + + + {news.date} + +
+ {news.title} +
+ + + {news.excerpt} + + + 阅读更多 + + + +
+
+ ))} +
+
(null); - const [touchEnd, setTouchEnd] = useState(null); + const touchStartX = useRef(0); const containerRef = useRef(null); const handleTouchStart = (e: React.TouchEvent) => { - setTouchEnd(null); - const touch = e.targetTouches[0]; - if (touch) { - setTouchStart(touch.clientX); - } + touchStartX.current = e.touches[0].clientX; }; - const handleTouchMove = (e: React.TouchEvent) => { - const touch = e.targetTouches[0]; - if (touch) { - setTouchEnd(touch.clientX); - } - }; + const handleTouchEnd = (e: React.TouchEvent) => { + const touchEndX = e.changedTouches[0].clientX; + const diff = touchStartX.current - touchEndX; - const handleTouchEnd = () => { - if (!touchStart || !touchEnd) {return;} - - const distance = touchStart - touchEnd; - const isLeftSwipe = distance > threshold; - const isRightSwipe = distance < -threshold; - - if (isLeftSwipe && onSwipeLeft) { - onSwipeLeft(); - } - - if (isRightSwipe && onSwipeRight) { - onSwipeRight(); + if (Math.abs(diff) > threshold) { + if (diff > 0 && onSwipeLeft) { + onSwipeLeft(); + } else if (diff < 0 && onSwipeRight) { + onSwipeRight(); + } } }; @@ -57,7 +42,6 @@ export function TouchSwipe({ ref={containerRef} className={className} onTouchStart={handleTouchStart} - onTouchMove={handleTouchMove} onTouchEnd={handleTouchEnd} > {children}