soiz1 commited on
Commit
a7ebd15
·
verified ·
1 Parent(s): dc7cba2

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +513 -19
index.html CHANGED
@@ -1,19 +1,513 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="ja">
4
+ <head>
5
+ <link rel="preconnect" href="https://fonts.googleapis.com">
6
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
7
+ <link href="https://fonts.googleapis.com/css2?family=Yomogi&display=swap" rel="stylesheet">
8
+ <meta charset="UTF-8">
9
+ <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ <title>マーカー編集機能付きのLeafletマップ</title>
11
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" />
12
+ <style>
13
+ body{
14
+ font-family: "Yomogi", cursive;
15
+ font-weight: 400;
16
+ font-style: normal;
17
+ background-repeat: repeat; background-image:url("https://lh3.googleusercontent.com/d/1MpGi0bdyjKZNYgKQyMWpIZM0R0q1i4rD");
18
+ background-attachment: fixed;
19
+
20
+ }
21
+ #map { height: 600px; width: 100%; }
22
+ #marker-editor { display: none; position: absolute; top: 10px; left: 10px; background: #fff; padding: 15px; border-radius: 5px; box-shadow: 0 0 15px rgba(0, 0, 0, .3); z-index: 1000; cursor: move; }
23
+ #marker-editor input, #marker-editor textarea { display: block; width: 100%; margin-bottom: 10px; }
24
+ #marker-editor button { width: 100%; padding: 10px; border: none; background-color: #007bff; color: #fff; font-size: 16px; border-radius: 4px; cursor: pointer; }
25
+ #marker-editor button:hover { background-color: #0056b3; }
26
+ input[type=file] { color: #1f2937; cursor: pointer; border: 1px solid #bfc2c7; border-radius: .375rem; padding-right: .5rem; width: 24rem; }
27
+ ::-webkit-file-upload-button, ::file-selector-button { background-color: #d1d5db; color: #1f2937; border: none; cursor: pointer; border-right: 1px solid #bfc2c7; padding: .25rem 1rem; margin-right: 1rem; }
28
+ #icon-preview { display: none; margin-top: 10px; max-width: 100%; }
29
+ #icon-settings { display: none; margin-top: 10px; }
30
+ #icon-settings label { display: block; margin-bottom: 5px; }
31
+
32
+ body::-webkit-scrollbar {
33
+ width: 5px;
34
+ background-color: #c9d8f5;
35
+ }
36
+ body::-webkit-scrollbar-thumb {
37
+ background: #67b9e6;
38
+ width: 5px;
39
+ border-radius: 5px;
40
+ }
41
+ #loading {
42
+ position: fixed;
43
+ top: 0;
44
+ left: 0;
45
+ width: 100%;
46
+ height: 100%;
47
+ background-color: rgba(255, 255, 255, 0.8);
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ font-size: 24px;
52
+ z-index: 9999; /* 最高の重なり順に設定 */
53
+ opacity: 1;
54
+ transition: opacity 0.5s ease; /* フェードアウトのトランジション */
55
+ }
56
+ </style>
57
+ </head>
58
+ <body>
59
+ <div id="loading">Loading...</div>
60
+ <img src="https://lh3.googleusercontent.com/d/1Wo9oLj4D6JEsT_MWUZ4VyaIy10uLN3q0" />
61
+ <div id="map" style="width:90%; margin:5%;"></div>
62
+ <div id="marker-editor">
63
+ <h3>マーカーを編集</h3>
64
+ <label for="marker-lat">緯度:</label>
65
+ <input type="text" id="marker-lat">
66
+ <hr>
67
+ <label for="marker-lng">経度:</label>
68
+ <input type="text" id="marker-lng">
69
+ <hr>
70
+ <a href="javascript:window.open('/tool/marker');">アイコン</a>
71
+ <input type="radio" name="icon-source" value="upload" checked>アップロードから
72
+ <input type="radio" name="icon-source" value="url">URLから読み込む
73
+ <div id="icon-upload-input" style="display: block; margin-bottom: 20px;">
74
+ <label for="marker-icon-upload">マーカーのアイコンをアップロード:</label>
75
+ <input type="file" id="marker-icon-upload" accept="image/*">
76
+ </div>
77
+ <div id="icon-url-input" style="display: none; margin-bottom: 20px;">
78
+ <label for="marker-icon-url">マーカーのアイコンURL:</label>
79
+ <input type="text" id="marker-icon-url" value="https://unpkg.com/leaflet@1.9.3/dist/images/marker-icon-2x.png">
80
+ <button id="load-icon-url">画像を編集</button>
81
+ </div>
82
+ <img id="icon-preview" src="" alt="アイコンプレビュー">
83
+ <div id="icon-settings">
84
+ <label for="icon-width">アイコンの幅:</label>
85
+ <input type="range" id="icon-width" min="10" max="100" value="25">
86
+ <span id="icon-width-value">25</span>px
87
+ <label for="icon-height">アイコンの高さ:</label>
88
+ <input type="range" id="icon-height" min="10" max="100" value="41">
89
+ <span id="icon-height-value">41</span>px
90
+ </div>
91
+ <label for="marker-popup">ポップアップHTML:</label>
92
+ <textarea id="marker-popup" rows="4"></textarea>
93
+ <label for="marker-tooltip">ツールチップHTML:</label>
94
+ <textarea id="marker-tooltip" rows="4"></textarea>
95
+ <button id="save-marker" style="font-family: inherit; font-weight: 800; font-style: normal;">OK</button>
96
+ </div>
97
+ <textarea id="output-html" rows="20" cols="100" readonly hidden></textarea><div id="output-code" style="word-break: break-all;">ここに生成されたHTMLが表示されます。</div><button id="copyButton" style="font-family: inherit; font-weight: 700; font-style: normal;">コードをコピー</button><br>
98
+ <button id="generate-html" style="width: 50%; padding: 10px; border: none; background-color: #007bff; color: #fff; font-size: 16px; border-radius: 4px; cursor: pointer; margin: 20px; font-family: inherit; font-weight: 800; font-style: normal;">HTMLを生成</button>
99
+ <!-- HTML入力エリアの追加 -->
100
+
101
+
102
+ <script>
103
+ const output = document.getElementById('output-code');
104
+ output.innerHTML = hljs.highlight('html', "ここに生成されたHTMLが表示されます。").value;
105
+ output.classList.add('hljs');</script>
106
+ <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
107
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/mono-blue.min.css">
108
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>
109
+
110
+ <script>
111
+ window.onload = function() {
112
+ const loading = document.getElementById('loading');
113
+ loading.style.opacity = '0';
114
+ setTimeout(() => {
115
+ loading.style.display = 'none';
116
+ loadMapFromStorage(); // ストレージからマップを読み込む
117
+ }, 500);
118
+ };
119
+ </script>
120
+
121
+
122
+ <script>
123
+
124
+ function saveMapToStorage() {
125
+ const markers = [];
126
+ map.eachLayer((layer) => {
127
+ if (layer instanceof L.Marker) {
128
+ const marker = layer;
129
+ const icon = marker.options.icon;
130
+ const { lat, lng } = marker.getLatLng();
131
+ markers.push({
132
+ lat: lat,
133
+ lng: lng,
134
+ iconUrl: icon.options.iconUrl,
135
+ iconSize: icon.options.iconSize,
136
+ popupContent: marker.getPopup() ? marker.getPopup().getContent() : '',
137
+ tooltipContent: marker.getTooltip() ? marker.getTooltip().getContent() : '',
138
+ });
139
+ }
140
+ });
141
+ localStorage.setItem('leafletMap', JSON.stringify(markers));
142
+ }
143
+
144
+ function loadMapFromStorage() {
145
+ const storedMarkers = JSON.parse(localStorage.getItem('leafletMap'));
146
+ if (!storedMarkers) {
147
+ console.warn('No markers found in local storage.');
148
+ return;
149
+ }
150
+
151
+ if (!map) {
152
+ console.error('Map is not initialized.');
153
+ return;
154
+ }
155
+
156
+ storedMarkers.forEach((data) => {
157
+ if (!data.iconUrl || !data.iconSize) {
158
+ console.error('Icon data is incomplete.');
159
+ return;
160
+ }
161
+
162
+ const icon = L.icon({
163
+ iconUrl: data.iconUrl,
164
+ iconSize: data.iconSize,
165
+ iconAnchor: [data.iconSize[0] / 2, data.iconSize[1]],
166
+ popupAnchor: [0, -data.iconSize[1]],
167
+ tooltipAnchor: [data.iconSize[0] / 2, -data.iconSize[1] / 2],
168
+ });
169
+ const marker = L.marker([data.lat, data.lng], { icon: icon }).addTo(map);
170
+ if (data.popupContent) marker.bindPopup(data.popupContent);
171
+ if (data.tooltipContent) marker.bindTooltip(data.tooltipContent);
172
+ });
173
+ }
174
+
175
+ function updatePreviewSize() {
176
+ var e = document.getElementById("icon-width").value;
177
+ var t = document.getElementById("icon-height").value;
178
+ var n = document.getElementById("icon-preview");
179
+ n.style.width = e + "px";
180
+ n.style.height = t + "px";
181
+ document.getElementById("icon-width-value").textContent = e;
182
+ document.getElementById("icon-height-value").textContent = t;
183
+ if (editingMarker) {
184
+ var o = document.querySelector('input[name="icon-source"]:checked').value === "url" ? document.getElementById("marker-icon-url").value : n.src;
185
+ var i = L.icon({
186
+ iconUrl: o,
187
+ iconSize: [e, t],
188
+ iconAnchor: [e / 2, t],
189
+ popupAnchor: [0, -t],
190
+ tooltipAnchor: [e / 2, -t / 2]
191
+ });
192
+ editingMarker.setIcon(i);
193
+ saveMapToStorage();
194
+ }
195
+ }
196
+
197
+ function openEditor(e) {
198
+ const t = e.getLatLng();
199
+ document.getElementById("marker-lat").value = t.lat;
200
+ document.getElementById("marker-lng").value = t.lng;
201
+ document.getElementById("marker-popup").value = e.getPopup() ? e.getPopup().getContent() : "";
202
+ document.getElementById("marker-tooltip").value = e.getTooltip() ? e.getTooltip().getContent() : "";
203
+ document.getElementById("marker-editor").style.display = "block";
204
+ editingMarker = e;
205
+ updatePreviewSize();
206
+ }
207
+
208
+ function generateMapHTML() {
209
+ const e = [];
210
+ map.eachLayer((function(t) {
211
+ if (t instanceof L.Marker) {
212
+ const n = t;
213
+ const o = n.options.icon;
214
+ const i = o.options.iconUrl;
215
+ const r = o.options.iconSize;
216
+ const c = n.getLatLng();
217
+ const l = n.getPopup() ? n.getPopup().getContent() : "";
218
+ const a = n.getTooltip() ? n.getTooltip().getContent() : "";
219
+ e.push({
220
+ lat: c.lat,
221
+ lng: c.lng,
222
+ iconUrl: i,
223
+ iconWidth: r[0],
224
+ iconHeight: r[1],
225
+ popupContent: l,
226
+ tooltipContent: a
227
+ });
228
+ }
229
+ }));
230
+ const t = map.getCenter();
231
+ const n = map.getZoom();
232
+ const o = `
233
+ <div id="map" style="height: 600px; width: 100%;"></div>
234
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" />
235
+ <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"><\/script>
236
+ <script>
237
+ var map = L.map('map').setView([${t.lat}, ${t.lng}], ${n});
238
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
239
+ attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
240
+ }).addTo(map);
241
+
242
+ ${e.map(e => `
243
+ var icon = L.icon({
244
+ iconUrl: '${e.iconUrl}',
245
+ iconSize: [${e.iconWidth}, ${e.iconHeight}],
246
+ iconAnchor: [${e.iconWidth} / 2, ${e.iconHeight}],
247
+ popupAnchor: [0, -${e.iconHeight}],
248
+ tooltipAnchor: [${e.iconWidth} / 2, -${e.iconHeight} / 2]
249
+ });
250
+
251
+ var marker = L.marker([${e.lat}, ${e.lng}], {
252
+ icon: icon,
253
+ zIndexOffset: 1000
254
+ }).addTo(map);
255
+
256
+ ${e.popupContent ? `marker.bindPopup('${e.popupContent.replace(/'/g, "\\'").replace(/<\/script>/g, "<\\/script>")}');` : ""}
257
+ ${e.tooltipContent ? `marker.bindTooltip('${e.tooltipContent.replace(/'/g, "\\'").replace(/<\/script>/g, "<\\/script>")}');` : ""}
258
+ `).join("\n")}
259
+ <\/script>
260
+ `;
261
+ document.getElementById("output-html").value = o;
262
+ const input = document.getElementById('output-html').value;
263
+ const output = document.getElementById('output-code');
264
+ output.innerHTML = hljs.highlight('html', input).value;
265
+ output.classList.add('hljs');
266
+ }
267
+
268
+ function resizeImage(e, t, n, o) {
269
+ const i = new FileReader();
270
+ i.onload = function(e) {
271
+ const i = new Image();
272
+ i.onload = function() {
273
+ const e = document.createElement("canvas");
274
+ e.width = t;
275
+ e.height = n;
276
+ e.getContext("2d").drawImage(i, 0, 0, t, n);
277
+ o(e.toDataURL());
278
+ };
279
+ i.src = e.target.result;
280
+ };
281
+ i.readAsDataURL(e);
282
+ }
283
+
284
+ document.getElementById("marker-icon-upload").addEventListener("change", function() {
285
+ const e = this.files[0];
286
+ const t = document.getElementById("icon-preview");
287
+ if (e) {
288
+ resizeImage(e, parseInt(document.getElementById("icon-width").value), parseInt(document.getElementById("icon-height").value), function(imageDataUrl) {
289
+ t.src = imageDataUrl;
290
+ t.style.display = "block";
291
+ document.getElementById("icon-settings").style.display = "block"; // 高さと幅の設定を表示
292
+ updatePreviewSize();
293
+ });
294
+ } else {
295
+ t.style.display = "none";
296
+ document.getElementById("icon-settings").style.display = "none"; // アップロードされていない場合は非表示
297
+ }
298
+ });
299
+
300
+
301
+ document.getElementById("load-icon-url").addEventListener("click", function() {
302
+ const e = document.getElementById("marker-icon-url").value;
303
+ const t = document.getElementById("icon-preview");
304
+ if (e) {
305
+ t.src = e;
306
+ t.onload = function() {
307
+ t.style.display = "block";
308
+ document.getElementById("icon-settings").style.display = "block";
309
+ updatePreviewSize();
310
+ };
311
+ t.onerror = function() {
312
+ alert("画像の読み込みに失敗しました。URLを確認してください。");
313
+ t.style.display = "none";
314
+ document.getElementById("icon-settings").style.display = "none";
315
+ };
316
+ } else {
317
+ t.style.display = "none";
318
+ document.getElementById("icon-settings").style.display = "none";
319
+ }
320
+ });
321
+
322
+ document.getElementById("icon-width").addEventListener("input", updatePreviewSize);
323
+ document.getElementById("icon-height").addEventListener("input", updatePreviewSize);
324
+
325
+ const map = L.map("map").setView([33.321797711641395, 130.52061378343208], 16);
326
+ L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(map);
327
+
328
+ let editingMarker = null;
329
+ let hoveredMarker = null;
330
+
331
+ map.on("click", function(e) {
332
+ if (editingMarker) {
333
+ const t = e.latlng;
334
+ editingMarker.setLatLng([t.lat, t.lng]);
335
+ document.getElementById("marker-lat").value = t.lat;
336
+ document.getElementById("marker-lng").value = t.lng;
337
+ updatePreviewSize();
338
+ saveMapToStorage();
339
+ } else {
340
+ const t = e.latlng;
341
+ const n = L.marker(t).addTo(map);
342
+ n.bindPopup("新しいマーカー");
343
+ n.bindTooltip("新しいマーカーのツールチップ");
344
+ n.on("mouseover", function() {
345
+ hoveredMarker = n;
346
+ console.log("Marker hovered:", n);
347
+ });
348
+ n.on("mouseout", function() {
349
+ hoveredMarker === n && (hoveredMarker = null, console.log("Marker no longer hovered"));
350
+ });
351
+ openEditor(n);
352
+ }
353
+ });
354
+
355
+ document.querySelectorAll('input[name="icon-source"]').forEach(function(e) {
356
+ e.addEventListener("change", function() {
357
+ const value = this.value;
358
+ if (value === "url") {
359
+ document.getElementById("icon-url-input").style.display = "block";
360
+ document.getElementById("icon-upload-input").style.display = "none";
361
+ } else {
362
+ document.getElementById("icon-url-input").style.display = "none";
363
+ document.getElementById("icon-upload-input").style.display = "block";
364
+ }
365
+ updatePreviewSize();
366
+ });
367
+ });
368
+
369
+ document.getElementById("save-marker").addEventListener("click", function() {
370
+ if (editingMarker) {
371
+ const lat = parseFloat(document.getElementById("marker-lat").value);
372
+ const lng = parseFloat(document.getElementById("marker-lng").value);
373
+ const popupContent = document.getElementById("marker-popup").value;
374
+ const tooltipContent = document.getElementById("marker-tooltip").value;
375
+
376
+ const iconSource = document.querySelector('input[name="icon-source"]:checked').value;
377
+ let iconUrl = "";
378
+
379
+ if (iconSource === "url") {
380
+ iconUrl = document.getElementById("marker-icon-url").value;
381
+ } else if (iconSource === "upload") {
382
+ const file = document.getElementById("marker-icon-upload").files[0];
383
+ if (file) {
384
+ // Blob URLからData URLに変換する処理
385
+ resizeImage(file, parseInt(document.getElementById("icon-width").value), parseInt(document.getElementById("icon-height").value), function(dataUrl) {
386
+ iconUrl = dataUrl;
387
+ applyIconAndSaveMarker(lat, lng, popupContent, tooltipContent, iconUrl);
388
+ });
389
+ saveMapToStorage();
390
+ return; // 非同期処理が完了するまで待つためここでリターン
391
+ }
392
+ }
393
+
394
+ // URLの場合や、アップロードファイルがない場合の処理
395
+ applyIconAndSaveMarker(lat, lng, popupContent, tooltipContent, iconUrl);
396
+ }
397
+ });
398
+
399
+ function applyIconAndSaveMarker(lat, lng, popupContent, tooltipContent, iconUrl) {
400
+ const iconWidth = parseInt(document.getElementById("icon-width").value);
401
+ const iconHeight = parseInt(document.getElementById("icon-height").value);
402
+
403
+ editingMarker.setLatLng([lat, lng]);
404
+ if (iconUrl) {
405
+ const icon = L.icon({
406
+ iconUrl: iconUrl,
407
+ iconSize: [iconWidth, iconHeight],
408
+ iconAnchor: [iconWidth / 2, iconHeight],
409
+ popupAnchor: [0, -iconHeight],
410
+ tooltipAnchor: [iconWidth / 2, -iconHeight / 2]
411
+ });
412
+ editingMarker.setIcon(icon);
413
+ }
414
+
415
+ editingMarker.bindPopup(popupContent);
416
+ editingMarker.bindTooltip(tooltipContent);
417
+
418
+ document.getElementById("marker-editor").style.display = "none";
419
+ editingMarker = null;
420
+ saveMapToStorage();
421
+ }
422
+
423
+
424
+ document.addEventListener("keydown", function(e) {
425
+ if (e.key === "e" && hoveredMarker) {
426
+ openEditor(hoveredMarker);
427
+ }
428
+ });
429
+
430
+ (function() {
431
+ const e = document.getElementById("marker-editor");
432
+ let t, n, o = false;
433
+ e.addEventListener("mousedown", function(i) {
434
+ if (!i.target.closest("input, textarea, button")) {
435
+ t = i.clientX - e.getBoundingClientRect().left;
436
+ n = i.clientY - e.getBoundingClientRect().top;
437
+ o = true;
438
+ }
439
+ });
440
+ document.addEventListener("mousemove", function(i) {
441
+ if (o) {
442
+ e.style.left = i.clientX - t + "px";
443
+ e.style.top = i.clientY - n + "px";
444
+ }
445
+ });
446
+ document.addEventListener("mouseup", function() {
447
+ o = false;
448
+ });
449
+ })();
450
+ document.getElementById("copyButton").onclick = function() {
451
+ const textToCopy = document.getElementById("output-code").innerText;
452
+ navigator.clipboard.writeText(textToCopy).then(() => {
453
+ alert("テキストがコピーされました!");
454
+ }).catch(err => {
455
+ console.error('コピーに失敗しました:', err);
456
+ });
457
+ };
458
+
459
+ document.getElementById("generate-html").addEventListener("click", generateMapHTML);
460
+
461
+ // マーカー追加時
462
+ map.on("click", function(e) {
463
+ if (editingMarker) {
464
+ const t = e.latlng;
465
+ editingMarker.setLatLng([t.lat, t.lng]);
466
+ document.getElementById("marker-lat").value = t.lat;
467
+ document.getElementById("marker-lng").value = t.lng;
468
+ updatePreviewSize();
469
+ saveMapToStorage(); // 編集後に保存
470
+ } else {
471
+ const t = e.latlng;
472
+ const n = L.marker(t).addTo(map);
473
+ n.bindPopup("新しいマーカー");
474
+ n.bindTooltip("新しいマーカーのツールチップ");
475
+ n.on("mouseover", function() {
476
+ hoveredMarker = n;
477
+ });
478
+ n.on("mouseout", function() {
479
+ hoveredMarker === n && (hoveredMarker = null);
480
+ });
481
+ openEditor(n);
482
+ saveMapToStorage(); // 新しいマーカー追加後に保存
483
+ }
484
+ });
485
+
486
+ // マーカー移動時にも保存
487
+ map.on("markerdragend", function(e) {
488
+ saveMapToStorage(); // マーカー移動後に保存
489
+ });
490
+
491
+ map.on("contextmenu", function (e) {
492
+ const clickedMarkers = [];
493
+
494
+ // クリックされた位置と既存のマーカーの距離を計算
495
+ map.eachLayer(function (layer) {
496
+ if (layer instanceof L.Marker) {
497
+ const distance = map.distance(e.latlng, layer.getLatLng());
498
+ if (distance < 20) { // 近い距離(ピクセル相当の距離)内のマーカーを検出
499
+ clickedMarkers.push(layer);
500
+ }
501
+ }
502
+ });
503
+
504
+ // クリックされたマーカーがあれば、最初の1つに対して編集を開く
505
+ if (clickedMarkers.length > 0) {
506
+ openEditor(clickedMarkers[0]);
507
+ }
508
+ });
509
+
510
+ // マップが動いたときに保存
511
+ </script>
512
+ </body>
513
+ </html>