aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2024-01-13 15:43:16 +0100
committerGuilhem Moulin <guilhem@fripost.org>2024-01-13 23:49:40 +0100
commitb0d7609c9e386ecdc383f73d59f94f94097b33f1 (patch)
treeb2e2139c27ad97af80a65e1148d7ad6f07c24ef0
parent610d754456a7e4e7c702e60c8d3e0ecf6459d240 (diff)
CSS: Make the feel more bootstrap-y.
-rw-r--r--index.html16
-rw-r--r--main.js123
-rw-r--r--style.css356
3 files changed, 270 insertions, 225 deletions
diff --git a/index.html b/index.html
index bae1dc5..dd4d802 100644
--- a/index.html
+++ b/index.html
@@ -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">
diff --git a/main.js b/main.js
index ff4bd7e..d59adbf 100644
--- a/main.js
+++ b/main.js
@@ -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';
diff --git a/style.css b/style.css
index 8eda3c6..106315e 100644
--- a/style.css
+++ b/style.css
@@ -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%;
+ }
+}