diff options
-rw-r--r-- | index.html | 16 | ||||
-rw-r--r-- | main.js | 123 | ||||
-rw-r--r-- | style.css | 356 |
3 files changed, 270 insertions, 225 deletions
@@ -7,11 +7,19 @@ </head> <body> <div id="map"></div> - <div id="layer-selection-panel" aria-hidden="true"> - <div class="form-check form-switch"> - <input class="form-check-input" type="checkbox" role="switch" id="layer-topowebb_nedtonad"> - <label class="form-check-label" for="layer-topowebb_nedtonad">Nedtonad bakgrund karta</label> + <div id="map-control-container" aria-hidden="true"> + <div id="zoom-control"></div> + <div id="layer-selection-panel" class="modal" role="dialog" aria-hidden="true"> + <div class="modal-content"> + <div class="modal-body"> + <div class="form-check form-switch"> + <input class="form-check-input" type="checkbox" role="switch" id="layer-topowebb_nedtonad"> + <label class="form-check-label" for="layer-topowebb_nedtonad">Nedtonad bakgrund karta</label> + </div> + </div> + </div> </div> + <div id="map-menu"></div> </div> <div class="modal" id="modal-info" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered modal-lg"> @@ -94,28 +94,7 @@ const baseMapSource = new WMTS({ const map = new Map({ - controls: [ - new Zoom({ - zoomInTipLabel: 'Zooma in', - zoomInLabel: (function() { - const label = document.createElement('i'); - label.classList.add('bi', 'bi-plus'); - return label; - })(), - zoomOutTipLabel: 'Zooma ut', - zoomOutLabel: (function() { - const label = document.createElement('i'); - label.classList.add('bi', 'bi-dash'); - return label; - })(), - }), - new ZoomSlider({ - }), - new ScaleLine({ - units: 'metric', - minWidth: 150, - }), - ], + controls: [], view: new View({ projection: projection, extent: extent, @@ -135,16 +114,62 @@ const map = new Map({ target: document.getElementById('map'), }); -/* add the menu to the viewport */ -const menu = document.createElement('div'); -menu.ariaHidden = 'true'; -menu.id = 'map-menu'; -map.getViewport().appendChild(menu); +/* move the control container to the viewport */ +const container = document.getElementById('map-control-container'); +map.getViewport().appendChild(container); + +/* zoom in/out */ +(function() { + const zoomInLabel = document.createElement('i'); + zoomInLabel.classList.add('bi', 'bi-plus'); + + const zoomOutLabel = document.createElement('i'); + zoomOutLabel.classList.add('bi', 'bi-dash'); + + const control = new Zoom({ + zoomInTipLabel: 'Zooma in', + zoomInLabel: zoomInLabel, + zoomOutTipLabel: 'Zooma ut', + zoomOutLabel: zoomOutLabel, + target: document.getElementById('zoom-control'), + }); + + control.element.classList.add('btn-group-vertical'); + for (const btn of control.element.getElementsByTagName('button')) { + btn.classList.add('btn', 'btn-light'); + } + map.addControl(control); +})(); + +/* zoom slider */ +(function() { + const control = new ZoomSlider({ + target: document.getElementById('zoom-control'), + }); + control.element.classList.add('modal'); + for (const btn of control.element.getElementsByTagName('button')) { + btn.classList.add('btn', 'btn-light'); + } + map.addControl(control); +})(); + +/* scale line */ +(function() { + const control = new ScaleLine({ + units: 'metric', + minWidth: 150, + target: container, + }); + control.element.classList.add('modal', 'modal-content'); + map.addControl(control); +})(); /* layer selection button */ +const menu = document.getElementById('map-menu'); (function() { const div = document.createElement('div'); - menu.append(div); + menu.appendChild(div); + div.id = 'layer-selection-button'; div.classList.add('ol-unselectable', 'ol-control'); const btn = document.createElement('button'); @@ -152,6 +177,7 @@ map.getViewport().appendChild(menu); btn.type = 'button'; btn.ariaExpanded = 'false'; btn.title = 'Byt kartlager'; + btn.classList.add('btn', 'btn-light'); const i = document.createElement('i'); btn.appendChild(i); @@ -162,9 +188,13 @@ map.getViewport().appendChild(menu); if (btn.ariaExpanded === 'true') { panel.ariaHidden = 'true'; btn.ariaExpanded = 'false'; + btn.classList.add('btn-light'); + btn.classList.remove('btn-dark'); } else { panel.ariaHidden = 'false'; btn.ariaExpanded = 'true'; + btn.classList.add('btn-dark'); + btn.classList.remove('btn-light'); } }; })(); @@ -177,19 +207,40 @@ map.getViewport().appendChild(menu); const labelActive = document.createElement('i'); labelActive.classList.add('bi', 'bi-fullscreen-exit'); - map.addControl(new FullScreen({ + const titleInactive = 'Helskärmsläge'; + const titleActive = 'Lämna helskärmsläge'; + const classInactive = 'btn-light'; + const classActive = 'btn-dark'; + + const control = new FullScreen({ label: label, labelActive: labelActive, - tipLabel: 'Växla helskärmsläge', + tipLabel: titleInactive, keys: true, target: menu, - })); + }) + control.element.getElementsByTagName('button')[0].classList.add('btn', classInactive); + map.addControl(control); + + control.addEventListener('enterfullscreen', function() { + const btn = control.element.getElementsByTagName('button')[0]; + btn.classList.add(classActive); + btn.classList.remove(classInactive); + btn.title = titleActive; + }) + control.addEventListener('leavefullscreen', function() { + const btn = control.element.getElementsByTagName('button')[0]; + btn.classList.add(classInactive); + btn.classList.remove(classActive); + btn.title = titleInactive; + }) })(); /* info button */ (function() { const div = document.createElement('div'); - menu.append(div); + menu.appendChild(div); + div.id = 'info-button'; div.classList.add('ol-unselectable', 'ol-control'); const btn = document.createElement('button'); @@ -197,6 +248,7 @@ map.getViewport().appendChild(menu); btn.type = 'button'; btn.ariaExpanded = 'false'; btn.title = 'Visa information'; + btn.classList.add('btn', 'btn-light'); const i = document.createElement('i'); btn.appendChild(i); @@ -206,9 +258,13 @@ map.getViewport().appendChild(menu); const modal = new Modal(panel, {}); panel.addEventListener('show.bs.modal', function() { btn.ariaExpanded = 'true'; + btn.classList.add('btn-dark'); + btn.classList.remove('btn-light'); }); panel.addEventListener('hidden.bs.modal', function() { btn.ariaExpanded = 'false'; + btn.classList.add('btn-light'); + btn.classList.remove('btn-dark'); }); btn.onclick = function() { @@ -216,7 +272,8 @@ map.getViewport().appendChild(menu); }; })(); -menu.ariaHidden = 'false'; +/* we're all set, show the control container now */ +container.ariaHidden = 'false'; document.getElementById('layer-topowebb_nedtonad').onchange = function(event) { const layer = event.target.checked ? 'topowebb_nedtonad' : 'topowebb'; @@ -5,234 +5,214 @@ html, body { margin: 0; height: 100%; - --ol-partial-background-color: rgba(255, 255, 255, .9); - --ol-background-color: var(--bs-body-bg); --ol-foreground-color: var(--bs-body-color); - --menu-factor-size: 1.75; - --menu-border-width: 2px; - --menu-border-radius: 4px; - --menu-border-color: var(--ol-subtle-background-color); - --menu-button-size: 1.75em; - --menu-spacing: .5em; - --menu-spacing-interline: .25em; -} -.modal { - --bs-modal-border-width: var(--menu-border-width); - --bs-border-radius-lg: var(--menu-border-radius); - --bs-modal-border-radius: var(--menu-border-radius); - --bs-modal-bg: var(--bs-body-bg); - --bs-modal-color: var(--bs-body-color); -} -#modal-info .modal-header { - border-bottom: none; - --bs-modal-header-border-width: 0; -} -.btn-close { - --bs-btn-close-focus-shadow: none; -} -@media screen and (max-width: 500px) { - html, body { - --menu-factor-size: 1; - --menu-border-width: 1px; - --menu-border-radius: 2px; - } + --ol-background-color: var(--bs-body-bg); + + /* highlight non-bootstrapy style */ + --ol-accent-background-color: red; + --ol-subtle-background-color: red; + --ol-partial-background-color: red; + --ol-subtle-foreground-color: red; + --ol-brand-color: red; } + + #map { position: absolute; top: 0; bottom: 0; width: 100%; } -#modal-info.modal { - --link-dark-rgb: var(--bs-modal-color); - --bs-emphasis-color-rgb: var(--bs-modal-color); -} -.form-check-input:focus:not(:focus-visible, :hover) { - box-shadow: none; -} -.ol-control button:focus:not(:focus-visible, :hover) { - color: var(--ol-subtle-foreground-color); - text-decoration: none; - outline: none; -} -#map-menu, .ol-zoom, .ol-zoomslider { - font-size: calc(100% * var(--menu-factor-size)); -} -#map-menu, .ol-control { - background-color: transparent; -} -#map-menu[aria-hidden="true"], -#layer-selection-panel[aria-hidden="true"] { - display: none; + +#map-control-container { + --map-container-padding: 1rem; + position: absolute; + padding: var(--map-container-padding); + display: flex; + justify-content: flex-end; + width: 100%; + height: 100%; } -.ol-control button, -#map-menu button, -#layer-selection-panel { - border: var(--menu-border-width) solid var(--menu-border-color); - background-color: var(--ol-background-color); - background-clip: padding-box; - border-radius: var(--menu-border-radius); - color: var(--ol-subtle-foreground-color); +@media screen and (max-width: 576px) { + #map-control-container { + --map-container-padding: .5rem; + } } -.ol-control button, #map-menu button { - width: var(--menu-button-size); - height: var(--menu-button-size); - font-size: inherit; - text-align: center; - font-weight: bold; - text-decoration: none; + +#zoom-control { display: block; - line-height: .4em; - padding: 0; -} -.ol-control button:hover, -.ol-control button:focus, -#map-menu button:hover, -#map-menu button:focus { - outline: none; -} -.ol-control button:hover, -.ol-control button:focus-visible, -#map-menu button:hover, -#map-menu button:focus-visible { - --menu-border-color: var(--ol-subtle-foreground-color); - color: var(--ol-foreground-color); -} -.ol-zoom > .ol-zoom-in, -.ol-zoom > .ol-zoom-out, -.ol-zoomslider { - --menu-button-size: 1.375em; -} -.ol-zoom > .ol-zoom-in, -.ol-zoom > .ol-zoom-out { - margin: 0; - height: calc(var(--menu-button-size) - var(--menu-border-width) * .5) !important; + margin-right: auto; } -.ol-zoom > button.ol-zoom-in:hover, -.ol-zoom > button.ol-zoom-in:focus-visible, -.ol-zoom > button.ol-zoom-out:hover, -.ol-zoom > button.ol-zoom-out:focus-visible { +#zoom-control .ol-zoom { position: relative; - z-index: 1; - height: var(--menu-button-size) !important; -} -.ol-zoom > .ol-zoom-in { - border-radius: var(--menu-border-radius) var(--menu-border-radius) 0 0; - border-bottom-width: calc(var(--menu-border-width) * .5); -} -.ol-zoom > button.ol-zoom-in:hover, -.ol-zoom > button.ol-zoom-in:focus-visible { - border-bottom-width: var(--menu-border-width); - margin-bottom: calc(-.5 * var(--menu-border-width)); -} -.ol-zoom > .ol-zoom-out { - border-radius: 0 0 var(--menu-border-radius) var(--menu-border-radius); - border-top-width: calc(var(--menu-border-width) * .5); -} -.ol-zoom > button.ol-zoom-out:hover, -.ol-zoom > button.ol-zoom-out:focus-visible { - border-top-width: var(--menu-border-width); - margin-top: calc(-.5 * var(--menu-border-width)); -} -@media screen and (max-height: 500px) { - .ol-zoomslider { - display: none; - } -} -.ol-zoomslider { - --ol-zoomslider-thumb-height: 15px; - --ol-zoomslider-margin: 14px; -} -@media screen and (max-width: 500px) { - .ol-zoomslider { - --ol-zoomslider-thumb-height: 10px; - --ol-zoomslider-margin: 8px; - } -} -.ol-zoomslider, button.ol-zoomslider-thumb { - --menu-border-width2: 1px; + display: block; + width: revert; + top: auto; + left: auto; } -.ol-zoomslider { - background-color: rgba(255, 255, 255, .7); - background-color: rgb(from var(--ol-partial-background-color) r g b / .7); - border-radius: var(--menu-border-radius); - border: var(--menu-border-width) solid var(--menu-border-color); - width: var(--menu-button-size); - padding: calc(var(--ol-zoomslider-margin) + var(--ol-zoomslider-thumb-height)*.3) 0; - left: var(--menu-spacing); - top: calc(var(--menu-spacing) + var(--menu-button-size)*2 - var(--menu-border-width) + var(--menu-spacing)); +#zoom-control .ol-zoomslider { + margin-top: .5rem; + position: relative; + display: block; + width: revert; + top: auto; + left: auto; + padding: 10px 0; + + background-color: var(--bs-body-bg); + border-radius: var(--bs-modal-border-radius); + border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); + overflow-y: hidden; + z-index: 0; } -.ol-zoomslider::after { +#zoom-control .ol-zoomslider::after { content: ""; position: absolute; - top: var(--ol-zoomslider-margin); - left: var(--ol-zoomslider-margin); - right: var(--ol-zoomslider-margin); - bottom: var(--ol-zoomslider-margin); - background-color: var(--ol-subtle-background-color); - border-radius: calc((var(--menu-button-size) - var(--menu-border-width))*.5 - var(--ol-zoomslider-margin)); - border: var(--menu-border-width2) solid var(--menu-border-color); + top: 3%; + left: calc(50% - 3px); + width: 6px; + height: 94%; + background-color: RGBA(211, 212, 213, .4); + border-radius: 5px; + border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); cursor: pointer; } -.ol-zoomslider:hover { - background-color: var(--ol-partial-background-color); -} -.ol-zoomslider button.ol-zoomslider-thumb { - z-index: 1; - height: var(--ol-zoomslider-thumb-height); - width: calc((var(--menu-button-size) - 2*var(--menu-border-width))*.85); +#zoom-control button.ol-zoomslider-thumb { + z-index: 10; + height: 10px; + width: 80%; margin: 0 auto; - border: var(--menu-border-width2) solid var(--menu-border-color); + padding: 0; } + .ol-scale-line { - position: absolute; - bottom: calc(var(--menu-spacing) * var(--menu-factor-size)); - left: calc(var(--menu-spacing) * var(--menu-factor-size)); - border: var(--menu-border-width) solid var(--menu-border-color); - background-color: var(--ol-partial-background-color); + display: block; + width: revert; + height: revert; + top: auto; + bottom: var(--map-container-padding); + left: var(--map-container-padding); + + padding: .5rem; + background-color: var(--bs-modal-bg); background-clip: padding-box; - border-radius: var(--menu-border-radius); - padding: calc(.5ex * var(--menu-factor-size)); -} -.ol-scale-line .ol-scale-line-inner { - font-size: 80%; + border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); + border-radius: var(--bs-modal-border-radius); +} +.ol-scale-line-inner { + border: 1px solid var(--bs-body-color); + border-top: none; + color: var(--bs-body-color); + font-size: small; margin: 0; } -#map-menu { - position: absolute; - right: var(--menu-spacing); - top: var(--menu-spacing); - margin: 0; + +#map-menu, #zoom-control { + position: relative; +} +@media screen and (min-width: 577px) { + #map-menu > .ol-control > button { + font-size: 200%; + } } #map-menu > * { - margin-top: var(--menu-spacing-interline); + margin-top: .5rem; +} +@media screen and (max-width: 576px) { + #map-menu > * { + margin-top: .25rem; + } } #map-menu > *:first-child { margin-top: 0; } + #map-menu > .ol-control { position: relative; inset: initial; } -#map-menu button[aria-expanded="true"] { - background-color: var(--ol-subtle-foreground-color); - color: var(--ol-background-color); +.ol-control { + background: none; + border: none; + outline: none; } -#map-menu button[aria-expanded="true"]:hover, -#map-menu button[aria-expanded="true"]:focus-visible { - background-color: var(--ol-foreground-color); - border-color: var(--ol-foreground-color); +.ol-control button.btn { + --bs-btn-padding-x: 0.5rem; + --bs-btn-padding-y: 0.5rem; + display: block; + margin: 0; + padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x); + width: auto; + height: auto; + font-weight: bold; + text-decoration: none; + font-size: inherit; + text-align: center; + color: var(--bs-btn-color); + background-color: var(--bs-btn-bg); + border-radius: var(--bs-btn-border-radius); + border: var(--bs-btn-border-width) solid var(--bs-btn-border-color); +} +.ol-control button.btn:focus:not(:focus-visible, :hover) { + text-decoration: none; + color: var(--bs-btn-color); + background-color: var(--bs-btn-bg); + border-color: var(--bs-btn-border-color); + outline: none; +} +.ol-control button.btn:hover, +.ol-control button.btn:focus-visible { + text-decoration: none; + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); + outline: none; +} +.btn-light, .btn-dark { + --bs-btn-border-color: var(--bs-btn-hover-border-color); +} + +#map-control-container[aria-hidden="true"], +#layer-selection-panel[aria-hidden="true"] { + display: none; } #layer-selection-panel { - position: absolute; - top: calc(var(--menu-spacing) * var(--menu-factor-size)); - right: calc((var(--menu-spacing) + var(--menu-button-size) + var(--menu-spacing-interline)) * var(--menu-factor-size)); - padding: .75ex; - color: var(--ol-foreground-color); + position: relative; + display: block; + min-width: min-content; + max-width: 35%; + width: revert; + margin-right: 1rem; + font-size: medium; + z-index: 0; + --bs-modal-color: var(--bs-body-color); + --bs-modal-padding: .75rem; +} +@media screen and (max-width: 576px) { + #layer-selection-panel { + max-width: 100%; + margin-right: .5rem; + display: none; + } + #layer-selection-button, + #map-menu #layer-selection-panel, + #map-menu .ol-full-screen { + display: none; + } + #map-menu #info-button { + bottom: 0; + right: 0; + position: absolute; + } } -@media screen and (max-width: 500px) { - #layer-selection-btn { +@media screen and (max-height: 576px) { + #zoom-control .ol-zoomslider { display: none; } } +@media screen and (max-width: 768px) { + #layer-selection-panel { + max-width: 60%; + } +} |