Skip to content

Commit

Permalink
feat: map controls
Browse files Browse the repository at this point in the history
  • Loading branch information
turban committed Jan 28, 2020
1 parent 49e3d2c commit cacd51e
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 125 deletions.
4 changes: 4 additions & 0 deletions src/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export class MapGL extends Evented {
if (!layer.isOnMap()) {
await layer.addTo(this)

this.fire('layeradd', this._layers)

// Layer is removed while being created
if (!this.hasLayer(layer)) {
this.removeLayer(layer)
Expand All @@ -112,6 +114,8 @@ export class MapGL extends Evented {
}

this._layers = this._layers.filter(l => l !== layer)

this.fire('layerremove', this._layers)
}

remove() {
Expand Down
12 changes: 12 additions & 0 deletions src/controls/FitBounds.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class FitBoundsControl {
addTo(map) {
this._map = map
map.getMapGL().addControl(this)

map.on('layeradd', this.onLayerChange)
map.on('layerremove', this.onLayerChange)
}

onAdd() {
Expand All @@ -38,6 +41,9 @@ class FitBoundsControl {
}

onRemove() {
this._map.on('layeradd', this.onLayerChange)
this._map.on('layerremove', this.onLayerChange)

this._container.removeEventListener('click', this.onClick)
this._container.parentNode.removeChild(this._container)

Expand All @@ -54,6 +60,12 @@ class FitBoundsControl {
this._map.fitBounds(bounds)
}
}

onLayerChange = () => {
this._container.style.display = this._map.getLayersBounds()
? 'block'
: 'none'
}
}

export default FitBoundsControl
25 changes: 3 additions & 22 deletions src/controls/Measure.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
import turfLength from '@turf/length'
import turfArea from '@turf/area'
import bbox from '@turf/bbox'
import { createElement } from '../utils/dom'
import { twoDecimals, kmToMiles } from '../utils/numbers'
import './Measure.css'

// Inspired by https://github.com/ljagis/leaflet-measure

const twoDecimals = value => (Math.round(value * 100) / 100).toLocaleString()

const kmToMiles = value => value * 0.621371192

const createElement = (element, className, text, appendTo) => {
const el = document.createElement(element)

if (className) {
el.className = className
}

if (text) {
el.innerText = text
}

if (appendTo) {
appendTo.appendChild(el)
}

return el
}

// TODO: Proper clean-up on remove
class MeasureControl {
constructor() {
this._isActive = false
Expand Down
214 changes: 112 additions & 102 deletions src/controls/Search.css
Original file line number Diff line number Diff line change
@@ -1,90 +1,95 @@
/* Basics */
.mapboxgl-ctrl-generic-geocoder,
.mapboxgl-ctrl-generic-geocoder *,
.mapboxgl-ctrl-generic-geocoder *:after,
.mapboxgl-ctrl-generic-geocoder *:before {
.dhis2-maps-ctrl-search,
.dhis2-maps-ctrl-search *,
.dhis2-maps-ctrl-search *:after,
.dhis2-maps-ctrl-search *:before {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
.mapboxgl-ctrl-generic-geocoder {
font:18px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
position:relative;
background-color:white;
width:33.3333%;
min-width:400px;
max-width:500px;
z-index:1;
border-radius:3px;
}
.dhis2-maps-ctrl-search {
font: 18px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
position: relative;
background-color: white;
width: 33.3333%;
min-width: 400px;
max-width: 500px;
z-index: 1;
border-radius: 3px;
}

.mapboxgl-ctrl-generic-geocoder input[type='text'] {
font-size:12px;
width:100%;
border:0;
background-color:transparent;
height:40px;
margin:0;
color:rgba(0,0,0,.5);
padding:10px 10px 10px 40px;
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;
}
.mapboxgl-ctrl-generic-geocoder input:focus {
.dhis2-maps-ctrl-search input[type='text'] {
font-size: 12px;
width: 100%;
border: 0;
background-color: transparent;
height:4 0px;
margin: 0;
color: rgba(0,0,0,.5);
padding: 10px 10px 10px 40px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

.dhis2-maps-ctrl-search input:focus {
color:rgba(0,0,0,.75);
outline:0;
box-shadow:none;
outline:thin dotted\8;
}
}

.mapboxgl-ctrl-generic-geocoder .geocoder-icon-search {
position:absolute;
top:10px;
left:10px;
}
.mapboxgl-ctrl-generic-geocoder button {
padding:0;
margin:0;
background-color:#fff;
border:none;
cursor:pointer;
}
.mapboxgl-ctrl-generic-geocoder .geocoder-pin-right * {
background-color:#fff;
z-index:2;
position:absolute;
right:10px;
top:10px;
display:none;
}
.dhis2-maps-ctrl-search .geocoder-icon-search {
position:absolute;
top:10px;
left:10px;
}

.mapboxgl-ctrl-generic-geocoder,
.mapboxgl-ctrl-generic-geocoder ul {
box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
}
.dhis2-maps-ctrl-search button {
padding:0;
margin:0;
background-color:#fff;
border:none;
cursor:pointer;
}

.dhis2-maps-ctrl-search .geocoder-pin-right * {
background-color:#fff;
z-index:2;
position:absolute;
right:10px;
top:10px;
display:none;
}

.dhis2-maps-ctrl-search,
.dhis2-maps-ctrl-search ul {
box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
}

/* Suggestions */
.mapboxgl-ctrl-generic-geocoder ul {
background-color:#fff;
border-radius: 0 0 3px 3px;
left:0;
list-style:none;
margin:0;
padding:0;
position:absolute;
width:100%;
top:100%;
z-index:1000;
overflow:hidden;
font-size:12px;
}
.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl-generic-geocoder ul,
.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-generic-geocoder ul {
.dhis2-maps-ctrl-search ul {
background-color:#fff;
border-radius: 0 0 3px 3px;
left:0;
list-style:none;
margin:0;
padding:0;
position:absolute;
width:100%;
top:100%;
z-index:1000;
overflow:hidden;
font-size:12px;
}

.mapboxgl-ctrl-bottom-left .dhis2-maps-ctrl-search ul,
.mapboxgl-ctrl-bottom-right .dhis2-maps-ctrl-search ul {
top:auto;
bottom:100%;
}
.mapboxgl-ctrl-generic-geocoder ul > li > a {
}

.dhis2-maps-ctrl-search ul > li > a {
clear:both;
cursor:default;
display:block;
Expand All @@ -95,20 +100,23 @@
white-space:nowrap;
border-bottom:1px solid rgba(0,0,0,0.1);
color:#404040;
}
.mapboxgl-ctrl-generic-geocoder ul > li:last-child > a { border-bottom:none; }
.mapboxgl-ctrl-generic-geocoder ul > li > a:hover {
color:#202020;
background-color:#f3f3f3;
text-decoration:none;
cursor:pointer;
}
.mapboxgl-ctrl-generic-geocoder ul > li.active > a {
color:#202020;
background-color:#e3e3e3;
text-decoration:none;
cursor:pointer;
}
}

.dhis2-maps-ctrl-search ul > li:last-child > a { border-bottom:none; }

.dhis2-maps-ctrl-search ul > li > a:hover {
color:#202020;
background-color:#f3f3f3;
text-decoration:none;
cursor:pointer;
}

.dhis2-maps-ctrl-search ul > li.active > a {
color:#202020;
background-color:#e3e3e3;
text-decoration:none;
cursor:pointer;
}

@-webkit-keyframes rotate { from { -webkit-transform: rotate(0deg); } to { -webkit-transform: rotate(360deg); } }
@-moz-keyframes rotate { from { -moz-transform: rotate(0deg); } to { -moz-transform: rotate(360deg); } }
Expand All @@ -117,42 +125,40 @@

/* icons */
.geocoder-icon {
display:inline-block;
width:20px;
height:20px;
vertical-align:middle;
speak:none;
background-repeat:no-repeat;
}
.geocoder-icon-search {
display:inline-block;
width:20px;
height:20px;
vertical-align:middle;
background-repeat:no-repeat;
}
.geocoder-icon-search {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgdmVyc2lvbj0iMS4xIj4NCiAgPHBhdGggZD0iTTguNSA0QzYgNCA0IDYgNCA4LjUgNCAxMSA2IDEzIDguNSAxMyA5LjQgMTMgMTAuMiAxMi44IDEwLjggMTIuM0wxMC45IDEyLjMgMTQuMyAxNS43QzE0LjUgMTUuOSAxNC43IDE2IDE1IDE2IDE1LjYgMTYgMTYgMTUuNiAxNiAxNSAxNiAxNC43IDE1LjkgMTQuNSAxNS43IDE0LjNMMTIuMyAxMC45IDEyLjMgMTAuOEMxMi44IDEwLjIgMTMgOS40IDEzIDguNSAxMyA2IDExIDQgOC41IDR6TTguNSA1LjVDMTAuMiA1LjUgMTEuNSA2LjggMTEuNSA4LjUgMTEuNSAxMC4yIDEwLjIgMTEuNSA4LjUgMTEuNSA2LjggMTEuNSA1LjUgMTAuMiA1LjUgOC41IDUuNSA2LjggNi44IDUuNSA4LjUgNS41eiIgZmlsbD0iIzAwMCIvPg0KPC9zdmc+);
}
.geocoder-icon-close {
}
.geocoder-icon-close {
background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgdmVyc2lvbj0iMS4xIiBoZWlnaHQ9IjIwIiB3aWR0aD0iMjAiPg0KICA8cGF0aCBkPSJtNSA1IDAgMS41IDMuNSAzLjUtMy41IDMuNSAwIDEuNSAxLjUgMCAzLjUtMy41IDMuNSAzLjUgMS41IDAgMC0xLjUtMy41LTMuNSAzLjUtMy41IDAtMS41LTEuNSAwLTMuNSAzLjUtMy41LTMuNS0xLjUgMHoiIGZpbGw9IiMwMDAiLz4NCjwvc3ZnPg==);
}
.geocoder-icon-loading {
}
.geocoder-icon-loading {
background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxwYXRoIGQ9Im0xMCAyIDAgMy4zYzIuNiAwIDQuNyAyLjEgNC43IDQuN2wzLjMgMGMwLTQuNC0zLjYtOC04LTh6IiBmaWxsPSIjMDAwIi8+PHBhdGggZD0iTTEwIDJDNi44IDIgMy43IDQuMSAyLjYgNy4xIDEuNCAxMCAyLjEgMTMuNiA0LjUgMTUuOGMyLjQgMi40IDYuNCAyLjkgOS40IDEuMiAyLjUtMS40IDQuMi00LjIgNC4yLTctMS4xIDAtMi4yIDAtMy4zIDAgMC4xIDIuMi0xLjcgNC4zLTMuOCA0LjZDOC43IDE1IDYuNCAxMy44IDUuNyAxMS43IDQuOCA5LjcgNS42IDcuMSA3LjYgNiA4LjMgNS42IDkuMSA1LjMgMTAgNS4zYzAtMS4xIDAtMi4yIDAtMy4zeiIgc3R5bGU9ImZpbGw6IzAwMDtvcGFjaXR5OjAuMiIvPjwvc3ZnPg==);
-webkit-animation: rotate 400ms linear infinite;
-moz-animation: rotate 400ms linear infinite;
-ms-animation: rotate 400ms linear infinite;
animation: rotate 400ms linear infinite;
}

}

/* CUSTOM */

.mapboxgl-ctrl-generic-geocoder input[type='text'] {
.dhis2-maps-ctrl-search input[type='text'] {
height: 30px;
padding-left: 35px;
}

.mapboxgl-ctrl-generic-geocoder .geocoder-icon-search {
.dhis2-maps-ctrl-search .geocoder-icon-search {
top: 3px;
left: 3px;
background-size: 26px 26px;
}

.mapboxgl-ctrl-generic-geocoder .geocoder-pin-right * {
.dhis2-maps-ctrl-search .geocoder-pin-right * {
top: 5px;
right: 5px;
}
Expand All @@ -170,3 +176,7 @@
.dhis2-maps-ctrl-search-collapsed .suggestions-wrapper {
display: none;
}

.dhis2-maps-ctrl-search-collapsed:hover {
background-color: #f5f5f5;
}
2 changes: 1 addition & 1 deletion src/controls/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class SearchControl {
const label = map._getUIString('SearchControl.SearchForPlace')

const el = (this.container = document.createElement('div'))
el.className = 'mapboxgl-ctrl-generic-geocoder mapboxgl-ctrl'
el.className = 'mapboxgl-ctrl dhis2-maps-ctrl-search'

const icon = document.createElement('span')
icon.className = 'geocoder-icon geocoder-icon-search'
Expand Down
17 changes: 17 additions & 0 deletions src/utils/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const createElement = (element, className, text, appendTo) => {
const el = document.createElement(element)

if (className) {
el.className = className
}

if (text) {
el.innerText = text
}

if (appendTo) {
appendTo.appendChild(el)
}

return el
}
4 changes: 4 additions & 0 deletions src/utils/numbers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const twoDecimals = value =>
(Math.round(value * 100) / 100).toLocaleString()

export const kmToMiles = value => value * 0.621371192

0 comments on commit cacd51e

Please sign in to comment.