From 7bc2b1dac0ec16f68d82a16214c2cc81125709dc Mon Sep 17 00:00:00 2001 From: Hilore Jain <53331388+hilor05@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:52:13 +0530 Subject: [PATCH 1/4] Implemented two more directions to render tooltip Rrose works very well in solving the auto panning problem but when the tooltip is too big to be rendered in north or south direction, it fails to render tooltip within the viewport. So I implemented two new directions namely east and west apart from the already existing (n, ne, nw, s, se, sw). The tooltip is fixed along the y axis and starts from the top of the view port, the tip of the tooltip, moves according to the point of selection along the y axis. The tooltip is rendered east or west based on the space available. --- leaflet.rrose-src.js | 85 ++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 26 deletions(-) diff --git a/leaflet.rrose-src.js b/leaflet.rrose-src.js index b3ffccf..f7938a8 100644 --- a/leaflet.rrose-src.js +++ b/leaflet.rrose-src.js @@ -20,36 +20,45 @@ L.Rrose = L.Popup.extend({ _initLayout:function () { var prefix = 'leaflet-rrose', container = this._container = L.DomUtil.create('div', prefix + ' ' + this.options.className + ' leaflet-zoom-animated'), - closeButton, wrapper; - - if (this.options.closeButton) { - closeButton = this._closeButton = L.DomUtil.create('a', prefix + '-close-button', container); - closeButton.href = '#close'; - closeButton.innerHTML = '×'; - - L.DomEvent.on(closeButton, 'click', this._onCloseButtonClick, this); - } - + wrapper; // Set the pixel distances from the map edges at which popups are too close and need to be re-oriented. - var x_bound = 80, y_bound = 80; - // Determine the alternate direction to pop up; north mimics Leaflet's default behavior, so we initialize to that. - this.options.position = 'n'; + var x_bound = this.options.width, y_bound = this.options.height; + // tip of the tooltip has side = 15px + // therefore tip_base = 15*sqrt(2)/2 , tip_altitude = sqrt(15^2-(base/2)^2), tip_padding = 20 - tip_altitude + // these are needed for positioning the tooltip properly + + let tip_side = 15; + this.tip_base = tip_side * Math.sqrt(2); + this.tip_altitude = Math.sqrt(Math.pow(tip_side,2)-Math.pow(this.tip_base/2,2)); + this.tip_padding = 20 - this.tip_altitude;// tip container width = 20px + y_bound -= this.tip_padding; + this.options.position = ''; // Then see if the point is too far north... - var y_diff = y_bound - this._map.latLngToContainerPoint(this._latlng).y; - if (y_diff > 0) { - this.options.position = 's' - } + let n_diff = this._map.latLngToContainerPoint(this._latlng).y - y_bound; + let s_diff = (this._map.getSize().y - this._map.latLngToContainerPoint(this._latlng).y)-y_bound; + if (n_diff > 0) { + this.options.position = 'n'; + } else if(s_diff > 0){ + this.options.position = 's'; + } // or too far east... var x_diff = this._map.latLngToContainerPoint(this._latlng).x - (this._map.getSize().x - x_bound); if (x_diff > 0) { - this.options.position += 'w' + this.options.position += 'w'; } else { // or too far west. x_diff = x_bound - this._map.latLngToContainerPoint(this._latlng).x; if (x_diff > 0) { - this.options.position += 'e' + this.options.position += 'e'; } } + // if the tooltip fits neither north nor south, we can move the tip pointer along the y axis and fix the tooltip instead + // this is possible considering the height and width of the tooltip is always less than the height and width of the map respectively + + if(this.options.position == ''){ + //tooltip fits neither north nor south and it is ok to open it both east and west, we set our default to east + this.options.position = 'e'; + } // Create the necessary DOM elements in the correct order. Pure 'n' and 's' conditions need only one class for styling, others need two. if (/s/.test(this.options.position)) { @@ -59,28 +68,45 @@ L.Rrose = L.Popup.extend({ } else { this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container' + ' ' + prefix + '-tip-container-' + this.options.position, container); - wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper' + ' ' + prefix + '-content-wrapper-' + this.options.position, container); + wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper', container); } this._tip = L.DomUtil.create('div', prefix + '-tip' + ' ' + prefix + '-tip-' + this.options.position, this._tipContainer); L.DomEvent.disableClickPropagation(wrapper); this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper); L.DomEvent.on(this._contentNode, 'mousewheel', L.DomEvent.stopPropagation); } - else { + else if (/n/.test(this.options.position)){ if (this.options.position === 'n') { wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper', container); this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container', container); } else { - wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper' + ' ' + prefix + '-content-wrapper-' + this.options.position, container); + wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper', container); this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container' + ' ' + prefix + '-tip-container-' + this.options.position, container); } L.DomEvent.disableClickPropagation(wrapper); this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper); L.DomEvent.on(this._contentNode, 'mousewheel', L.DomEvent.stopPropagation); this._tip = L.DomUtil.create('div', prefix + '-tip' + ' ' + prefix + '-tip-' + this.options.position, this._tipContainer); - } + } else { + if (this.options.position === 'e') { + wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper', container); + this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container' + ' ' + prefix + '-tip-container-' + this.options.position, container); + } else if(this.options.position === 'w'){ + wrapper = this._wrapper = L.DomUtil.create('div', prefix + '-content-wrapper', container); + this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container' + ' ' + prefix + '-tip-container-' + this.options.position, container); + } + this._tip = L.DomUtil.create('div', prefix + '-tip' + ' ' + prefix + '-tip-' + this.options.position, this._tipContainer); + L.DomEvent.disableClickPropagation(wrapper); + this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper); + L.DomEvent.on(this._contentNode, 'mousewheel', L.DomEvent.stopPropagation); + } + if (this.options.closeButton) { + closeButton = this._closeButton = L.DomUtil.create('a', 'leaflet-popup-close-button', container); + closeButton.innerHTML = '×'; + L.DomEvent.on(closeButton, 'click', this._onCloseButtonClick, this); + } }, _updatePosition:function () { @@ -93,9 +119,10 @@ L.Rrose = L.Popup.extend({ } if (/s/.test(this.options.position)) { - this._containerBottom = -this._container.offsetHeight + offset.y - (is3d ? 0 : pos.y); + this._containerBottom = -this._container.offsetHeight + offset.y - (is3d ? 0 : pos.y) + this.tip_padding; + this._closeButton.style.top = "20px"; } else { - this._containerBottom = -offset.y - (is3d ? 0 : pos.y); + this._containerBottom = -offset.y - (is3d ? 0 : pos.y) - this.tip_padding; } if (/e/.test(this.options.position)) { @@ -107,7 +134,13 @@ L.Rrose = L.Popup.extend({ else { this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x + (is3d ? 0 : pos.x); } - + if(this.options.position == 'e' || this.options.position == 'w'){ + //this._containerBottom = -(this._container.offsetHeight/2) + offset.y; + this.tip_base = this.options.position == 'e' ? this.tip_base / 2 * -1 : this.tip_base / 2; + this._containerBottom = -(this._container.offsetHeight-this._map.latLngToContainerPoint(this._latlng).y) + offset.y; + this._containerLeft = this._containerLeft + offset.x - this.tip_base; + this._tipContainer.style.top = this._map.latLngToContainerPoint(this._latlng).y - this.tip_altitude+"px"; + } this._container.style.bottom = this._containerBottom + 'px'; this._container.style.left = this._containerLeft + 'px'; } From 99c39cf8868388b35dd2697dca754403b1bef16b Mon Sep 17 00:00:00 2001 From: Hilore Jain <53331388+hilor05@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:53:53 +0530 Subject: [PATCH 2/4] css added for e-w case --- leaflet.rrose.css | 123 +++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 72 deletions(-) diff --git a/leaflet.rrose.css b/leaflet.rrose.css index 0b178d2..2c3df19 100644 --- a/leaflet.rrose.css +++ b/leaflet.rrose.css @@ -2,16 +2,12 @@ .leaflet-rrose { position: absolute; - text-align: center; } -.leaflet-rrose-content-wrapper { - padding: 1px; - text-align: left; -} - -.leaflet-rrose-content { - margin: 14px 20px; +.leaflet-rrose-content{ + margin: 0px; + min-width: 300px; + line-height: 1.4; } .leaflet-rrose-tip-container { @@ -22,6 +18,28 @@ overflow: hidden; } +.leaflet-rrose-tip-container-e { + margin: 0 auto; + position: absolute; + left: -28px; + top: 50%; + transform: rotate(270deg); + width: 40px; + height: 20px; + overflow: hidden; +} + +.leaflet-rrose-tip-container-w { + margin: 0 auto; + position: absolute; + right: -30px; + top: 50%; + transform: rotate(90deg); + width: 40px; + height: 20px; + overflow: hidden; +} + .leaflet-rrose-tip-container-se, .leaflet-rrose-tip-container-ne { margin-left: 0; } @@ -50,6 +68,18 @@ margin: 11px auto 0; } +.leaflet-rrose-tip-s { + margin: 11px auto 0; +} + +.leaflet-rrose-tip-e { + margin: 11px auto 0; +} + +.leaflet-rrose-tip-w { + margin: 11px auto 0; +} + .leaflet-rrose-tip-se { margin: 11px 11px 11px -8px; overflow: hidden; } @@ -66,74 +96,23 @@ margin: -8px 11px 11px 32px; overflow: hidden; } -a.leaflet-rrose-close-button { - position: absolute; - top: 0; - right: 0; - padding: 4px 5px 0 0; - text-align: center; - width: 18px; - height: 14px; - font: 16px/14px Tahoma, Verdana, sans-serif; - color: #c3c3c3; - text-decoration: none; - font-weight: bold; -} - -a.leaflet-rrose-close-button:hover { - color: #999; -} - -.leaflet-rrose-content p { - margin: 18px 0; -} - -.leaflet-rrose-scrolled { - overflow: auto; - border-bottom: 1px solid #ddd; - border-top: 1px solid #ddd; -} /* Visual appearance */ .leaflet-rrose-content-wrapper, .leaflet-rrose-tip { - background: white; - - box-shadow: 0 3px 10px #888; - -moz-box-shadow: 0 3px 10px #888; - -webkit-box-shadow: 0 3px 14px #999; -} - -.leaflet-rrose-content-wrapper { - -moz-border-radius: 20px; - -webkit-border-radius: 20px; - border-radius: 20px; -} - -.leaflet-rrose-content-wrapper-se { - -moz-border-radius: 0 20px 20px 20px; - -webkit-border-radius: 0 20px 20px 20px; - border-radius: 0 20px 20px 20px; -} - -.leaflet-rrose-content-wrapper-sw { - -moz-border-radius: 20px 0 20px 20px; - -webkit-border-radius: 20px 0 20px 20px; - border-radius: 20px 0 20px 20px; -} - -.leaflet-rrose-content-wrapper-nw, .leaflet-rrose-content-wrapper-w { - -moz-border-radius: 20px 20px 0 20px; - -webkit-border-radius: 20px 20px 0 20px; - border-radius: 20px 20px 0 20px; -} - -.leaflet-rrose-content-wrapper-ne, .leaflet-rrose-content-wrapper-e { - -moz-border-radius: 20px 20px 20px 0; - -webkit-border-radius: 20px 20px 20px 0; - border-radius: 20px 20px 20px 0; + color: #fff; + background: #333; + border-radius: 0px; + opacity: 0.95; + padding: 1px; } -.leaflet-rrose-content { - font: 12px/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif; +a.leaflet-popup-close-button { + font-size: 18px; + margin: 0px; + padding: 6px 0px 0px 0px; + height: 29px; + width: 29px; + color: #fff; + border-left: 1px solid; } From 840170ee07e95c8ac9babc2b25781b34a1da53db Mon Sep 17 00:00:00 2001 From: Hilore Jain <53331388+hilor05@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:15:12 +0530 Subject: [PATCH 3/4] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 410e834..5eaceef 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,11 @@ In your project, drop `leaflet.rrose-src.js` alongside `leaflet-src.js`, `leafle onEachFeature: function(feature,layer){ layer.on('mouseover mousemove', function(e){ - var hover_bubble = new L.Rrose({ offset: new L.Point(0,-10), closeButton: false, autoPan: false }) - .setContent(feature.properties.name) - .setLatLng(e.latlng) - .openOn(rrose_map); - }); + var hover_bubble = new L.Rrose({ offset: new L.Point(0,0), autoPan: false, closeButton: true, height: tooltip_height, width: 303}) + .setContent(getOverlayTooltipHtml(layer.feature)) + .setLatLng(e.latlng) + .openOn(map); + }); layer.on('mouseout', function(e){ rrose_map.closePopup() }); } @@ -34,13 +34,13 @@ onEachFeature: function(feature,layer){ | se s sw | | | | | - | | + | e w | | | | | | ne n nw | ------------------------- ``` - At one point, I had the notion that the tip should be placed alongside the popup when the point was closer to the left or right edge of the map than to the top or bottom. I may revisit this idea in a future version, but in the current version, the tip always appears above or below the popup. In release 0.1.0, corners were subdivided based on which direction predominated, so that values such as 'ese' and 'sse' were calculated and addressed in css, although there was no difference visible between them; this behavior has been removed as unnecessary. + Two new directions are added in which the tip moves along side based on the point of selection in the map. The tooltip is fixed starting from the top of the view port while the tip moves.The tooltip is opened in east or west based on space available. - By default, orientation switching occurs when the point is closer than 80 pixels to the borders of your map. Changing the values of ```x_bound``` & ```y_bound``` will alter this behavior. + The default behavior where orientation switching occurs when the point is closer than 80 pixels to the borders of your map, is changed now and the user can send the width and height of the tooltip in options. From 941a611706c58eeff4428a8e4bc7ffeb2bc11021 Mon Sep 17 00:00:00 2001 From: Hilore Jain <53331388+hilor05@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:20:53 +0530 Subject: [PATCH 4/4] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5eaceef..8471ce3 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,10 @@ In your project, drop `leaflet.rrose-src.js` alongside `leaflet-src.js`, `leafle onEachFeature: function(feature,layer){ layer.on('mouseover mousemove', function(e){ - var hover_bubble = new L.Rrose({ offset: new L.Point(0,0), autoPan: false, closeButton: true, height: tooltip_height, width: 303}) - .setContent(getOverlayTooltipHtml(layer.feature)) + var hover_bubble = new L.Rrose({ offset: new L.Point(0,0), autoPan: false, closeButton: true, height: 343, width: 303}) + .setContent(feature.properties.name) .setLatLng(e.latlng) - .openOn(map); + .openOn(rrose_map); }); layer.on('mouseout', function(e){ rrose_map.closePopup() }); }