From d6ee1dde74cc176a58d11bfc4815e6f1076a0eae Mon Sep 17 00:00:00 2001 From: 3dtours Date: Wed, 17 Jun 2026 19:19:29 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20th=C3=AAm=20t=C3=ADnh=20n=C4=83ng=20n?= =?UTF-8?q?=C3=BAt=20la=20b=C3=A0n=20=C4=91=E1=BB=83=20xoay=20map=20theo?= =?UTF-8?q?=20h=C6=B0=E1=BB=9Bng=20B=E1=BA=AFc=20ho=E1=BA=B7c=20theo=20h?= =?UTF-8?q?=C6=B0=E1=BB=9Bng=20ng=C6=B0=E1=BB=9Di=20d=C3=B9ng=20di=20chuy?= =?UTF-8?q?=E1=BB=83n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/TourDetailPage.tsx | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/frontend/src/pages/TourDetailPage.tsx b/frontend/src/pages/TourDetailPage.tsx index 58e643d..e727dd1 100644 --- a/frontend/src/pages/TourDetailPage.tsx +++ b/frontend/src/pages/TourDetailPage.tsx @@ -29,6 +29,7 @@ import { Search, LocateFixed, Loader2, + Compass, Car, Bike, Navigation, @@ -98,6 +99,17 @@ const RecenterUser = ({ position, trigger }: { position: [number, number] | null }, [trigger, position, map]); return null; }; +// Component Helper để xử lý xoay bản đồ theo hướng di chuyển hoặc hướng Bắc +const MapRotationHandler = ({ rotation }: { rotation: number }) => { + const map = useMap(); + useEffect(() => { + const container = map.getContainer(); + // Xoay container bản đồ và scale nhẹ để tránh lộ khoảng trắng ở các góc khi xoay + container.style.transform = `rotate(${rotation}deg) scale(${rotation === 0 ? 1 : 1.2})`; + container.style.transition = 'transform 0.5s cubic-bezier(0.4, 0, 0.2, 1)'; + }, [rotation, map]); + return null; +}; // Menu ngữ cảnh cho bản đồ const MapContextMenu = ({ onAction }: { onAction: (action: string, latlng: L.LatLng) => void }) => { const [menuPos, setMenuPos] = useState<{ x: number, y: number, latlng: L.LatLng } | null>(null); @@ -309,6 +321,8 @@ export const TourDetailPage = ({ const [searchResults, setSearchResults] = useState([]); const [isSearching, setIsSearching] = useState(false); const [locateTrigger, setLocateTrigger] = useState(0); + const [isHeadingMode, setIsHeadingMode] = useState(false); + const [mapRotation, setMapRotation] = useState(0); const [isRoutingLoading, setIsRoutingLoading] = useState(false); const [travelMode, setTravelMode] = useState<'driving' | 'bike' | 'foot'>('driving'); const [routes, setRoutes] = useState([]); @@ -1217,6 +1231,9 @@ export const TourDetailPage = ({ {/* Xử lý di chuyển tâm bản đồ về phía người dùng */} + {/* Xử lý xoay bản đồ */} + + {/* Hiển thị vị trí hiện tại của người dùng */} {userLocation && ( @@ -1402,6 +1419,22 @@ export const TourDetailPage = ({ + {/* Nút La bàn / Xoay bản đồ */} + + {/* Nút Tìm tôi */}