diff --git a/frontend/js/main_map.js b/frontend/js/main_map.js index 02b6e4c..884da08 100644 --- a/frontend/js/main_map.js +++ b/frontend/js/main_map.js @@ -24,6 +24,9 @@ document.addEventListener('DOMContentLoaded', () => { // Chạy tuần tự để tránh xung đột luồng xử lý checkAuthStatus(); // 2. Kiểm tra đăng nhập + // 3. Khôi phục cảnh đang xem nếu có (sau khi người dùng reload trang) + restoreActiveScene(); + // Đảm bảo map đã sẵn sàng trước khi nạp data if (map) { // Chỉ nạp danh sách Scene để vẽ marker lên bản đồ @@ -713,7 +716,7 @@ async function deleteScene(sceneId) { /** * Fetches secure scene details and triggers the Panorama viewer */ -async function openScene(sceneId, privacy, shareToken, force = false) { +async function openScene(sceneId, privacy, shareToken, force = false, initialPitch = 0, initialYaw = 0) { // Nếu đang xem chính scene này và không yêu cầu làm mới (force), không cần nạp lại if (!force && currentSceneId === sceneId && document.getElementById('viewer-container').style.display === 'block') { return; @@ -781,7 +784,7 @@ async function openScene(sceneId, privacy, shareToken, force = false) { } // Initialize 3D Viewer with secure, referer-protected image stream - initPanoramaViewer(secureImageUrl, hotspots || [], sceneOwnerId); + initPanoramaViewer(secureImageUrl, hotspots || [], sceneOwnerId, initialPitch, initialYaw); } catch (error) { localStorage.removeItem('activeSceneId'); @@ -799,7 +802,9 @@ function restoreActiveScene() { if (savedSceneId) { const savedPrivacy = localStorage.getItem('activeScenePrivacy'); const savedToken = localStorage.getItem('activeSceneToken'); - openScene(savedSceneId, savedPrivacy, savedToken); + const savedPitch = parseFloat(localStorage.getItem('activeScenePitch')) || 0; + const savedYaw = parseFloat(localStorage.getItem('activeSceneYaw')) || 0; + openScene(savedSceneId, savedPrivacy, savedToken, false, savedPitch, savedYaw); } } diff --git a/frontend/js/viewer360.js b/frontend/js/viewer360.js index ef6c64a..0f04233 100644 --- a/frontend/js/viewer360.js +++ b/frontend/js/viewer360.js @@ -3,6 +3,14 @@ let currentHotspots = []; let securityApplied = false; let currentSceneOwnerId = null; +// Lưu lại góc nhìn hiện tại vào localStorage trước khi trang bị reload (F5) +window.addEventListener('beforeunload', () => { + if (activeViewer) { + localStorage.setItem('activeScenePitch', activeViewer.getPitch()); + localStorage.setItem('activeSceneYaw', activeViewer.getYaw()); + } +}); + /** * Hàm render tùy chỉnh cho hotspot để hiển thị bong bóng callout kèm ảnh thumbnail. * Thay thế icon mặc định của Pannellum bằng cấu trúc HTML mới. @@ -42,8 +50,10 @@ function renderCustomHotspot(hotSpotDiv, args) { * @param {string} imageUrl - Authorized URL to fetch the secure image stream * @param {Array} hotspots - List of hotspots from the database * @param {string} ownerId - ID of the scene owner + * @param {number} initialPitch - Góc nhìn dọc khởi tạo + * @param {number} initialYaw - Góc nhìn ngang khởi tạo */ -function initPanoramaViewer(imageUrl, hotspots = [], ownerId = null) { +function initPanoramaViewer(imageUrl, hotspots = [], ownerId = null, initialPitch = 0, initialYaw = 0) { currentHotspots = hotspots; currentSceneOwnerId = ownerId; const container = document.getElementById('viewer-container'); @@ -98,6 +108,8 @@ function initPanoramaViewer(imageUrl, hotspots = [], ownerId = null) { "type": "equirectangular", "panorama": imageUrl, "autoLoad": true, + "pitch": initialPitch, + "yaw": initialYaw, "showControls": true, "compass": false, "mouseZoom": true, @@ -120,6 +132,8 @@ function closeViewer() { localStorage.removeItem('activeSceneId'); localStorage.removeItem('activeScenePrivacy'); localStorage.removeItem('activeSceneToken'); + localStorage.removeItem('activeScenePitch'); + localStorage.removeItem('activeSceneYaw'); if (activeViewer) { try {