fix(map): مقاوم‌سازی راه‌اندازی نقشه برای موبایل — پیش‌سنجی WebGL، antialias فقط در صورت پشتیبانی، و خطای روشن به‌جای قاب خالی

This commit is contained in:
aramesh-site deploy
2026-10-09 18:01:47 +00:00
parent 2d1c670715
commit 324298c9d7
+23 -2
View File
@@ -53,6 +53,13 @@ export function useMapLibre({ center, zoom, scrollZoom = true, maxBounds, minZoo
let readyFallback: number | undefined
let dprQuery: MediaQueryList | null = null
let handleDprChange: (() => void) | null = null
// آیا می‌توان کانتکست آنتی‌آلیاسه گرفت؟ (تست سبک، یک‌بار در هر ساخت نقشه)
const probeCanvas = document.createElement('canvas')
const canAntialias = Boolean(
probeCanvas.getContext('webgl2', { antialias: true }) ||
probeCanvas.getContext('webgl', { antialias: true }),
)
const controller = new AbortController()
const timeoutId = window.setTimeout(() => controller.abort(), STYLE_TIMEOUT_MS)
@@ -61,6 +68,16 @@ export function useMapLibre({ center, zoom, scrollZoom = true, maxBounds, minZoo
// وب‌ورکر نقشه و پروتکل pmtiles باید پیش از ساخت نقشه آماده باشند؛
// وگرنه نخستین درخواست‌های کاشی در وب‌ورکر بی‌پاسخ می‌مانند
// پیش‌سنجی WebGL: برخی مرورگرهای موبایل (یا حالت ذخیرهٔ باتری/داده) کانتکست
// WebGL نمی‌دهند. بدون این بررسی، سازندهٔ مپ‌لیبر خطا می‌دهد و صفحه در حالت
// «در حال بارگذاری» گیر می‌کند — کاربر فقط یک قاب خالی می‌بیند.
const probe = document.createElement('canvas')
const gl = probe.getContext('webgl2') || probe.getContext('webgl') || probe.getContext('experimental-webgl')
if (!gl) {
setStatus('error')
return
}
Promise.all([loadMapStyle(controller.signal), ensureMapWorker()])
.then(([style]) => {
if (disposed) return
@@ -75,7 +92,9 @@ export function useMapLibre({ center, zoom, scrollZoom = true, maxBounds, minZoo
maxZoom: FALLBACK_MAX_ZOOM,
renderWorldCopies: false,
// لبه‌های نرم‌تر خطوط و چندضلعی‌ها — حس لوکس رندر برداری
canvasContextAttributes: { antialias: true },
// antialias فقط جایی که مطمئنیم پشتیبانی می‌شود — درخواست بی‌قید آن
// روی بعضی GPUهای موبایل کانتکست را رد می‌کند و نقشه ساخته نمی‌شود.
canvasContextAttributes: { antialias: canAntialias },
// کیفیت حداکثری در بزرگ‌نمایی‌های عمیق: هیچ سطحی با مقیاس‌کردن سطح
// بالاتر رندر نمی‌شود و همه‌ی سطح‌ها تا maxZoom از تقسیم هندسه
// می‌آیند (پیش‌فرض ۴ سطح آخر را overscale می‌کند). مبادله: کار
@@ -173,7 +192,9 @@ export function useMapLibre({ center, zoom, scrollZoom = true, maxBounds, minZoo
setMap(instance)
})
.catch(() => {
.catch((error) => {
// خطای ساخت/بارگذاری نقشه — وضعیت خطا با پیام قابل‌تلاش‌دوباره، نه قاب خالی
console.warn('[map] راه‌اندازی نقشه ناموفق بود:', error)
if (!disposed) setStatus('error')
})