diff --git a/frontend/src/pages/TourDetailPage.tsx b/frontend/src/pages/TourDetailPage.tsx index 9ba355e..fd27cf8 100644 --- a/frontend/src/pages/TourDetailPage.tsx +++ b/frontend/src/pages/TourDetailPage.tsx @@ -222,7 +222,7 @@ const MapRotationHandler = ({ rotation }: { rotation: number }) => { // 1. Dùng translateZ(0) để kích hoạt GPU trên iOS. // 2. Giảm scale xuống ~1.6 (vừa đủ che góc) để giảm tải cho bộ nhớ đệm đồ họa. container.style.transform = `rotate(${cumulativeRotationRef.current}deg) scale(2.2) translateZ(0)`; - container.style.transition = 'transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)'; + container.style.transition = 'transform 0.15s ease-out'; }, [rotation, map]); return null; }; @@ -867,6 +867,8 @@ export const TourDetailPage = ({ // Theo dõi hướng thiết bị (la bàn) useEffect(() => { + let lastHeading: number | null = null; + const handleOrientation = (event: any) => { let heading: number | null = null; @@ -876,17 +878,17 @@ export const TourDetailPage = ({ } // 2. Đối với Android (Chrome): Cần kiểm tra tính tuyệt đối của dữ liệu else if (event.alpha !== null && event.alpha !== undefined) { - // Chrome trên Android chỉ cung cấp hướng la bàn chuẩn khi event.absolute là true - // hoặc khi nhận từ sự kiện 'deviceorientationabsolute' if (event.absolute === true || event.type === 'deviceorientationabsolute') { - // Alpha trên Android tăng theo chiều ngược kim đồng hồ (0=North, 90=West) - // Cần chuyển đổi sang chiều kim đồng hồ để khớp với logic quay bản đồ heading = (360 - event.alpha) % 360; } } if (heading !== null) { - setDeviceOrientationHeading(heading); + // Chỉ cập nhật nếu hướng thay đổi lớn hơn 2 độ để giảm tải vẽ lại + if (lastHeading === null || Math.abs(heading - lastHeading) > 2) { + lastHeading = heading; + setDeviceOrientationHeading(heading); + } } }; @@ -1242,6 +1244,31 @@ export const TourDetailPage = ({ const rejectJoinRequest = useTourStore(state => state.rejectJoinRequest); const deleteTour = useTourStore(state => state.deleteTour); + const toggleCompassMode = async () => { + if (!isHeadingMode) { + if ( + typeof DeviceOrientationEvent !== 'undefined' && + typeof (DeviceOrientationEvent as any).requestPermission === 'function' + ) { + try { + const permissionState = await (DeviceOrientationEvent as any).requestPermission(); + if (permissionState === 'granted') { + setIsHeadingMode(true); + } else { + alert("Để xoay bản đồ theo hướng di chuyển, vui lòng cấp quyền truy cập cảm biến hướng (La bàn)."); + } + } catch (error) { + console.error("Error requesting compass permission:", error); + setIsHeadingMode(true); + } + } else { + setIsHeadingMode(true); + } + } else { + setIsHeadingMode(false); + setMapRotation(0); + } + }; // Khôi phục vị trí và mức zoom từ localStorage const [initialViewState] = useState(() => { @@ -1905,7 +1932,9 @@ export const TourDetailPage = ({ )} - {/* Tour Header Info */} + {!(activeTab === 'plan' && viewMode === 'map') && ( + <> + {/* Tour Header Info */}