diff --git a/map4.js b/map4.js index a9daac0..e6d731a 100644 --- a/map4.js +++ b/map4.js @@ -8,8 +8,6 @@ const supa = window.supabase.createClient(SUPABASE_URL, SUPABASE_KEY); // =================================== -// デバイスID(ローカル保存) -// =================================== let deviceId = localStorage.getItem("deviceId"); if (!deviceId) { deviceId = crypto.randomUUID(); @@ -30,8 +28,6 @@ const DEFAULT_LNG = 139.752799; // =================================== -// URL パラメータ -// =================================== function loadParams() { const p = new URLSearchParams(location.search); currentGroup = p.get("group"); @@ -42,34 +38,22 @@ } // =================================== -// ピンアイコン(常時ラベルなし) -// =================================== function createIcon(type) { - let pinImg = ""; - - if (type === "self") { - // 自分 → 青い星 - pinImg = "https://maps.gstatic.com/mapfiles/kml/paddle/blu-stars.png"; - } else { - // 他人 → ライトグリーン - pinImg = - "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png"; - } - return L.icon({ - iconUrl: pinImg, + iconUrl: + type === "self" + ? "https://maps.gstatic.com/mapfiles/kml/paddle/blu-stars.png" + : "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png", iconSize: [40, 55], - iconAnchor: [20, 50], // 画像の下あたり + iconAnchor: [20, 50], }); } // =================================== -// 現在地取得 -// =================================== function getPosition() { return new Promise((res, rej) => { navigator.geolocation.getCurrentPosition( - (pos) => res(pos.coords), + pos => res(pos.coords), rej, { enableHighAccuracy: true } ); @@ -77,8 +61,6 @@ } // =================================== -// 地図初期化 -// =================================== function initMap(lat, lng) { map = L.map("map").setView([lat, lng], 15); @@ -88,32 +70,24 @@ } // =================================== -// 自分のピン描画 -// =================================== function renderSelfMarker() { if (selfMarker) map.removeLayer(selfMarker); selfMarker = L.marker([lastLat, lastLng], { icon: createIcon("self"), - interactive: true, }).addTo(map); - // popup(吹き出し) selfMarker.bindPopup(`${currentUser}(あなた)`); - // ★ クリックした位置 e.latlng を使って中央へ selfMarker.on("click", (e) => { - map.panTo(e.latlng, { animate: true, duration: 0.5 }); + map.panTo(e.latlng, { animate: true, duration: 0.4 }); selfMarker.openPopup(); }); } // =================================== -// 自分の位置を Supabase に保存 -// =================================== async function saveMyLocation(lat, lng) { - await supa - .from("locations") + await supa.from("locations") .delete() .eq("group_name", currentGroup) .eq("device_id", deviceId); @@ -128,17 +102,14 @@ } // =================================== -// メンバー一覧 -// =================================== function showMemberList(latestByDevice) { const list = document.getElementById("memberList"); list.innerHTML = ""; - Object.values(latestByDevice).forEach((row) => { + Object.values(latestByDevice).forEach(row => { const li = document.createElement("li"); - const updated = new Date(row.updated_at); - const diff = (Date.now() - updated) / 1000; + const diff = (Date.now() - new Date(row.updated_at)) / 1000; li.classList.add(diff < 30 ? "online" : "offline"); const icon = document.createElement("div"); @@ -147,19 +118,14 @@ li.append(row.user_name); - // ★ メンバー一覧クリック → 対応するピンの click を発火 + // ★ ピンの click を発火(中央移動100%) li.addEventListener("click", () => { if (row.device_id === deviceId) { - if (selfMarker) { - selfMarker.fire("click"); - } + if (selfMarker) selfMarker.fire("click"); return; } - - const mk = otherMarkers.find((m) => m._myDeviceId === row.device_id); - if (!mk) return; - - mk.fire("click"); + const mk = otherMarkers.find(m => m._myDeviceId === row.device_id); + if (mk) mk.fire("click"); }); list.appendChild(li); @@ -167,8 +133,6 @@ } // =================================== -// 他ユーザー描画 -// =================================== async function showOtherUsers() { const { data } = await supa .from("locations") @@ -176,9 +140,8 @@ .eq("group_name", currentGroup) .order("updated_at", { ascending: false }); - if (!Array.isArray(data)) return; - latestByDevice = {}; + if (!Array.isArray(data)) return; for (const row of data) { if (!latestByDevice[row.device_id]) latestByDevice[row.device_id] = row; @@ -186,25 +149,22 @@ showMemberList(latestByDevice); - otherMarkers.forEach((m) => map.removeLayer(m)); + otherMarkers.forEach(m => map.removeLayer(m)); otherMarkers = []; - Object.values(latestByDevice).forEach((row) => { + Object.values(latestByDevice).forEach(row => { if (row.device_id === deviceId) return; const mk = L.marker([row.lat, row.lng], { icon: createIcon("other"), - interactive: true, }).addTo(map); mk._myDeviceId = row.device_id; - // popup mk.bindPopup(`${row.user_name}`); - // ★ ピン直接クリック → e.latlng で中央へ mk.on("click", (e) => { - map.panTo(e.latlng, { animate: true, duration: 0.5 }); + map.panTo(e.latlng, { animate: true, duration: 0.4 }); mk.openPopup(); }); @@ -213,8 +173,6 @@ } // =================================== -// main -// =================================== async function main() { loadParams(); @@ -232,11 +190,9 @@ initMap(lat, lng); renderSelfMarker(); - await saveMyLocation(lat, lng); await showOtherUsers(); - // 自分の位置更新 setInterval(async () => { try { const pos = await getPosition(); @@ -248,11 +204,13 @@ } catch {} }, 8000); - // 他ユーザー更新 setInterval(showOtherUsers, 2000); - const exit = document.getElementById("exitBtn"); - if (exit) exit.onclick = () => (location.href = "index.html"); + document.getElementById("exitBtn").onclick = + () => (location.href = "index.html"); + + // ★ Leaflet の中心ズレを完全修正 + setTimeout(() => map.invalidateSize(), 300); } window.addEventListener("DOMContentLoaded", main);