Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
bedb066407 | ||
|
27c7067c04 | ||
|
6ee5254780 | ||
|
8bd7535163 | ||
|
7a1e4232f4 | ||
|
cf2c5c0021 | ||
|
e74e460480 | ||
|
0cb10203c7 | ||
|
a8c0aefbd6 | ||
|
9c18cc19b7 | ||
|
1dc218ca8a | ||
|
bfd9b4fdf6 | ||
|
67707b7ded | ||
|
9c96037e32 | ||
|
fc4c63b519 | ||
|
fe1c9f6300 | ||
|
0d66bc1266 | ||
|
ba3982d9a6 | ||
|
f2cc9a9783 | ||
|
0c1aeebdf7 | ||
|
3324a57206 | ||
|
cf8e6882f8 | ||
|
6c4959deda | ||
|
e00b5576e6 | ||
|
e06b9d5109 | ||
|
b527049acb | ||
|
18ea53313f | ||
|
9e839def7a | ||
|
47f1fce82d |
182553
data/legacy-route.json
Normal file
11
dist/assets/index.7920774d.js
vendored
@ -1 +1 @@
|
|||||||
.ol-box{box-sizing:border-box;border-radius:2px;border:1.5px solid rgb(179,197,219);background-color:#fff6}.ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;transition:all .25s}.ol-scale-singlebar-even{background-color:#000}.ol-scale-singlebar-odd{background-color:#fff}.ol-scale-bar{position:absolute;bottom:8px;left:8px}.ol-scale-step-marker{width:1px;height:15px;background-color:#000;float:right;z-index:10}.ol-scale-step-text{position:absolute;bottom:-5px;font-size:12px;z-index:11;color:#000;text-shadow:-2px 0 #FFFFFF,0 2px #FFFFFF,2px 0 #FFFFFF,0 -2px #FFFFFF}.ol-scale-text{position:absolute;font-size:14px;text-align:center;bottom:25px;color:#000;text-shadow:-2px 0 #FFFFFF,0 2px #FFFFFF,2px 0 #FFFFFF,0 -2px #FFFFFF}.ol-scale-singlebar{position:relative;height:10px;z-index:9;box-sizing:border-box;border:1px solid black}.ol-unsupported{display:none}.ol-viewport,.ol-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ol-viewport canvas{all:unset}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.ol-control{position:absolute;background-color:#fff6;border-radius:4px;padding:2px}.ol-control:hover{background-color:#fff9}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-weight:700;text-decoration:none;font-size:inherit;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:#003c8880;border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:hover,.ol-control button:focus{text-decoration:none;background-color:#003c88b3}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);display:flex;flex-flow:row-reverse;align-items:center}.ol-attribution a{color:#003c88b3;text-decoration:none}.ol-attribution ul{margin:0;padding:1px .5em;color:#000;text-shadow:0 0 2px #fff;font-size:12px}.ol-attribution li{display:inline;list-style:none}.ol-attribution li:not(:last-child):after{content:" "}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle}.ol-attribution button{flex-shrink:0}.ol-attribution.ol-collapsed ul{display:none}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{top:4.5em;left:.5em;height:200px}.ol-zoomslider button{position:relative;height:10px}.ol-touch .ol-zoomslider{top:5.5em}.ol-overviewmap{left:.5em;bottom:.5em}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0}.ol-overviewmap .ol-overviewmap-map,.ol-overviewmap button{display:block}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px}.ol-overviewmap:not(.ol-collapsed) button{bottom:2px;left:2px;position:absolute}.ol-overviewmap.ol-collapsed .ol-overviewmap-map,.ol-overviewmap.ol-uncollapsible button{display:none}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7)}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move}html,body{margin:0;height:100%}#map{position:absolute;top:0;bottom:0;width:100%}
|
.ol-box{box-sizing:border-box;border-radius:2px;border:1.5px solid rgb(179,197,219);background-color:#fff6}.ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;transition:all .25s}.ol-scale-singlebar-even{background-color:#000}.ol-scale-singlebar-odd{background-color:#fff}.ol-scale-bar{position:absolute;bottom:8px;left:8px}.ol-scale-step-marker{width:1px;height:15px;background-color:#000;float:right;z-index:10}.ol-scale-step-text{position:absolute;bottom:-5px;font-size:12px;z-index:11;color:#000;text-shadow:-2px 0 #FFFFFF,0 2px #FFFFFF,2px 0 #FFFFFF,0 -2px #FFFFFF}.ol-scale-text{position:absolute;font-size:14px;text-align:center;bottom:25px;color:#000;text-shadow:-2px 0 #FFFFFF,0 2px #FFFFFF,2px 0 #FFFFFF,0 -2px #FFFFFF}.ol-scale-singlebar{position:relative;height:10px;z-index:9;box-sizing:border-box;border:1px solid black}.ol-unsupported{display:none}.ol-viewport,.ol-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ol-viewport canvas{all:unset}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.ol-control{position:absolute;background-color:#fff6;border-radius:4px;padding:2px}.ol-control:hover{background-color:#fff9}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-weight:700;text-decoration:none;font-size:inherit;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:#003c8880;border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:hover,.ol-control button:focus{text-decoration:none;background-color:#003c88b3}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);display:flex;flex-flow:row-reverse;align-items:center}.ol-attribution a{color:#003c88b3;text-decoration:none}.ol-attribution ul{margin:0;padding:1px .5em;color:#000;text-shadow:0 0 2px #fff;font-size:12px}.ol-attribution li{display:inline;list-style:none}.ol-attribution li:not(:last-child):after{content:" "}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle}.ol-attribution button{flex-shrink:0}.ol-attribution.ol-collapsed ul{display:none}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{top:4.5em;left:.5em;height:200px}.ol-zoomslider button{position:relative;height:10px}.ol-touch .ol-zoomslider{top:5.5em}.ol-overviewmap{left:.5em;bottom:.5em}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0}.ol-overviewmap .ol-overviewmap-map,.ol-overviewmap button{display:block}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px}.ol-overviewmap:not(.ol-collapsed) button{bottom:2px;left:2px;position:absolute}.ol-overviewmap.ol-collapsed .ol-overviewmap-map,.ol-overviewmap.ol-uncollapsible button{display:none}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7)}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move}html,body{margin:0;height:100%}#map{position:absolute;top:0;bottom:0;width:100%}img#logo{position:absolute;top:10px;right:10px;width:256px;height:auto}lightning-widget{display:block;position:absolute;bottom:10px;left:10px;width:200px}@media only screen and (max-width: 600px){lightning-widget{display:block;position:absolute;right:10px;width:auto}}
|
11
dist/assets/index.b6f9bc24.js
vendored
Normal file
0
data/icon.png → dist/img/icon.png
vendored
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
BIN
dist/img/r2b-logo.png
vendored
Normal file
After Width: | Height: | Size: 14 KiB |
0
data/van-100px.png → dist/img/van-100px.png
vendored
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
13
dist/index.html
vendored
@ -6,12 +6,21 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Road2Bitcoin Live Map</title>
|
<title>Road2Bitcoin Live Map</title>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
|
||||||
<script type="module" crossorigin src="/assets/index.7920774d.js"></script>
|
<script defer data-domain="r2b22.kip.pe" src="https://plausible.io/js/plausible.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index.eed9f443.css">
|
<script type="module" crossorigin src="/assets/index.b6f9bc24.js"></script>
|
||||||
|
<link rel="stylesheet" href="/assets/index.a04fc84d.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="map"><div id="popup"></div></div>
|
<div id="map"><div id="popup"></div></div>
|
||||||
|
<div id="people"></div>
|
||||||
|
<a href="https://teamsatoshi.org/wiki/Road2Bitcoin_2022" title="Road2Bitcoin 2022"><img id="logo" src="/img/r2b-logo.png"></a>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<lightning-widget name=""
|
||||||
|
accent="#e01b24"
|
||||||
|
to="team-satoshi@kosmos.org"
|
||||||
|
image="" />
|
||||||
|
<script src="/js/lightning-widget.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
2
dist/js/lightning-widget.js
vendored
Normal file
@ -6,10 +6,19 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Road2Bitcoin Live Map</title>
|
<title>Road2Bitcoin Live Map</title>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
|
||||||
|
<script defer data-domain="r2b22.kip.pe" src="https://plausible.io/js/plausible.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="map"><div id="popup"></div></div>
|
<div id="map"><div id="popup"></div></div>
|
||||||
|
<div id="people"></div>
|
||||||
|
<a href="https://teamsatoshi.org/wiki/Road2Bitcoin_2022" title="Road2Bitcoin 2022"><img id="logo" src="/img/r2b-logo.png"></a>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script type="module" src="./main.js"></script>
|
<script type="module" src="./main.js"></script>
|
||||||
|
|
||||||
|
<lightning-widget name=""
|
||||||
|
accent="#e01b24"
|
||||||
|
to="team-satoshi@kosmos.org"
|
||||||
|
image="" />
|
||||||
|
<script src="/js/lightning-widget.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
142
main.js
@ -8,11 +8,13 @@ import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
|
|||||||
import {Circle as CircleStyle, Fill, Icon, Stroke, Style} from 'ol/style';
|
import {Circle as CircleStyle, Fill, Icon, Stroke, Style} from 'ol/style';
|
||||||
import {OSM, Vector as VectorSource} from 'ol/source';
|
import {OSM, Vector as VectorSource} from 'ol/source';
|
||||||
import {useGeographic} from 'ol/proj';
|
import {useGeographic} from 'ol/proj';
|
||||||
import geojsonRoute from './geo/route.json'
|
import geojsonRoute from './data/r2b22-route.json'
|
||||||
import geojsonPOI from './geo/poi.json'
|
import geojsonPOI from './data/r2b22-poi.json';
|
||||||
|
import geojsonLegacy from './data/legacy-route.json';
|
||||||
|
|
||||||
useGeographic();
|
useGeographic();
|
||||||
|
|
||||||
|
async function main() {
|
||||||
const styles = {
|
const styles = {
|
||||||
lineOrange: new Style({
|
lineOrange: new Style({
|
||||||
stroke: new Stroke({
|
stroke: new Stroke({
|
||||||
@ -33,7 +35,7 @@ const styles = {
|
|||||||
anchor: [0.5, 46],
|
anchor: [0.5, 46],
|
||||||
anchorXUnits: 'fraction',
|
anchorXUnits: 'fraction',
|
||||||
anchorYUnits: 'pixels',
|
anchorYUnits: 'pixels',
|
||||||
src: 'data/icon.png',
|
src: '/img/icon.png',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
iconVan: new Style({
|
iconVan: new Style({
|
||||||
@ -41,7 +43,7 @@ const styles = {
|
|||||||
anchor: [0.5, 16],
|
anchor: [0.5, 16],
|
||||||
anchorXUnits: 'fraction',
|
anchorXUnits: 'fraction',
|
||||||
anchorYUnits: 'pixels',
|
anchorYUnits: 'pixels',
|
||||||
src: 'data/van-100px.png',
|
src: '/img/van-100px.png',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
circleBlack: new Style({
|
circleBlack: new Style({
|
||||||
@ -60,7 +62,9 @@ const styles = {
|
|||||||
// Route
|
// Route
|
||||||
//
|
//
|
||||||
|
|
||||||
const lastStageFinished = 4;
|
const tourStatus = await fetch('https://r2b22.kip.pe/status.json').then(res => res.json());
|
||||||
|
|
||||||
|
const lastStageFinished = tourStatus.lastStageFinished;
|
||||||
const stagesCompleted = geojsonRoute.features.slice(0, lastStageFinished);
|
const stagesCompleted = geojsonRoute.features.slice(0, lastStageFinished);
|
||||||
const stagesAhead = geojsonRoute.features.slice(lastStageFinished);
|
const stagesAhead = geojsonRoute.features.slice(lastStageFinished);
|
||||||
const vectorSourceStagesCompleted = new VectorSource();
|
const vectorSourceStagesCompleted = new VectorSource();
|
||||||
@ -96,20 +100,32 @@ const poiLayer = new VectorLayer({
|
|||||||
style: styles.circleBlack,
|
style: styles.circleBlack,
|
||||||
});
|
});
|
||||||
|
|
||||||
const vectorSourceVan = new VectorSource();
|
const vectorSourceTrackedPoints = new VectorSource();
|
||||||
|
|
||||||
const vanFeature= new Feature({
|
const vanFeature= new Feature({
|
||||||
geometry: new Point([ 12.498556, 45.780383 ]),
|
geometry: new Point([8.918618, 44.407408]),
|
||||||
name: 'Support Van'
|
name: 'Support Van'
|
||||||
});
|
});
|
||||||
|
|
||||||
vectorSourceVan.addFeature(vanFeature);
|
vectorSourceTrackedPoints.addFeature(vanFeature);
|
||||||
|
|
||||||
const vanLayer = new VectorLayer({
|
const trackedPointsLayer = new VectorLayer({
|
||||||
source: vectorSourceVan,
|
source: vectorSourceTrackedPoints,
|
||||||
style: styles.iconVan
|
style: styles.iconVan
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Legacy routes
|
||||||
|
//
|
||||||
|
|
||||||
|
const vectorSourceLegacy = new VectorSource();
|
||||||
|
vectorSourceLegacy.addFeatures(new GeoJSON().readFeatures(geojsonLegacy));
|
||||||
|
|
||||||
|
const legacyLayer = new VectorLayer({
|
||||||
|
source: vectorSourceLegacy,
|
||||||
|
style: styles.lineOrange
|
||||||
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
// Map initialization
|
// Map initialization
|
||||||
//
|
//
|
||||||
@ -119,6 +135,8 @@ const view = new View({
|
|||||||
zoom: 6.6
|
zoom: 6.6
|
||||||
})
|
})
|
||||||
|
|
||||||
|
window.view = view;
|
||||||
|
|
||||||
const map = new Map({
|
const map = new Map({
|
||||||
target: 'map',
|
target: 'map',
|
||||||
layers: [
|
layers: [
|
||||||
@ -127,12 +145,25 @@ const map = new Map({
|
|||||||
}),
|
}),
|
||||||
stagesCompletedLayer,
|
stagesCompletedLayer,
|
||||||
stagesAheadLayer,
|
stagesAheadLayer,
|
||||||
|
legacyLayer,
|
||||||
poiLayer,
|
poiLayer,
|
||||||
vanLayer
|
trackedPointsLayer
|
||||||
],
|
],
|
||||||
view: view
|
view: view
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Center map on current/next stage
|
||||||
|
//
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const nextStageFeature = new GeoJSON().readFeature(stagesAhead[0]);
|
||||||
|
view.fit(nextStageFeature.getGeometry(), {
|
||||||
|
maxZoom: 10,
|
||||||
|
duration: 1000
|
||||||
|
});
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Popups
|
// Popups
|
||||||
//
|
//
|
||||||
@ -153,20 +184,26 @@ function disposePopover() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createPopoverHtml(feature) {
|
||||||
|
const container = document.createElement('div');
|
||||||
|
const title = document.createElement('div');
|
||||||
|
title.textContent = feature.get('name');
|
||||||
|
container.append(title);
|
||||||
|
return container.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
// display popup on click
|
// display popup on click
|
||||||
map.on('click', function (evt) {
|
map.on('click', function (evt) {
|
||||||
const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
|
const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
|
||||||
return feature;
|
return feature;
|
||||||
});
|
});
|
||||||
disposePopover();
|
disposePopover();
|
||||||
if (!feature) {
|
if (!feature) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
popup.setPosition(evt.coordinate);
|
popup.setPosition(evt.coordinate);
|
||||||
popover = new bootstrap.Popover(popupEl, {
|
popover = new bootstrap.Popover(popupEl, {
|
||||||
placement: 'top',
|
placement: 'top',
|
||||||
html: true,
|
html: true,
|
||||||
content: feature.get('name'),
|
content: createPopoverHtml(feature)
|
||||||
});
|
});
|
||||||
popover.show();
|
popover.show();
|
||||||
});
|
});
|
||||||
@ -180,3 +217,78 @@ map.on('pointermove', function (evt) {
|
|||||||
|
|
||||||
// Close the popup when the map is moved
|
// Close the popup when the map is moved
|
||||||
map.on('movestart', disposePopover);
|
map.on('movestart', disposePopover);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tracking
|
||||||
|
//
|
||||||
|
|
||||||
|
const updateInterval = 10000;
|
||||||
|
const peopleOverlays = {};
|
||||||
|
|
||||||
|
function createParticipantHTML (name) {
|
||||||
|
if (document.getElementById(`user-${name}`)) return;
|
||||||
|
const el = document.createElement('img');
|
||||||
|
el.src = `https://r2b22.kip.pe/avatars/${name}.png`;
|
||||||
|
el.id = `user-${name}`;
|
||||||
|
el.style = 'width: 40px; height: 40px; border-radius: 20px; cursor: pointer';
|
||||||
|
document.getElementById('people').append(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createParticipantOverlay (name) {
|
||||||
|
if (peopleOverlays[name]) return;
|
||||||
|
const overlayElement = new Overlay({
|
||||||
|
stopEvent: false,
|
||||||
|
positioning: 'center-center',
|
||||||
|
element: document.getElementById(`user-${name}`)
|
||||||
|
});
|
||||||
|
peopleOverlays[name] = overlayElement;
|
||||||
|
map.addOverlay(overlayElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRecentTimestamp (tst) {
|
||||||
|
// newer than 2 hours ago?
|
||||||
|
return (tst * 1000) > (Date.now() - 2*60*60*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateData(startInterval=false) {
|
||||||
|
fetch('https://r2b22.kip.pe/last.json')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const vanData = data.find(i => i.name == 'satoshithevan');
|
||||||
|
const vanCoords = [vanData.lon, vanData.lat];
|
||||||
|
vanFeature.getGeometry().setCoordinates(vanCoords);
|
||||||
|
|
||||||
|
for (const item of data) {
|
||||||
|
if (!tourStatus.participants.includes(item.name)) continue;
|
||||||
|
if (!isRecentTimestamp(item.tst)) continue;
|
||||||
|
createParticipantHTML(item.name);
|
||||||
|
createParticipantOverlay(item.name);
|
||||||
|
const overlay = peopleOverlays[item.name];
|
||||||
|
overlay.setPosition([item.lon, item.lat]);
|
||||||
|
|
||||||
|
function clickHandler () {
|
||||||
|
disposePopover();
|
||||||
|
popup.setPosition([item.lon, item.lat]);
|
||||||
|
popover = new bootstrap.Popover(popupEl, {
|
||||||
|
placement: 'top',
|
||||||
|
html: true,
|
||||||
|
content: `Rider: ${item.name}`
|
||||||
|
});
|
||||||
|
popover.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
const avatarEl = document.getElementById(`user-${item.name}`);
|
||||||
|
avatarEl.removeEventListener('click', clickHandler);
|
||||||
|
avatarEl.addEventListener('click', clickHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (startInterval) {
|
||||||
|
setInterval(updateData, updateInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateData(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
|
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ol-vite",
|
"name": "ol-vite",
|
||||||
"version": "1.0.0",
|
"version": "1.10.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ol-vite",
|
"name": "ol-vite",
|
||||||
"version": "1.0.0",
|
"version": "1.10.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ol": "latest"
|
"ol": "latest"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "map",
|
"name": "map",
|
||||||
"version": "1.0.0",
|
"version": "1.10.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
BIN
public/img/icon.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
public/img/r2b-logo.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
public/img/van-100px.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
2
public/js/lightning-widget.js
Normal file
26
style.css
@ -4,9 +4,35 @@ html, body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#map {
|
#map {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img#logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 256px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
lightning-widget {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 10px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
lightning-widget {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|