Skip to content

Commit 8005992

Browse files
committed
Add photo details on selecting
1 parent 0457284 commit 8005992

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed

src/map.html

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,74 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Photos map</title>
77
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/ol.css">
8-
<style>html, body, .map {
9-
padding: 0;
10-
margin: 0;
11-
width: 100%;
12-
height: 100%;
13-
}</style>
8+
<style>
9+
html, body {
10+
padding: 0;
11+
margin: 0;
12+
width: 100%;
13+
height: 100%;
14+
}
15+
body {
16+
display: grid;
17+
grid-template-columns: 3fr 1fr;
18+
}
19+
.map {
20+
min-width: 75%;
21+
height: 100%;
22+
background-color: #b5d0d0;
23+
}
24+
25+
@media (max-width: 768px) {
26+
body {
27+
grid-template-columns: 1fr;
28+
grid-template-rows: auto auto;
29+
}
30+
}
31+
32+
#photo-details {
33+
overflow: auto;
34+
}
35+
.photo-details-container {
36+
max-width: 100%;
37+
display: grid;
38+
grid-template-columns: auto 1fr;
39+
gap: 0.6rem;
40+
align-items: start;
41+
}
42+
.photo-thumbnail {
43+
max-width: 150px;
44+
max-height: 150px;
45+
object-fit: cover;
46+
}
47+
.photo-details-content {
48+
display: flex;
49+
flex-direction: column;
50+
}
51+
.photo-details-content h3 {
52+
margin: 0;
53+
}
54+
.photo-details-content p {
55+
margin: 0.2rem 0;
56+
}
57+
</style>
1458
</head>
1559
<body>
1660
<div id="map" class="map"></div>
61+
<div id="photo-details"></div>
62+
63+
<script type="text/html" id="photo-template">
64+
<div class="photo-details-container">
65+
<a href="{path}" target="_blank" title="Click to open photo in new tab">
66+
<img src="{preview}" class="photo-thumbnail">
67+
</a>
68+
<div class="photo-details-content">
69+
<h3>{name}</h3>
70+
<p><b>Camera:</b> {make} {model}</p>
71+
<p><b>Date:</b> {date}</p>
72+
</div>
73+
</div>
74+
</script>
75+
1776
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ol.js"></script>
1877
<script src="map.js"></script>
1978
</body>

src/map.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
const photosSource = new ol.source.Vector();
22

3+
// Configure map layers: bottom - OpenStreetMap map, top - photo thumbnails
34
const layerOSM = new ol.layer.Tile({
45
source: new ol.source.OSM()
56
});
67
const layerThumbs = new ol.layer.Vector({
78
source: photosSource,
89
style: thumbStyle,
10+
updateWhileAnimating: true,
11+
updateWhileInteracting: true,
912
});
1013
const map = new ol.Map({
1114
target: 'map',
@@ -16,6 +19,23 @@ const map = new ol.Map({
1619
})
1720
});
1821

22+
// Configure thumbnail selector
23+
const thumbSelector = new ol.interaction.Select({
24+
layers: [layerThumbs],
25+
style: selectedStyle
26+
});
27+
map.addInteraction(thumbSelector);
28+
29+
const selectedFeatures = thumbSelector.getFeatures();
30+
selectedFeatures.on('add', event => {
31+
const feature = event.target.item(0);
32+
const details = photoDetails(feature);
33+
document.getElementById('photo-details').innerHTML = details;
34+
});
35+
selectedFeatures.on('remove', () => {
36+
document.getElementById('photo-details').innerHTML = '';
37+
});
38+
1939
const handleMapDataLoaded = items => {
2040
const transform = ol.proj.getTransform('EPSG:4326', 'EPSG:3857');
2141
items.forEach(item => {
@@ -27,11 +47,27 @@ const handleMapDataLoaded = items => {
2747
});
2848
};
2949
handleMapDataLoaded([{
50+
"name": "dsc_1337_ps_5996.jpg",
51+
"path": "https://annimon.com/albums/files/dsc_1337_ps_5996.jpg",
3052
"preview": "https://annimon.com/albums/screens/dsc_1337_ps_5996.jpg.250.png",
3153
"lat": 47.765957,
32-
"lon": 37.255646
54+
"lon": 37.255646,
55+
"make": "Sony Ericsson",
56+
"model": "MK16i",
57+
"date": "2017-06-02 19:30:08"
3358
}]);
3459

60+
// -- photo details --
61+
function photoDetails(feature) {
62+
let content = document.getElementById('photo-template').innerHTML;
63+
const keys = ['name', 'preview', 'date', 'lat', 'lon', 'make', 'model', 'path'];
64+
keys.forEach(key => {
65+
const value = feature.get(key);
66+
content = content.replace(`{${key}}`, value);
67+
});
68+
return content;
69+
}
70+
3571
// -- icon styles --
3672
const cache = {};
3773

@@ -50,6 +86,10 @@ function thumbStyle(feature, resolution) {
5086
return [photoStyle(feature, clamp(0.2, 0.1 / resolution, 1))];
5187
}
5288

89+
function selectedStyle(feature, resolution) {
90+
return [photoStyle(feature, clamp(0.4, 0.14 / resolution, 1.2))];
91+
}
92+
5393
function clamp(min, value, max) {
5494
if (value < min) return min;
5595
if (value > max) return max;

0 commit comments

Comments
 (0)