├── .editerconfig ├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── examples └── index.html ├── package.json └── src ├── L.Control.SlideMenu.css └── L.Control.SlideMenu.js /.editerconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Masashi Takeshita 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Leaflet.SlideMenu 2 | ==== 3 | 4 | A simple slide menu for Leaflet. 5 | When you click the menu button and the menu is displayed to slide. 6 | Please set the innerHTML to slide menu. 7 | 8 | 9 | ## Usage 10 | 11 | This control uses [Font Awesome](https://fortawesome.github.io/Font-Awesome/) for the icon by default. To use, include: 12 | 13 | ```html 14 | 15 | ``` 16 | 17 | Include the CSS: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | 24 | Include the JavaScript: 25 | 26 | ```html 27 | 28 | ``` 29 | 30 | 31 | Example usage: 32 | 33 | ```javascript 34 | L.control.slideMenu('

test

').addTo(map); 35 | ``` 36 | 37 | ## Arguments 38 | ```javascript 39 | L.control.slideMenu(innerHTML, options?) 40 | ``` 41 | `innerHTML:` Set the innerHTML in the menu. 42 | `options:` [SlideMenu Options](https://github.com/unbam/Leaflet.SlideMenu/blob/master/README.md#options) 43 | 44 | 45 | ## Options 46 | 47 | `position:` The standard Leaflet.Control position parameter. Defaults to 'topleft' 48 | `menuposition:` Set the position of the slide menu. Defaults to 'topleft' 49 | `width:` Set the width of the slide menu. Defaults to '300px' 50 | `height:` Set the height of the slide menu. Defaults to '100%' 51 | `direction:` Set the direction of the slide menu animation. Defaults to 'horizontal' 52 | `changeperc:` The percentage of total size by one movement. The unit is percent. Defaults to '10' 53 | `delay:` The display of the slide menu set the speed for moving one by "X"px ("X" is calculated from `changeperc`). The unit is milliseconds. Defaults to '10' 54 | `icon:` Set the menu icon for 'Font Awesome' of the slide menu. Defaults to 'fa-bars' 55 | `hidden:` Set the hide of the slide menu. Defaults to 'false' 56 | 57 | 58 | ## Methods 59 | 60 | `setContents(innerHTML):` Set the innerHTML in the menu. Please use here if you do not set the innerHTML to the argument of the slide menu. 61 | 62 | 63 | ## Demo 64 | 65 | [DemoPage](http://unbam.github.io/Leaflet.SlideMenu/) 66 | 67 | 68 | ## License 69 | 70 | MIT 71 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-slidemenu", 3 | "description": "A simple slide menu for Leaflet.", 4 | "main": "src/L.Control.SlideMenu.js", 5 | "authors": [ 6 | "Masashi Takeshita " 7 | ], 8 | "license": "MIT", 9 | "keywords": [ 10 | "leaflet" 11 | ], 12 | "homepage": "https://github.com/unbam/Leaflet.SlideMenu", 13 | "ignore": [ 14 | "**/.*", 15 | "node_modules", 16 | "bower_components" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | Leaflet SlideMenu Demo 10 | 15 | 19 | 23 | 24 | 25 | 56 | 57 | 58 |
59 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-slidemenu", 3 | "version": "0.4.1", 4 | "description": "A simple slide menu for Leaflet.", 5 | "main": "src/L.Control.SlideMenu.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/unbam/Leaflet.SlideMenu.git" 9 | }, 10 | "keywords": [ 11 | "leaflet" 12 | ], 13 | "author": { 14 | "name": "Masashi Takeshita", 15 | "email": "masashibox@gmail.com" 16 | }, 17 | "license": "MIT", 18 | "homepage": "https://github.com/unbam/Leaflet.SlideMenu#readme" 19 | } 20 | -------------------------------------------------------------------------------- /src/L.Control.SlideMenu.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-slidemenu{ 2 | cursor: pointer; 3 | } 4 | 5 | .leaflet-menu{ 6 | position: absolute; 7 | background-color: rgba(255, 255, 255, 255); 8 | overflow: auto; 9 | cursor: default; 10 | z-index: 9999; 11 | box-shadow: #222 -1px -1px 20px 0px; 12 | } 13 | 14 | .leaflet-menu-contents { 15 | padding: 10px; 16 | } 17 | 18 | .leaflet-menu::-webkit-scrollbar{ 19 | width: 7px; 20 | height: 7px; 21 | background: #f2f2f2; 22 | } 23 | 24 | .leaflet-menu::-webkit-scrollbar-thumb{ 25 | border-radius: 2px; 26 | background: #777; 27 | } 28 | 29 | .leaflet-menu-close-button{ 30 | background-color: transparent; 31 | border: none; 32 | font-size: 14pt; 33 | color: #777; 34 | cursor: pointer; 35 | } 36 | 37 | .leaflet-menu-close-button:hover{ 38 | color: #0443a8; 39 | } -------------------------------------------------------------------------------- /src/L.Control.SlideMenu.js: -------------------------------------------------------------------------------- 1 | L.Control.SlideMenu = L.Control.extend({ 2 | options: { 3 | position: 'topleft', 4 | menuposition: 'topleft', // topleft,topright,bottomleft,bottomright 5 | width: '300px', 6 | height: '100%', 7 | direction: 'horizontal', // vertical or horizontal 8 | changeperc: '10', 9 | delay: '10', 10 | icon: 'fa-solid fa-bars', 11 | hidden: false, 12 | icon_close: { 13 | class_up: 'fa fa-chevron-up', 14 | class_down: 'fa fa-chevron-down', 15 | class_left: 'fa fa-chevron-left', 16 | class_right: 'fa fa-chevron-right', 17 | size: '16pt', 18 | color: '#BBCC22' 19 | } 20 | }, 21 | 22 | initialize: function(innerHTML, options){ 23 | L.Util.setOptions(this, options); 24 | this._innerHTML = innerHTML; 25 | this._isLeftPosition = this.options.menuposition == 'topleft' || 26 | this.options.menuposition == 'bottomleft' ? true : false; 27 | this._isTopPosition = this.options.menuposition == 'topleft' || 28 | this.options.menuposition == 'topright' ? true : false; 29 | this._isHorizontal = this.options.direction == 'horizontal' ? true : false; 30 | }, 31 | 32 | onAdd: function(map){ 33 | this._container = L.DomUtil.create('div', 'leaflet-control-slidemenu leaflet-bar leaflet-control'); 34 | var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', this._container); 35 | link.title = 'Menu'; 36 | L.DomUtil.create('span', this.options.icon, link); 37 | 38 | this._menu = L.DomUtil.create('div', 'leaflet-menu', map._container); 39 | 40 | this._menu.style.width = this.options.width; 41 | this._menu.style.height = this.options.height; 42 | 43 | if(this._isHorizontal){ 44 | var frominit = -(parseInt(this.options.width, 10)); 45 | if(this._isLeftPosition){ 46 | this._menu.style.left = '-' + this.options.width; 47 | } 48 | else{ 49 | this._menu.style.right = '-' + this.options.width; 50 | } 51 | 52 | if(this._isTopPosition){ 53 | this._menu.style.top = '0px'; 54 | } 55 | else{ 56 | this._menu.style.bottom = '0px'; 57 | } 58 | } 59 | else{ 60 | var frominit = -(parseInt(this.options.height, 10)); 61 | if(this._isLeftPosition){ 62 | this._menu.style.left = '0px'; 63 | } 64 | else{ 65 | this._menu.style.right = '0px'; 66 | } 67 | 68 | if(this._isTopPosition){ 69 | this._menu.style.top = '-' + this.options.height; 70 | } 71 | else{ 72 | this._menu.style.bottom = '-' + this.options.height; 73 | } 74 | } 75 | 76 | var closeButton = L.DomUtil.create('button', 'leaflet-menu-close-button', this._menu); 77 | 78 | closeButton.style.fontSize = this.options.icon_close.size; 79 | closeButton.style.color = this.options.icon_close.color; 80 | 81 | if(this._isHorizontal){ 82 | if(this._isLeftPosition){ 83 | closeButton.style.float = 'right'; 84 | L.DomUtil.addClass(closeButton, this.options.icon_close.class_left); 85 | } 86 | else{ 87 | closeButton.style.float = 'left'; 88 | L.DomUtil.addClass(closeButton, this.options.icon_close.class_right); 89 | } 90 | } 91 | else{ 92 | if(this._isTopPosition){ 93 | closeButton.style.float = 'right'; 94 | L.DomUtil.addClass(closeButton, this.options.icon_close.class_up); 95 | } 96 | else{ 97 | closeButton.style.float = 'right'; 98 | L.DomUtil.addClass(closeButton, this.options.icon_close.class_down); 99 | } 100 | } 101 | 102 | this._contents = L.DomUtil.create('div', 'leaflet-menu-contents', this._menu); 103 | this._contents.innerHTML = this._innerHTML; 104 | this._contents.style.clear = 'both'; 105 | 106 | if(this._isHorizontal){ 107 | var ispx = this.options.width.slice(-1) == 'x' ? true : false; 108 | var unit = parseInt(this.options.width, 10) * parseInt(this.options.changeperc, 10) / 100; 109 | } 110 | else{ 111 | var ispx = this.options.height.slice(-1) == 'x' ? true : false; 112 | var unit = parseInt(this.options.height, 10) * parseInt(this.options.changeperc, 10) / 100; 113 | } 114 | 115 | L.DomEvent.disableClickPropagation(this._menu); 116 | L.DomEvent 117 | .on(link, 'click', L.DomEvent.stopPropagation) 118 | .on(link, 'click', function(){ 119 | // Open 120 | this._animate(this._menu, frominit, 0, true, ispx, unit); 121 | }, this) 122 | .on(closeButton, 'click', L.DomEvent.stopPropagation) 123 | .on(closeButton, 'click', function(){ 124 | // Close 125 | this._animate(this._menu, 0, frominit, false, ispx, unit); 126 | }, this); 127 | L.DomEvent.on(this._menu, 'mouseover', function(){ 128 | map.scrollWheelZoom.disable(); 129 | }); 130 | L.DomEvent.on(this._menu, 'mouseout', function(){ 131 | map.scrollWheelZoom.enable(); 132 | }); 133 | 134 | if(this.options.hidden){ 135 | this.hide(); 136 | } 137 | 138 | return this._container; 139 | }, 140 | 141 | onRemove: function(map){ 142 | //Remove sliding menu from DOM 143 | map._container.removeChild(this._menu); 144 | delete this._menu; 145 | }, 146 | 147 | setContents: function(innerHTML){ 148 | this._innerHTML = innerHTML; 149 | this._contents.innerHTML = this._innerHTML; 150 | }, 151 | 152 | _animate: function(menu, from, to, isOpen, ispx, unit){ 153 | if(this._isHorizontal){ 154 | if(this._isLeftPosition){ 155 | menu.style.left = from + (ispx ? 'px' : '%'); 156 | } 157 | else{ 158 | menu.style.right = from + (ispx ? 'px' : '%'); 159 | } 160 | } 161 | else{ 162 | if(this._isTopPosition){ 163 | menu.style.top = from + (ispx ? 'px' : '%'); 164 | } 165 | else{ 166 | menu.style.bottom = from + (ispx ? 'px' : '%'); 167 | } 168 | } 169 | 170 | if(from != to){ 171 | setTimeout(function(slideMenu){ 172 | var value = isOpen ? from + unit : from - unit; 173 | slideMenu._animate(slideMenu._menu, value, to, isOpen, ispx, unit); 174 | }, parseInt(this.options.delay), this); 175 | } 176 | else{ 177 | return; 178 | } 179 | }, 180 | 181 | hide: function () { 182 | this._container.style.display = 'none'; 183 | }, 184 | 185 | show: function () { 186 | this._container.style.display = 'inherit'; 187 | } 188 | }); 189 | 190 | L.control.slideMenu = function(innerHTML, options) { 191 | return new L.Control.SlideMenu(innerHTML, options); 192 | }; 193 | --------------------------------------------------------------------------------