├── .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 |
--------------------------------------------------------------------------------