Hiển thị text overlay trên màn hình

This commit is contained in:
2026-06-12 20:35:39 +07:00
parent 00bde46c5e
commit 6a0422aa00
3 changed files with 139 additions and 3 deletions
+84 -3
View File
@@ -369,6 +369,14 @@ function formatSystemDate(dateString) {
}
}
/**
* Kiểm tra xem người dùng có đang dùng thiết bị di động hay không
*/
function isMobileDevice() {
return (window.innerWidth <= 768) ||
(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
}
/**
* Initializes the full-screen Leaflet Map
*/
@@ -388,7 +396,11 @@ function initMap() {
if (isNaN(startZoom)) startZoom = 13;
// Khởi tạo bản đồ với zoomControl và tắt attribution mặc định của Leaflet
map = L.map('map', { zoomControl: true, attributionControl: false }).setView([startLat, startLng], startZoom);
map = L.map('map', {
zoomControl: !isMobileDevice(), // Ẩn nút +/- trên mobile để lấy thêm không gian hiển thị
attributionControl: false,
tap: true // Hỗ trợ click trên thiết bị cảm ứng tốt hơn
}).setView([startLat, startLng], startZoom);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
@@ -1056,7 +1068,7 @@ async function loadScenes(urlToken = null) {
let thumbUrl = `${API_BASE_URL}/assets/view/${assetId}`;
if (token) thumbUrl += `?token=${token}`;
else if (scene.privacy === 'shared' && scene.shareToken) thumbUrl += `?token=${scene.shareToken}`;
thumbHtml = `<img src="${thumbUrl}" alt="${sceneName}">`;
thumbHtml = `<img src="${thumbUrl}" alt="${sceneName}" loading="lazy">`;
}
const calloutIcon = L.divIcon({
@@ -1423,6 +1435,9 @@ async function openScene(sceneId, privacy, shareToken, force = false, initialPit
// Initialize 3D Viewer with secure, referer-protected image stream
initPanoramaViewer(secureImageUrl, hotspots || [], sceneOwnerId, initialPitch, initialYaw);
// Hiển thị thông tin overlay góc màn hình
updateViewerInfoOverlay(scene);
// Sau khi mở thành công từ URL trực tiếp, xóa tham số để làm sạch thanh địa chỉ (URL chuyên nghiệp)
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('sceneId') || window.location.pathname.includes('/api/share/')) {
@@ -1453,6 +1468,72 @@ async function openScene(sceneId, privacy, shareToken, force = false, initialPit
}
}
/**
* Cập nhật overlay thông tin cảnh đang xem (Góc dưới bên trái)
*/
async function updateViewerInfoOverlay(scene) {
if (!scene) {
console.warn("updateViewerInfoOverlay: Scene object is null or undefined. Cannot display info.");
return;
}
let overlay = document.getElementById('viewer-info-overlay');
if (!overlay) {
overlay = document.createElement('div');
overlay.id = 'viewer-info-overlay';
// Append to body to allow independent positioning and animation
document.body.appendChild(overlay);
}
const lang = systemSettings.language || 'vi';
const name = scene.name || scene.title || (lang === 'vi' ? "Cảnh không tên" : "Untitled Scene");
const desc = scene.description || "";
const author = scene.createdBy?.username || (lang === 'vi' ? "Ẩn danh" : "Anonymous");
const date = formatSystemDate(scene.createdAt);
// Lấy tọa độ để truy vấn địa chỉ
const lat = scene.gps?.lat || scene.lat;
const lng = scene.gps?.lng || scene.lng;
let locationText = lang === 'vi' ? "Đang xác định vị trí..." : "Locating...";
overlay.innerHTML = `
<div class="info-content">
<h4>${name}</h4>
${desc ? `<p>${desc}</p>` : ''}
<div class="info-meta">
<span>👤 ${author}</span>
<span>📸 ${lang === 'vi' ? 'Ngày chụp' : 'Date taken'}: ${date}</span>
<span id="overlay-address">📍 ${locationText}</span>
</div>
</div>
`;
overlay.classList.add('show'); // Make it visible with transition
// Thực hiện Reverse Geocoding để lấy địa chỉ từ tọa độ
try {
const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
const data = await res.json();
const address = data.display_name || `${lat.toFixed(4)}, ${lng.toFixed(4)}`;
const addrElem = document.getElementById('overlay-address');
if (addrElem) addrElem.innerText = `📍 ${address}`;
} catch (e) {
const addrElem = document.getElementById('overlay-address');
if (addrElem) addrElem.innerText = `📍 ${lat.toFixed(4)}, ${lng.toFixed(4)}`;
}
}
/**
* Ẩn overlay thông tin cảnh đang xem
*/
window.hideViewerInfoOverlay = function() {
const overlay = document.getElementById('viewer-info-overlay');
if (overlay) {
overlay.classList.remove('show'); // Hide it with transition
// Optionally remove from DOM after transition if not needed
// setTimeout(() => overlay.remove(), 300); // Match CSS transition duration
}
}
/**
* Khôi phục Scene đang xem từ localStorage sau khi reload trang
*/
@@ -1951,7 +2032,7 @@ async function loadMyTours() {
if (assetId) {
let thumbUrl = `${API_BASE_URL}/assets/view/${assetId}`;
if (token) thumbUrl += `?token=${token}`;
card.style.backgroundImage = `url('${thumbUrl}')`;
card.innerHTML = `<img class="tour-card-bg" src="${thumbUrl}" loading="lazy">`;
} else {
card.style.backgroundColor = '#1a1a1a';
}