WIP: jeste lepsi prohlizecka.

This commit is contained in:
severak 2021-07-15 22:27:20 +02:00
parent ebf5a90056
commit 69830e4859
5 changed files with 2175 additions and 43 deletions

View File

@ -19,6 +19,7 @@ route('', '/', function (){
// if (!user()) return redirect('/login/'); // if (!user()) return redirect('/login/');
$rows = di('rows'); $rows = di('rows');
$Parsedown = new Parsedown();
$pois = $rows->more('poi'); $pois = $rows->more('poi');
$geojson = ['type'=>'FeatureCollection', 'features'=>[]]; $geojson = ['type'=>'FeatureCollection', 'features'=>[]];
foreach ($pois as $poi) { foreach ($pois as $poi) {
@ -26,8 +27,8 @@ route('', '/', function (){
'type' => 'Feature', 'type' => 'Feature',
'properties' => [ 'properties' => [
'name' => $poi['name'], 'name' => $poi['name'],
'description' => $poi['description'], 'description' => $Parsedown->text($poi['description']),
'cheatsheet' => $poi['cheatsheet'] 'cheatsheet' => $Parsedown->text($poi['cheatsheet'])
], ],
'geometry'=>[ 'geometry'=>[
'type'=>'Point', 'type'=>'Point',

1712
lib/Parsedown.php Normal file

File diff suppressed because it is too large Load Diff

200
static/leaflet-sidebar.css Normal file
View File

@ -0,0 +1,200 @@
.sidebar {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
overflow: hidden;
z-index: 2000; }
.sidebar.collapsed {
width: 40px; }
@media (min-width: 768px) {
.sidebar {
top: 10px;
bottom: 10px;
transition: width 500ms; } }
@media (min-width: 768px) and (max-width: 991px) {
.sidebar {
width: 305px; } }
@media (min-width: 992px) and (max-width: 1199px) {
.sidebar {
width: 390px; } }
@media (min-width: 1200px) {
.sidebar {
width: 460px; } }
.sidebar-left {
left: 0; }
@media (min-width: 768px) {
.sidebar-left {
left: 10px; } }
.sidebar-right {
right: 0; }
@media (min-width: 768px) {
.sidebar-right {
right: 10px; } }
.sidebar-tabs {
top: 0;
bottom: 0;
height: 100%;
background-color: #fff; }
.sidebar-left .sidebar-tabs {
left: 0; }
.sidebar-right .sidebar-tabs {
right: 0; }
.sidebar-tabs, .sidebar-tabs > ul {
position: absolute;
width: 40px;
margin: 0;
padding: 0;
list-style-type: none; }
.sidebar-tabs > li, .sidebar-tabs > ul > li {
width: 100%;
height: 40px;
color: #333;
font-size: 12pt;
overflow: hidden;
transition: all 80ms; }
.sidebar-tabs > li:hover, .sidebar-tabs > ul > li:hover {
color: #000;
background-color: #eee; }
.sidebar-tabs > li.active, .sidebar-tabs > ul > li.active {
color: #fff;
background-color: #0074d9; }
.sidebar-tabs > li.disabled, .sidebar-tabs > ul > li.disabled {
color: rgba(51, 51, 51, 0.4); }
.sidebar-tabs > li.disabled:hover, .sidebar-tabs > ul > li.disabled:hover {
background: transparent; }
.sidebar-tabs > li.disabled > a, .sidebar-tabs > ul > li.disabled > a {
cursor: default; }
.sidebar-tabs > li > a, .sidebar-tabs > ul > li > a {
display: block;
width: 100%;
height: 100%;
line-height: 40px;
color: inherit;
text-decoration: none;
text-align: center; }
.sidebar-tabs > ul + ul {
bottom: 0; }
.sidebar-content {
position: absolute;
top: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.95);
overflow-x: hidden;
overflow-y: auto; }
.sidebar-left .sidebar-content {
left: 40px;
right: 0; }
.sidebar-right .sidebar-content {
left: 0;
right: 40px; }
.sidebar.collapsed > .sidebar-content {
overflow-y: hidden; }
.sidebar-pane {
display: none;
left: 0;
right: 0;
box-sizing: border-box;
padding: 10px 20px; }
.sidebar-pane.active {
display: block; }
@media (min-width: 768px) and (max-width: 991px) {
.sidebar-pane {
min-width: 265px; } }
@media (min-width: 992px) and (max-width: 1199px) {
.sidebar-pane {
min-width: 350px; } }
@media (min-width: 1200px) {
.sidebar-pane {
min-width: 420px; } }
.sidebar-header {
margin: -10px -20px 0;
height: 40px;
padding: 0 20px;
line-height: 40px;
font-size: 14.4pt;
color: #fff;
background-color: #0074d9; }
.sidebar-right .sidebar-header {
padding-left: 40px; }
.sidebar-close {
position: absolute;
top: 0;
width: 40px;
height: 40px;
text-align: center;
cursor: pointer; }
.sidebar-left .sidebar-close {
right: 0; }
.sidebar-right .sidebar-close {
left: 0; }
.sidebar-left ~ .sidebar-map {
margin-left: 40px; }
@media (min-width: 768px) {
.sidebar-left ~ .sidebar-map {
margin-left: 0; } }
.sidebar-right ~ .sidebar-map {
margin-right: 40px; }
@media (min-width: 768px) {
.sidebar-right ~ .sidebar-map {
margin-right: 0; } }
.sidebar {
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65); }
.sidebar.leaflet-touch {
box-shadow: none;
border-right: 2px solid rgba(0, 0, 0, 0.2); }
@media (min-width: 768px) {
.sidebar {
border-radius: 4px; }
.sidebar.leaflet-touch {
border: 2px solid rgba(0, 0, 0, 0.2); } }
@media (min-width: 768px) {
.sidebar-left ~ .sidebar-map .leaflet-left {
transition: left 500ms; } }
@media (min-width: 768px) and (max-width: 991px) {
.sidebar-left ~ .sidebar-map .leaflet-left {
left: 315px; } }
@media (min-width: 992px) and (max-width: 1199px) {
.sidebar-left ~ .sidebar-map .leaflet-left {
left: 400px; } }
@media (min-width: 1200px) {
.sidebar-left ~ .sidebar-map .leaflet-left {
left: 470px; } }
@media (min-width: 768px) {
.sidebar-left.collapsed ~ .sidebar-map .leaflet-left {
left: 50px; } }
@media (min-width: 768px) {
.sidebar-right ~ .sidebar-map .leaflet-right {
transition: right 500ms; } }
@media (min-width: 768px) and (max-width: 991px) {
.sidebar-right ~ .sidebar-map .leaflet-right {
right: 315px; } }
@media (min-width: 992px) and (max-width: 1199px) {
.sidebar-right ~ .sidebar-map .leaflet-right {
right: 400px; } }
@media (min-width: 1200px) {
.sidebar-right ~ .sidebar-map .leaflet-right {
right: 470px; } }
@media (min-width: 768px) {
.sidebar-right.collapsed ~ .sidebar-map .leaflet-right {
right: 50px; } }

216
static/leaflet-sidebar.js Normal file
View File

@ -0,0 +1,216 @@
/* global L */
/**
* @name Sidebar
* @class L.Control.Sidebar
* @extends L.Control
* @param {string} id - The id of the sidebar element (without the # character)
* @param {Object} [options] - Optional options object
* @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
* @see L.control.sidebar
*/
L.Control.Sidebar = L.Control.extend(/** @lends L.Control.Sidebar.prototype */ {
includes: (L.Evented.prototype || L.Mixin.Events),
options: {
position: 'left'
},
initialize: function (id, options) {
var i, child;
L.setOptions(this, options);
// Find sidebar HTMLElement
this._sidebar = L.DomUtil.get(id);
// Attach .sidebar-left/right class
L.DomUtil.addClass(this._sidebar, 'sidebar-' + this.options.position);
// Attach touch styling if necessary
if (L.Browser.touch)
L.DomUtil.addClass(this._sidebar, 'leaflet-touch');
// Find sidebar > div.sidebar-content
for (i = this._sidebar.children.length - 1; i >= 0; i--) {
child = this._sidebar.children[i];
if (child.tagName == 'DIV' &&
L.DomUtil.hasClass(child, 'sidebar-content'))
this._container = child;
}
// Find sidebar ul.sidebar-tabs > li, sidebar .sidebar-tabs > ul > li
this._tabitems = this._sidebar.querySelectorAll('ul.sidebar-tabs > li, .sidebar-tabs > ul > li');
for (i = this._tabitems.length - 1; i >= 0; i--) {
this._tabitems[i]._sidebar = this;
}
// Find sidebar > div.sidebar-content > div.sidebar-pane
this._panes = [];
this._closeButtons = [];
for (i = this._container.children.length - 1; i >= 0; i--) {
child = this._container.children[i];
if (child.tagName == 'DIV' &&
L.DomUtil.hasClass(child, 'sidebar-pane')) {
this._panes.push(child);
var closeButtons = child.querySelectorAll('.sidebar-close');
for (var j = 0, len = closeButtons.length; j < len; j++)
this._closeButtons.push(closeButtons[j]);
}
}
},
/**
* Add this sidebar to the specified map.
*
* @param {L.Map} map
* @returns {Sidebar}
*/
addTo: function (map) {
var i, child;
this._map = map;
for (i = this._tabitems.length - 1; i >= 0; i--) {
child = this._tabitems[i];
var sub = child.querySelector('a');
if (sub.hasAttribute('href') && sub.getAttribute('href').slice(0,1) == '#') {
L.DomEvent
.on(sub, 'click', L.DomEvent.preventDefault )
.on(sub, 'click', this._onClick, child);
}
}
for (i = this._closeButtons.length - 1; i >= 0; i--) {
child = this._closeButtons[i];
L.DomEvent.on(child, 'click', this._onCloseClick, this);
}
return this;
},
/**
* @deprecated - Please use remove() instead of removeFrom(), as of Leaflet 0.8-dev, the removeFrom() has been replaced with remove()
* Removes this sidebar from the map.
* @param {L.Map} map
* @returns {Sidebar}
*/
removeFrom: function(map) {
console.log('removeFrom() has been deprecated, please use remove() instead as support for this function will be ending soon.');
this.remove(map);
},
/**
* Remove this sidebar from the map.
*
* @param {L.Map} map
* @returns {Sidebar}
*/
remove: function (map) {
var i, child;
this._map = null;
for (i = this._tabitems.length - 1; i >= 0; i--) {
child = this._tabitems[i];
L.DomEvent.off(child.querySelector('a'), 'click', this._onClick);
}
for (i = this._closeButtons.length - 1; i >= 0; i--) {
child = this._closeButtons[i];
L.DomEvent.off(child, 'click', this._onCloseClick, this);
}
return this;
},
/**
* Open sidebar (if necessary) and show the specified tab.
*
* @param {string} id - The id of the tab to show (without the # character)
*/
open: function(id) {
var i, child;
// hide old active contents and show new content
for (i = this._panes.length - 1; i >= 0; i--) {
child = this._panes[i];
if (child.id == id)
L.DomUtil.addClass(child, 'active');
else if (L.DomUtil.hasClass(child, 'active'))
L.DomUtil.removeClass(child, 'active');
}
// remove old active highlights and set new highlight
for (i = this._tabitems.length - 1; i >= 0; i--) {
child = this._tabitems[i];
if (child.querySelector('a').hash == '#' + id)
L.DomUtil.addClass(child, 'active');
else if (L.DomUtil.hasClass(child, 'active'))
L.DomUtil.removeClass(child, 'active');
}
this.fire('content', { id: id });
// open sidebar (if necessary)
if (L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
this.fire('opening');
L.DomUtil.removeClass(this._sidebar, 'collapsed');
}
return this;
},
/**
* Close the sidebar (if necessary).
*/
close: function() {
// remove old active highlights
for (var i = this._tabitems.length - 1; i >= 0; i--) {
var child = this._tabitems[i];
if (L.DomUtil.hasClass(child, 'active'))
L.DomUtil.removeClass(child, 'active');
}
// close sidebar
if (!L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
this.fire('closing');
L.DomUtil.addClass(this._sidebar, 'collapsed');
}
return this;
},
/**
* @private
*/
_onClick: function() {
if (L.DomUtil.hasClass(this, 'active'))
this._sidebar.close();
else if (!L.DomUtil.hasClass(this, 'disabled'))
this._sidebar.open(this.querySelector('a').hash.slice(1));
},
/**
* @private
*/
_onCloseClick: function () {
this.close();
}
});
/**
* Creates a new sidebar.
*
* @example
* var sidebar = L.control.sidebar('sidebar').addTo(map);
*
* @param {string} id - The id of the sidebar element (without the # character)
* @param {Object} [options] - Optional options object
* @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
* @returns {Sidebar} A new sidebar instance
*/
L.control.sidebar = function (id, options) {
return new L.Control.Sidebar(id, options);
};

View File

@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php if (isset($title)) echo $title . ' - ' ; ?>Průvodce</title> <title><?php if (isset($title)) echo $title . ' - ' ; ?>Průvodce</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="/static/uboot.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
<script src="https://cdn.maptiler.com/mapbox-gl-js/v1.5.1/mapbox-gl.js"></script> <script src="https://cdn.maptiler.com/mapbox-gl-js/v1.5.1/mapbox-gl.js"></script>
<script src="https://cdn.maptiler.com/mapbox-gl-leaflet/latest/leaflet-mapbox-gl.js"></script> <script src="https://cdn.maptiler.com/mapbox-gl-leaflet/latest/leaflet-mapbox-gl.js"></script>
@ -20,9 +21,8 @@
font: 10pt "Helvetica Neue", Arial, Helvetica, sans-serif; font: 10pt "Helvetica Neue", Arial, Helvetica, sans-serif;
} }
.lorem { #article-cheat {
font-style: italic; color: gray;
color: #AAA;
} }
</style> </style>
</head> </head>
@ -32,13 +32,6 @@
<div class="sidebar-tabs"> <div class="sidebar-tabs">
<ul role="tablist"> <ul role="tablist">
<li><a href="#home" role="tab"><i class="fa fa-bars"></i></a></li> <li><a href="#home" role="tab"><i class="fa fa-bars"></i></a></li>
<li><a href="#profile" role="tab"><i class="fa fa-user"></i></a></li>
<li class="disabled"><a href="#messages" role="tab"><i class="fa fa-envelope"></i></a></li>
<li><a href="https://github.com/Turbo87/sidebar-v2" role="tab" target="_blank"><i class="fa fa-github"></i></a></li>
</ul>
<ul role="tablist">
<li><a href="#settings" role="tab"><i class="fa fa-gear"></i></a></li>
</ul> </ul>
</div> </div>
@ -46,35 +39,18 @@
<div class="sidebar-content"> <div class="sidebar-content">
<div class="sidebar-pane" id="home"> <div class="sidebar-pane" id="home">
<h1 class="sidebar-header"> <h1 class="sidebar-header">
<span id="article-name"></span> <span id="article-name">Turistický průvodce</span>
<span class="sidebar-close"><i class="fa fa-caret-left"></i></span> <span class="sidebar-close"><i class="fa fa-caret-left"></i></span>
</h1> </h1>
<div id="article-text"> <div id="article-text">
<p>A responsive sidebar for mapping libraries like <a href="http://leafletjs.com/">Leaflet</a> or <a href="http://openlayers.org/">OpenLayers</a>.</p> <p>Matička Metropolis...</p>
<p>Stránka je v přípravě.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p> </div>
<p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<div id="article-cheat">
</div> </div>
</div> </div>
<div class="sidebar-pane" id="profile">
<h1 class="sidebar-header">Profile<span class="sidebar-close"><i class="fa fa-caret-left"></i></span></h1>
</div>
<div class="sidebar-pane" id="messages">
<h1 class="sidebar-header">Messages<span class="sidebar-close"><i class="fa fa-caret-left"></i></span></h1>
</div>
<div class="sidebar-pane" id="settings">
<h1 class="sidebar-header">Settings<span class="sidebar-close"><i class="fa fa-caret-left"></i></span></h1>
</div>
</div> </div>
</div> </div>
@ -84,28 +60,55 @@
</div> </div>
<p><a href="https://svita.cz/">Svita.cz</a> <a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a></p> <p><a href="https://svita.cz/">Svita.cz</a> <a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a></p>
<script> <script>
function webgl_support() {
try {
var canvas = document.createElement('canvas');
return !!window.WebGLRenderingContext &&
(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
} catch (e) {
return false;
}
return false;
}
function detectMob() {
return ( ( window.innerWidth <= 800 ) && ( window.innerHeight <= 600 ) );
}
whenReady(function () {
var map = L.map('map').setView([50.08536, 14.42040], 15); var map = L.map('map').setView([50.08536, 14.42040], 15);
// TODO - try catch fallback CartoDB if (!webgl_support() || detectMob()) {
var gl = L.mapboxGL({ var OpenStreetMap_Mapnik = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: "\u003ca href=\"https://svita.cz/\"\u003eSvita.cz\u003c/a\u003e \u003ca href=\"https://www.maptiler.com/copyright/\" target=\"_blank\"\u003e\u0026copy; MapTiler\u003c/a\u003e \u003ca href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\"\u003e\u0026copy; OpenStreetMap contributors\u003c/a\u003e", maxZoom: 19,
style: 'https://api.maptiler.com/maps/28280352-f69a-45fd-8dd7-2f178d7ed64f/style.json?key=lFBi7gs1S6TyJPtVVvOX' attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map); }).addTo(map);
} else {
var gl = L.mapboxGL({
attribution: "\u003ca href=\"https://svita.cz/\"\u003eSvita.cz\u003c/a\u003e \u003ca href=\"https://www.maptiler.com/copyright/\" target=\"_blank\"\u003e\u0026copy; MapTiler\u003c/a\u003e \u003ca href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\"\u003e\u0026copy; OpenStreetMap contributors\u003c/a\u003e",
style: 'https://api.maptiler.com/maps/28280352-f69a-45fd-8dd7-2f178d7ed64f/style.json?key=lFBi7gs1S6TyJPtVVvOX'
}).addTo(map);
}
var sidebar = L.control.sidebar('sidebar').addTo(map); var sidebar = L.control.sidebar('sidebar').addTo(map);
L.geoJSON(<?php echo json_encode($geojson); ?>, { L.geoJSON(<?php echo json_encode($geojson); ?>, {}).on('click', function (layer) {
}).on('click', function (layer) {
// TODO - dirty JS // TODO - dirty JS
console.log('klik', layer.layer.feature.properties.name); console.log('klik', layer.layer.feature.properties.name);
document.getElementById('article-name').innerText = layer.layer.feature.properties.name; document.getElementById('article-name').innerText = layer.layer.feature.properties.name;
document.getElementById('article-text').innerText = layer.layer.feature.properties.cheatsheet; document.getElementById('article-text').innerHTML = layer.layer.feature.properties.description;
document.getElementById('article-cheat').innerHTML = layer.layer.feature.properties.cheatsheet;
sidebar.open('home'); sidebar.open('home');
}).addTo(map); }).addTo(map);
});
</script> </script>
</body> </body>
</html> </html>