From 0c0488cc79f363a2aaebac14d9edca76faf492fc Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 22 Jan 2024 01:58:37 +0100 Subject: Add ability to grab and move popovers. --- main.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 11 deletions(-) (limited to 'main.js') diff --git a/main.js b/main.js index 4ed491f..051ef5f 100644 --- a/main.js +++ b/main.js @@ -807,9 +807,54 @@ map.addLayer(new VectorTileLayer({ const header = document.createElement('div'); header.classList.add('d-flex'); - const pageNode = document.createElement('div'); - pageNode.classList.add('flex-grow-1', 'pe-4'); - header.appendChild(pageNode); + const headerGrabbingArea = document.createElement('div'); + headerGrabbingArea.classList.add('flex-grow-1', 'grabbing-area', 'pe-2', 'me-2'); + header.appendChild(headerGrabbingArea); + + headerGrabbingArea.onmousedown = function(event) { + if (event.button != 0) { + return; + } + const popoverTip = Popover.getInstance(popup).tip; + pageNode.classList.add('grabbing-area-grabbed'); + + if (!popoverTip.classList.contains('popover-detached')) { + /* detach popover tip */ + popoverTip.classList.add('popover-detached'); + const rect = popoverTip.getBoundingClientRect(); + const maxHeight = document.getElementById('map').getBoundingClientRect().height - 1 - rect.top - + popoverTip.getElementsByClassName('popover-header')[0].getBoundingClientRect().height; + + const style = popoverTip.style; + style.display = 'none'; /* avoid reflows between the following assignments */ + style.position = 'absolute'; + style.transform = ''; + style.inset = `${rect.top}px auto auto ${rect.left}px`; + style.display = ''; + } + + let clientX = event.clientX, clientY = event.clientY; + document.onmousemove = function(event) { + const offsetX = clientX - event.clientX; + const offsetY = clientY - event.clientY; + clientX = event.clientX; + clientY = event.clientY; + popoverTip.style.top = (popoverTip.offsetTop - offsetY).toString() + 'px'; + popoverTip.style.left = (popoverTip.offsetLeft - offsetX).toString() + 'px'; + }; + + document.onmouseup = function(event) { + if (event.button != 0) { + return; + } + pageNode.classList.remove('grabbing-area-grabbed'); + document.onmousemove = null; + document.onmouseup = null; + }; + }; + + const pageNode = document.createElement('h6'); + headerGrabbingArea.appendChild(pageNode); const pageNum = document.createElement('span'); const pageCount = document.createElement('span'); @@ -891,10 +936,10 @@ map.addLayer(new VectorTileLayer({ return; } - /* unclear how many feature we'll find, render prev/next buttons invisible for now */ - pageNode.classList.add('invisible'); - btnPrev.classList.add('invisible', 'disabled'); - btnNext.classList.add('invisible', 'disabled'); + /* unclear how many feature we'll find, don't render prev/next buttons for now */ + pageNode.classList.add('d-none'); + btnPrev.classList.add('d-none', 'disabled'); + btnNext.classList.add('d-none', 'disabled'); map.forEachFeatureAtPixel(event.pixel, function(feature, layer) { const properties = feature.getProperties(); @@ -955,10 +1000,10 @@ map.addLayer(new VectorTileLayer({ pageCount.innerHTML = features.length.toString(); if (features.length == 2) { - /* there are ≥2 features, make prev/pre buttons visible */ - btnNext.classList.remove('invisible', 'disabled'); - btnPrev.classList.remove('invisible'); - pageNode.classList.remove('invisible'); + /* there are ≥2 features, render prev/pre buttons */ + btnNext.classList.remove('d-none', 'disabled'); + btnPrev.classList.remove('d-none'); + pageNode.classList.remove('d-none'); } if (popover === null || popover.tip === null) { -- cgit v1.2.3