Skip to content

Commit c46d0c0

Browse files
author
interactive-game-maps
committed
Init
0 parents  commit c46d0c0

File tree

9 files changed

+482
-0
lines changed

9 files changed

+482
-0
lines changed

images/collectibles/example.png

6.44 KB
Loading

images/icons/information.png

7.42 KB
Loading

index.html

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Interactive map of Template</title>
6+
7+
<meta charset="utf-8" />
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
10+
<!-- Leaflet's CSS -->
11+
<link rel="stylesheet" href="https://unpkg.com/leaflet@latest/dist/leaflet.css" crossorigin="" />
12+
13+
<!-- Make sure you put this AFTER Leaflet's CSS -->
14+
<script src="https://unpkg.com/leaflet@latest/dist/leaflet.js" crossorigin=""></script>
15+
16+
<!-- Grouping markers to cluster -->
17+
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@latest/dist/MarkerCluster.css" crossorigin="" />
18+
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@latest/dist/MarkerCluster.Default.css"
19+
crossorigin="" />
20+
<script src="https://unpkg.com/leaflet.markercluster@latest/dist/leaflet.markercluster.js" crossorigin=""></script>
21+
22+
<!-- Nested marker cluster -->
23+
<script src="https://unpkg.com/leaflet.featuregroup.subgroup@latest/dist/leaflet.featuregroup.subgroup.js"></script>
24+
25+
<!-- Additional icons -->
26+
<link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/fontawesome.min.css" rel="stylesheet"
27+
crossorigin="" />
28+
<link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/solid.min.css" rel="stylesheet"
29+
crossorigin="" />
30+
<link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/brands.min.css" rel="stylesheet"
31+
crossorigin="" />
32+
33+
<!-- Sidebar -->
34+
<link rel="stylesheet" href="https://unpkg.com/leaflet-sidebar-v2@latest/css/leaflet-sidebar.css" crossorigin="" />
35+
<script src="https://unpkg.com/leaflet-sidebar-v2@latest/js/leaflet-sidebar.min.js" crossorigin=""></script>
36+
37+
<!-- Marker editor -->
38+
<link rel="stylesheet" href="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.css"
39+
crossorigin="" />
40+
<script src="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.min.js"
41+
crossorigin=""></script>
42+
43+
<link rel="stylesheet" href="common/style.css" />
44+
</head>
45+
46+
<body>
47+
<div id="map"></div>
48+
49+
<!-- include classes -->
50+
<script src="common/custom_layers.js" type="text/javascript"></script>
51+
<script src="common/interactive_layer.js" type="text/javascript"></script>
52+
<script src="common/interactive_map.js" type="text/javascript"></script>
53+
<script src="common/share_marker.js" type="text/javascript"></script>
54+
<script src="common/utils.js" type="text/javascript"></script>
55+
56+
<!-- include features from file -->
57+
<script src="marker/collectibles.js" type="text/javascript"></script>
58+
<script src="marker/information.js" type="text/javascript"></script>
59+
60+
<!-- include layer logic -->
61+
<script src="marker_logic/collectibles.js" type="text/javascript"></script>
62+
<script src="marker_logic/information.js" type="text/javascript"></script>
63+
64+
<!-- include map specific stuff -->
65+
<script src="map_utils.js" type="text/javascript"></script>
66+
<script src="map.js" type="text/javascript"></script>
67+
</body>
68+
69+
</html>

map.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Step 0:
2+
// Add all feature geoJSON and layer logic to the `index.html`
3+
// In this example this is:
4+
// * `marker/collectibles.js`
5+
// * `marker/information.js`
6+
// * `marker_logic/collectibles.js`
7+
// * `marker_logic/information.js`
8+
9+
// Step 1:
10+
// Initialize the map with basic information
11+
var interactive_map = new InteractiveMap('map', {
12+
max_good_zoom: 6,
13+
max_map_zoom: 8,
14+
website_source: 'https://github.com/interactive-game-maps/template',
15+
website_subdir: 'template',
16+
attribution: `
17+
<li><a href="https://www.example.com/index.html">$Thing</a> used by <a href="https://www.example.com/index.html">$person</a> under <a href="https://www.example.com/index.html">$license</a></li>
18+
<li>This project uses sample images from <a href="https://picsum.photos/>picsum.photos</a></li>
19+
`
20+
});
21+
22+
// Step 2:
23+
// Add at least one tile layer
24+
//
25+
// generate them from an image with (don't forget do adjust the zoom levels `-z`):
26+
// https://github.com/commenthol/gdal2tiles-leaflet
27+
// `./gdal2tiles.py -l -p raster -w none -z 3-5 full_map.jpg map_tiles`
28+
interactive_map.addTileLayer('Ingame map', {
29+
minNativeZoom: 2,
30+
maxNativeZoom: 4,
31+
attribution: 'Map from <a href="https://www.example.com/index.html">$source</a>'
32+
});
33+
34+
// Step 2.5 (optional):
35+
// Add more tile layer
36+
// interactive_map.addTileLayer('Overview', {
37+
// minNativeZoom: 2,
38+
// maxNativeZoom: 4,
39+
// attribution: 'Map from <a href="https://www.example.com/index.html">$source</a>'
40+
// }, 'overview_tiles/{z}/{x}/{y}.png');
41+
42+
// Step 3:
43+
// Add at least one marker layer
44+
// The order matters - they will appear in this order in the sidebar and layer control
45+
// See `marker_logic/collectibles.js` for a really basic layer
46+
addCollectibles(interactive_map);
47+
48+
// Step 3.5 (optional):
49+
// Add more marker layer
50+
// See `marker_logic/information.js` for more advanced technics
51+
addInformation(interactive_map);
52+
53+
// Step 4:
54+
// Finalize the map after adding all layers.
55+
interactive_map.finalize();
56+
57+
// Step 5:
58+
// Open `index.html` to view the map.
59+
// You can now add additional layers by clicking the edit button in the lower left
60+
// While editing a layer you can export the geoJSON in the toolbar on the right when you're done
61+
// and add them here to step 3 to display them fixed for all users.

map_utils.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Return html with the media to display
2+
// Add media that should be included into the popup to a new `html` and return the `html` afterwards
3+
// This is just basic html stuff from within JavaScript
4+
5+
function getPopupMedia(feature, layer_id) {
6+
7+
// Create top element to insert to
8+
var html = document.createElement('div');
9+
10+
// Some logical distinction between information our geoJSON provides
11+
// Do the following for geoJSON features that have an `image_id` property
12+
if (feature.properties.image_id) {
13+
14+
// Create a new element - `a` will be a clickable link
15+
var image_link = document.createElement('a');
16+
17+
// Add a destination to our link
18+
image_link.href = `images/${layer_id}/${feature.properties.image_id}.png`;
19+
20+
// Create a new element - `img` will be an image
21+
var image = document.createElement('img');
22+
23+
// Add a class to our image. `popup-media` will get a size change listener to readjust
24+
// the popup location
25+
image.className = 'popup-media';
26+
27+
// Add the image that should be displayed to the image element
28+
image.src = image_link.href;
29+
30+
// Add the image inside the image link so clicking on the image will open the image in big
31+
image_link.appendChild(image);
32+
33+
// Add the image link with the included image to our top html element
34+
html.appendChild(image_link);
35+
36+
// Do the following for geoJSON features hat have an `external_id` property
37+
} else if (feature.properties.external_id) {
38+
39+
// Create a new element - `a` will be a clickable link
40+
var image_link = document.createElement('a');
41+
42+
// Add a destination to our link
43+
image_link.href = `https://www.example.com/collectibles${feature.properties.image_link}`;
44+
45+
// Create a new element - `img` will be an image
46+
var image = document.createElement('img');
47+
48+
// Add a class to our image. `popup-media` will get a size change listener to readjust
49+
// the popup location
50+
image.className = 'popup-media';
51+
52+
// Add the image that should be displayed to the image element
53+
image.src = `https://picsum.photos/${feature.properties.external_id}`;
54+
55+
// Add the image inside the image link so clicking on the image will open the image in big
56+
image_link.appendChild(image);
57+
58+
// Add the image link with the included image to the top html element
59+
html.appendChild(image_link);
60+
61+
// Do the following for geoJSON features hat have an `video_id` property
62+
} else if (feature.properties.video_id) {
63+
64+
// Videos can't resize properly yet so we have to do hardcode them in for now
65+
const POPUP_WIDTH_16_9 = Math.min(500, window.screen.availWidth - 100, (window.screen.availHeight - 200) * 16 / 9);
66+
const POPUP_WIDTH_4_3 = Math.min(500, window.screen.availWidth - 100, (window.screen.availHeight - 200) * 4 / 3);
67+
68+
// YouTube videos need an `iframe` element
69+
var video = document.createElement('iframe');
70+
71+
// Add the `popup-media` class anyway
72+
video.className = 'popup-media';
73+
74+
// Set a fixed width and height for the video
75+
video.width = POPUP_WIDTH_16_9;
76+
video.height = POPUP_WIDTH_16_9 / 16 * 9;
77+
78+
// The source of the iframe
79+
video.src = `https://www.youtube-nocookie.com/embed/${feature.properties.video_id}`;
80+
81+
// Add the video to the top html element
82+
html.appendChild(video);
83+
}
84+
85+
// At last return the created html element
86+
return html;
87+
}

marker/collectibles.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
var collectibles = {
2+
"type": "FeatureCollection",
3+
"features": [
4+
{
5+
"type": "Feature",
6+
"properties": {
7+
"id": "1",
8+
"image_id": "example"
9+
},
10+
"geometry": {
11+
"type": "Point",
12+
"coordinates": [
13+
0,
14+
0
15+
]
16+
}
17+
},
18+
{
19+
"type": "Feature",
20+
"properties": {
21+
"id": "2",
22+
"external_id": "/1920/1080",
23+
"image_link": "#dsa",
24+
"description": "Go there and do that"
25+
},
26+
"geometry": {
27+
"type": "Point",
28+
"coordinates": [
29+
1,
30+
0
31+
]
32+
}
33+
}
34+
]
35+
};

marker/information.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
var information = {
2+
"type": "FeatureCollection",
3+
"features": [
4+
{
5+
"type": "Feature",
6+
"properties": {
7+
"id": "1",
8+
"name": "Information 1",
9+
"external_id": "/1920/1080"
10+
},
11+
"geometry": {
12+
"type": "Polygon",
13+
"coordinates": [[
14+
[0, -1],
15+
[1, -1],
16+
[1, -2],
17+
[0, -2]
18+
]]
19+
}
20+
},
21+
{
22+
"type": "Feature",
23+
"properties": {
24+
"id": "1",
25+
"external_id": "/1920/1080"
26+
},
27+
"geometry": {
28+
"type": "Point",
29+
"coordinates": [
30+
0.5,
31+
-1.5
32+
]
33+
}
34+
},
35+
{
36+
"type": "Feature",
37+
"properties": {
38+
"id": "Dangerous areas",
39+
"name": "Dangerous area 1",
40+
"external_id": "/1920/1080"
41+
},
42+
"geometry": {
43+
"type": "Polygon",
44+
"coordinates": [[
45+
[0, -3],
46+
[1, -3],
47+
[1, -4],
48+
[0, -4]
49+
]]
50+
}
51+
},
52+
{
53+
"type": "Feature",
54+
"properties": {
55+
"id": "Dangerous areas",
56+
"name": "Dangerous area 2",
57+
"video_id": "abcdef"
58+
},
59+
"geometry": {
60+
"type": "Polygon",
61+
"coordinates": [[
62+
[0, -5],
63+
[1, -5],
64+
[1, -6],
65+
[0, -6]
66+
]]
67+
}
68+
},
69+
{
70+
"type": "Feature",
71+
"properties": {
72+
"id": "Important waypoint 1",
73+
"external_id": "/1920/1080"
74+
},
75+
"geometry": {
76+
"type": "Point",
77+
"coordinates": [
78+
2,
79+
0
80+
]
81+
}
82+
}
83+
]
84+
};

marker_logic/collectibles.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Simple
2+
// Just a simple group of collectibles, trackable in the sidebar
3+
4+
function addCollectibles(map) {
5+
6+
// New layer with id `collectibles` from geoJSON `collectibles`
7+
map.addInteractiveLayer('collectibles', collectibles, {
8+
9+
// The display name for this layer
10+
name: 'Collectibles',
11+
12+
// This layer should have a tab in the sidebar with a list for each feature ID
13+
create_checkbox: true,
14+
15+
// Each feature should have a popup
16+
// This internally calls `getPopupMedia()` to associate an image or video
17+
// See `map_utils.js` for an example
18+
create_feature_popup: true,
19+
20+
// This layer should be visible by default
21+
is_default: true,
22+
23+
// We don't have created a custom icon so let's use a generic one from Font Awesome
24+
// Omitting this uses the group icon in `images/icons/${this.id}.png` by default
25+
// This needs a html string or a function that return a html string
26+
sidebar_icon_html: '<i class="fas fa-gem"></i>',
27+
28+
// We don't have created a custom icon so we have to manually provide a marker
29+
// Omitting this sets a marker with the group icon in `images/icons/${this.id}.png` by default
30+
// This can include logic based on feature properties
31+
// https://leafletjs.com/reference.html#geojson-pointtolayer
32+
pointToLayer: function (feature, latlng) {
33+
34+
// https://leafletjs.com/reference.html#marker
35+
return L.marker(latlng, {
36+
37+
// We don't have created a custom icon so let's use a generic one from Font Awesome
38+
// This can take:
39+
// * a Font Awesome `fa-` string
40+
// * the group id (`this.id`) to take the `images/icons/${this.id}.png`
41+
// * a max 2 char long string
42+
// * nothing for a generic marker
43+
icon: Utils.getCustomIcon('fa-gem'),
44+
riseOnHover: true
45+
});
46+
}
47+
});
48+
}

0 commit comments

Comments
 (0)