From 8350ba8f815c09783efc82978770658ad71bd12b Mon Sep 17 00:00:00 2001 From: Gwendolyn Date: Fri, 6 Sep 2024 18:53:20 +0200 Subject: [PATCH] key/legend control --- src/c3nav/site/static/site/css/c3nav.scss | 72 +++ src/c3nav/site/static/site/js/c3nav.js | 618 +++++++++++++--------- 2 files changed, 449 insertions(+), 241 deletions(-) diff --git a/src/c3nav/site/static/site/css/c3nav.scss b/src/c3nav/site/static/site/css/c3nav.scss index 61249cb0..855fa21f 100644 --- a/src/c3nav/site/static/site/css/c3nav.scss +++ b/src/c3nav/site/static/site/css/c3nav.scss @@ -1555,4 +1555,76 @@ blink { top: 40px; left: 21px; } +} + + +.leaflet-control-key { + background-color: white; + border-radius: 0.5rem; + border: 2px solid rgba(0, 0, 0, 0.2); + background-clip: padding-box; + + &.leaflet-control-key-expanded > .collapsed-toggle { + display: none; + } + + > .collapsed-toggle { + width: 26px; + height: 26px; + line-height: 26px; + text-align: center; + &::before { + content: '🔑'; + } + } + + > .pin-toggle { + display: none; + position: absolute; + right: 0.5rem; + color: black; + font-size: 1.5rem; + top: 0.5rem; + width: 2.5rem; + height: 2.5rem; + border: 1px solid #DCDCDC; + border-radius: 0.5rem; + text-align: center; + cursor: pointer; + + &:hover { + box-shadow: inset 0 0 2px black; + } + + &.active { + border-color: black; + background: #DCDCDC; + box-shadow: inset 0 0 2px black; + } + } + + &.leaflet-control-key-expanded > .pin-toggle { + display: block; + } + + > .content { + display: none; + padding: 1rem; + gap: 1rem; + grid-template-columns: 26px 1fr; + + > .key { + display: grid; + grid-column: span 2; + grid-template-columns: subgrid; + > .key-color { + width: 100%; + height: 100%; + } + } + } + + &.leaflet-control-key-expanded > .content { + display: grid; + } } \ No newline at end of file diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index ca3b2020..a4a68140 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -30,15 +30,15 @@ /* * Polyfill for Math.Log2 because Internet Explorer sucks */ - Math.log2 = Math.log2 || function(x) { + Math.log2 = Math.log2 || function (x) { return Math.log(x) * Math.LOG2E; }; var originalGetIconBox = L.LayerGroup.Collision.prototype._getIconBox; - L.LayerGroup.Collision.prototype._getIconBox = function(el) { + L.LayerGroup.Collision.prototype._getIconBox = function (el) { var result = originalGetIconBox(el); - var offsetX = (result[2]-result[0]/2), - offsetY = (result[3]-result[1]/2); + var offsetX = (result[2] - result[0] / 2), + offsetY = (result[3] - result[1] / 2); result[0] -= offsetX; result[1] -= offsetY; result[2] -= offsetX; @@ -57,41 +57,41 @@ localStorageWrapper = { get length() { try { return localStorage.length; - } catch(e) { + } catch (e) { return 0; } }, - key: function(key) { + key: function (key) { try { return localStorage.key(key); - } catch(e) { + } catch (e) { return null; } }, - getItem: function(keyName) { + getItem: function (keyName) { try { return localStorage.getItem(keyName) - } catch(e) { + } catch (e) { return null; } }, - setItem: function(keyName, keyValue) { + setItem: function (keyName, keyValue) { try { localStorage.setItem(keyName, keyValue) - } catch(e) { - console.log("can't set localstorage preference for "+ keyName); + } catch (e) { + console.log("can't set localstorage preference for " + keyName); } }, - removeItem: function(keyName) { + removeItem: function (keyName) { try { localStorage.removeItem(keyName) - } catch(e) { + } catch (e) { } }, - clear: function() { + clear: function () { try { localStorage.clear() - } catch(e) { + } catch (e) { } }, }; @@ -105,9 +105,9 @@ c3nav = { c3nav.load_material_symbols_if_needed(); c3nav.load_searchable_locations(); - $('#messages').find('ul.messages li').each(function() { + $('#messages').find('ul.messages li').each(function () { $(this).prepend( - $('close').click(function(e) { + $('close').click(function (e) { e.preventDefault(); $(this).parent().remove(); }) @@ -116,7 +116,7 @@ c3nav = { if (!window.mobileclient && !localStorageWrapper.getItem('hideAppAds') && navigator.userAgent.toLowerCase().indexOf("android") > -1 && c3nav.ssids) { $('.app-ads').show(); - $('.app-ads .close').click(function() { + $('.app-ads .close').click(function () { localStorageWrapper.setItem('hideAppAds', true); $('.app-ads').remove(); }); @@ -141,7 +141,7 @@ c3nav = { c3nav.themes = JSON.parse(document.getElementById('c3nav-themes').textContent); }, _searchable_locations_timer: null, - load_searchable_locations: function(firstTime) { + load_searchable_locations: function (firstTime) { c3nav._searchable_locations_timer = null; c3nav_api.get('map/locations?searchable=true') .then(c3nav._searchable_locations_loaded) @@ -151,14 +151,14 @@ c3nav = { } }); }, - _sort_labels: function(a, b) { + _sort_labels: function (a, b) { var result = (a[0].label_settings.min_zoom || -10) - (b[0].label_settings.min_zoom || -10); if (result === 0) result = b[0].label_settings.font_size - a[0].label_settings.font_size; return result; }, _last_time_searchable_locations_loaded: null, _searchable_locations_interval: 120000, - _searchable_locations_loaded: function(data) { + _searchable_locations_loaded: function (data) { c3nav._last_time_searchable_locations_loaded = Date.now(); if (data !== undefined) { var locations = [], @@ -193,7 +193,7 @@ c3nav = { c3nav._searchable_locations_timer = window.setTimeout(c3nav.load_searchable_locations, c3nav._searchable_locations_interval); } }, - continue_init: function() { + continue_init: function () { c3nav.init_map(); $('.locationinput').data('location', null); @@ -210,8 +210,8 @@ c3nav = { c3nav.random_location_groups = $main.is('[data-random-location-groups]') ? $main.attr('data-random-location-groups').split(',').map(id => parseInt(id)) : null; $(document).on('click', '.theme-selection>button', c3nav.select_theme); - - + + history.replaceState(state, window.location.path); c3nav.load_state(state, true); c3nav.update_map_locations(); @@ -268,7 +268,7 @@ c3nav = { //c3nav.test_location(); }, - test_location: function() { + test_location: function () { c3nav_api.get('positioning/locate-test') .then(data => { window.setTimeout(c3nav.test_location, 1000); @@ -281,7 +281,7 @@ c3nav = { }, state: {}, - update_state: function(routing, replace, details, options, nearby) { + update_state: function (routing, replace, details, options, nearby) { if (typeof routing !== "boolean") routing = c3nav.state.routing; if (details) { @@ -311,7 +311,7 @@ c3nav = { c3nav._sidebar_state_updated(new_state); }, - current_level: function() { + current_level: function () { return c3nav._levelControl.currentLevel || c3nav.resume_level; }, update_map_state: function (replace, level, center, zoom) { @@ -381,20 +381,20 @@ c3nav = { c3nav.update_map_locations(); }, - _clear_route_layers: function() { + _clear_route_layers: function () { c3nav._firstRouteLevel = null; c3nav._routeLayerBounds = {}; for (var id in c3nav._routeLayers) { c3nav._routeLayers[id].clearLayers(); } }, - _clear_detail_layers: function() { + _clear_detail_layers: function () { for (var id in c3nav._detailLayers) { c3nav._detailLayers[id].clearLayers(); } }, - update_location_labels: function() { + update_location_labels: function () { if (!c3nav._labelControl.labelsActive) return; c3nav._labelLayer.clearLayers(); var labels = c3nav.labels[c3nav.current_level()], @@ -440,7 +440,7 @@ c3nav = { }) } }, - _location_details_loaded: function(data) { + _location_details_loaded: function (data) { var $location_details = $('#location-details'); if ($location_details.attr('data-id') !== String(data.id)) { // loaded too late, information no longer needed @@ -487,7 +487,7 @@ c3nav = { if (data.geometry) { var custom_location = typeof data.id !== 'number', - report_url = '/report/l/'+String(data.id)+'/'; + report_url = '/report/l/' + String(data.id) + '/'; $location_details.find('.report').attr('href', report_url); } else { $location_details.find('.report').hide(); @@ -523,7 +523,7 @@ c3nav = { } c3nav.next_route_options = null; }, - _route_loaded: function(data, nofly) { + _route_loaded: function (data, nofly) { var $route = $('#route-summary'); if (data.error && $route.is('.loading')) { $route.find('span').text(data.error); @@ -539,7 +539,7 @@ c3nav = { c3nav._display_route_result(data.result, nofly); c3nav._display_route_options(data.options_form); }, - _display_route_result: function(result, nofly) { + _display_route_result: function (result, nofly) { var $route = $('#route-summary'), $details_wrapper = $('#route-details'), $details = $details_wrapper.find('.details-body'), @@ -556,10 +556,10 @@ c3nav = { $details.html(''); $details.append(c3nav._build_location_html(result.origin)); - for (var i=0; i < result.items.length; i++) { + for (var i = 0; i < result.items.length; i++) { item = result.items[i]; - for (var j=0; j < item.descriptions.length; j++) { + for (var j = 0; j < item.descriptions.length; j++) { description = item.descriptions[j]; $details.append(c3nav._build_route_item(description[0], description[1])); } @@ -650,24 +650,24 @@ c3nav = { elem.append($('').text(text)); return elem; }, - _add_intermediate_point: function(origin, destination, next) { - var angle = Math.atan2(destination[1]-next[1], destination[0]-next[0]), - distance = Math.sqrt(Math.pow(origin[0]-destination[0], 2) + Math.pow(origin[1]-destination[1], 2)), - offset = Math.min(1.5, distance/4), - point = [destination[0]+Math.cos(angle)*offset, destination[1]+Math.sin(angle)*offset]; + _add_intermediate_point: function (origin, destination, next) { + var angle = Math.atan2(destination[1] - next[1], destination[0] - next[0]), + distance = Math.sqrt(Math.pow(origin[0] - destination[0], 2) + Math.pow(origin[1] - destination[1], 2)), + offset = Math.min(1.5, distance / 4), + point = [destination[0] + Math.cos(angle) * offset, destination[1] + Math.sin(angle) * offset]; return [origin, point, destination]; }, - _add_line_to_route: function(level, coords, gray, link_to_level) { + _add_line_to_route: function (level, coords, gray, link_to_level) { if (coords.length < 2) return; var latlngs = L.GeoJSON.coordsToLatLngs(c3nav._smooth_line(coords)), routeLayer = c3nav._routeLayers[level]; - line = L.polyline(latlngs, { - color: gray ? '#888888': 'var(--color-primary)', - dashArray: (gray || link_to_level) ? '7' : null, - interactive: false, - smoothFactor: 0.5 - }).addTo(routeLayer); - bounds = {}; + line = L.polyline(latlngs, { + color: gray ? '#888888' : 'var(--color-primary)', + dashArray: (gray || link_to_level) ? '7' : null, + interactive: false, + smoothFactor: 0.5 + }).addTo(routeLayer); + bounds = {}; bounds[level] = line.getBounds(); c3nav._merge_bounds(c3nav._routeLayerBounds, bounds); @@ -677,43 +677,43 @@ c3nav = { opacity: 0, weight: 15, interactive: true - }).addTo(routeLayer).on('click', function() { + }).addTo(routeLayer).on('click', function () { c3nav._levelControl.setLevel(link_to_level); }); } }, - _smooth_line: function(coords) { + _smooth_line: function (coords) { if (coords.length > 2) { - for (var i=0; i<4; i++) { + for (var i = 0; i < 4; i++) { coords = c3nav._smooth_line_iteration(coords); } } return coords }, - _smooth_line_iteration: function(coords) { + _smooth_line_iteration: function (coords) { // Chaikin'S Corner Cutting Algorithm var new_coords = [coords[0]]; - for (var i=1; i').text(option.label)); + field_id = 'option_id_' + option.name; + $options.append($('