leaflet-with-dashoffset-canvas-fix 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2191 -0
- package/LICENSE +26 -0
- package/README.md +3 -0
- package/package.json +149 -0
- package/src/Leaflet.js +24 -0
- package/src/control/Control.Attribution.js +148 -0
- package/src/control/Control.Layers.js +443 -0
- package/src/control/Control.Scale.js +132 -0
- package/src/control/Control.Zoom.js +146 -0
- package/src/control/Control.js +174 -0
- package/src/control/index.js +17 -0
- package/src/core/Browser.js +220 -0
- package/src/core/Class.js +135 -0
- package/src/core/Events.js +344 -0
- package/src/core/Handler.js +57 -0
- package/src/core/Util.js +241 -0
- package/src/core/index.js +15 -0
- package/src/dom/DomEvent.DoubleTap.js +91 -0
- package/src/dom/DomEvent.Pointer.js +97 -0
- package/src/dom/DomEvent.js +315 -0
- package/src/dom/DomUtil.js +349 -0
- package/src/dom/Draggable.js +220 -0
- package/src/dom/PosAnimation.js +113 -0
- package/src/dom/index.js +9 -0
- package/src/geo/LatLng.js +137 -0
- package/src/geo/LatLngBounds.js +251 -0
- package/src/geo/crs/CRS.EPSG3395.js +20 -0
- package/src/geo/crs/CRS.EPSG3857.js +27 -0
- package/src/geo/crs/CRS.EPSG4326.js +23 -0
- package/src/geo/crs/CRS.Earth.js +33 -0
- package/src/geo/crs/CRS.Simple.js +36 -0
- package/src/geo/crs/CRS.js +139 -0
- package/src/geo/crs/index.js +15 -0
- package/src/geo/index.js +7 -0
- package/src/geo/projection/Projection.LonLat.js +28 -0
- package/src/geo/projection/Projection.Mercator.js +49 -0
- package/src/geo/projection/Projection.SphericalMercator.js +44 -0
- package/src/geo/projection/index.js +26 -0
- package/src/geometry/Bounds.js +219 -0
- package/src/geometry/LineUtil.js +306 -0
- package/src/geometry/Point.js +222 -0
- package/src/geometry/PolyUtil.js +129 -0
- package/src/geometry/Transformation.js +79 -0
- package/src/geometry/index.js +8 -0
- package/src/images/layers.svg +1 -0
- package/src/images/logo.svg +1 -0
- package/src/images/marker.svg +1 -0
- package/src/layer/DivOverlay.js +348 -0
- package/src/layer/FeatureGroup.js +94 -0
- package/src/layer/GeoJSON.js +452 -0
- package/src/layer/ImageOverlay.js +270 -0
- package/src/layer/Layer.js +275 -0
- package/src/layer/LayerGroup.js +159 -0
- package/src/layer/Popup.js +506 -0
- package/src/layer/SVGOverlay.js +50 -0
- package/src/layer/Tooltip.js +444 -0
- package/src/layer/VideoOverlay.js +106 -0
- package/src/layer/index.js +24 -0
- package/src/layer/marker/DivIcon.js +74 -0
- package/src/layer/marker/Icon.Default.js +66 -0
- package/src/layer/marker/Icon.js +165 -0
- package/src/layer/marker/Marker.Drag.js +161 -0
- package/src/layer/marker/Marker.js +419 -0
- package/src/layer/marker/index.js +8 -0
- package/src/layer/tile/GridLayer.js +923 -0
- package/src/layer/tile/TileLayer.WMS.js +137 -0
- package/src/layer/tile/TileLayer.js +289 -0
- package/src/layer/tile/index.js +6 -0
- package/src/layer/vector/Canvas.js +493 -0
- package/src/layer/vector/Circle.js +113 -0
- package/src/layer/vector/CircleMarker.js +109 -0
- package/src/layer/vector/Path.js +148 -0
- package/src/layer/vector/Polygon.js +159 -0
- package/src/layer/vector/Polyline.js +307 -0
- package/src/layer/vector/Rectangle.js +57 -0
- package/src/layer/vector/Renderer.getRenderer.js +45 -0
- package/src/layer/vector/Renderer.js +133 -0
- package/src/layer/vector/SVG.Util.js +39 -0
- package/src/layer/vector/SVG.VML.js +144 -0
- package/src/layer/vector/SVG.js +207 -0
- package/src/layer/vector/index.js +14 -0
- package/src/map/Map.js +1751 -0
- package/src/map/handler/Map.BoxZoom.js +152 -0
- package/src/map/handler/Map.DoubleClickZoom.js +55 -0
- package/src/map/handler/Map.Drag.js +235 -0
- package/src/map/handler/Map.Keyboard.js +183 -0
- package/src/map/handler/Map.ScrollWheelZoom.js +91 -0
- package/src/map/handler/Map.TapHold.js +102 -0
- package/src/map/handler/Map.TouchZoom.js +130 -0
- package/src/map/index.js +17 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import {Map} from '../Map';
|
|
2
|
+
import {Handler} from '../../core/Handler';
|
|
3
|
+
import * as Util from '../../core/Util';
|
|
4
|
+
import * as DomUtil from '../../dom/DomUtil';
|
|
5
|
+
import * as DomEvent from '../../dom/DomEvent';
|
|
6
|
+
import {LatLngBounds} from '../../geo/LatLngBounds';
|
|
7
|
+
import {Bounds} from '../../geometry/Bounds';
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map
|
|
11
|
+
* (zoom to a selected bounding box), enabled by default.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// @namespace Map
|
|
15
|
+
// @section Interaction Options
|
|
16
|
+
Map.mergeOptions({
|
|
17
|
+
// @option boxZoom: Boolean = true
|
|
18
|
+
// Whether the map can be zoomed to a rectangular area specified by
|
|
19
|
+
// dragging the mouse while pressing the shift key.
|
|
20
|
+
boxZoom: true
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export var BoxZoom = Handler.extend({
|
|
24
|
+
initialize: function (map) {
|
|
25
|
+
this._map = map;
|
|
26
|
+
this._container = map._container;
|
|
27
|
+
this._pane = map._panes.overlayPane;
|
|
28
|
+
this._resetStateTimeout = 0;
|
|
29
|
+
map.on('unload', this._destroy, this);
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
addHooks: function () {
|
|
33
|
+
DomEvent.on(this._container, 'mousedown', this._onMouseDown, this);
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
removeHooks: function () {
|
|
37
|
+
DomEvent.off(this._container, 'mousedown', this._onMouseDown, this);
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
moved: function () {
|
|
41
|
+
return this._moved;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
_destroy: function () {
|
|
45
|
+
DomUtil.remove(this._pane);
|
|
46
|
+
delete this._pane;
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
_resetState: function () {
|
|
50
|
+
this._resetStateTimeout = 0;
|
|
51
|
+
this._moved = false;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
_clearDeferredResetState: function () {
|
|
55
|
+
if (this._resetStateTimeout !== 0) {
|
|
56
|
+
clearTimeout(this._resetStateTimeout);
|
|
57
|
+
this._resetStateTimeout = 0;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
_onMouseDown: function (e) {
|
|
62
|
+
if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
|
|
63
|
+
|
|
64
|
+
// Clear the deferred resetState if it hasn't executed yet, otherwise it
|
|
65
|
+
// will interrupt the interaction and orphan a box element in the container.
|
|
66
|
+
this._clearDeferredResetState();
|
|
67
|
+
this._resetState();
|
|
68
|
+
|
|
69
|
+
DomUtil.disableTextSelection();
|
|
70
|
+
DomUtil.disableImageDrag();
|
|
71
|
+
|
|
72
|
+
this._startPoint = this._map.mouseEventToContainerPoint(e);
|
|
73
|
+
|
|
74
|
+
DomEvent.on(document, {
|
|
75
|
+
contextmenu: DomEvent.stop,
|
|
76
|
+
mousemove: this._onMouseMove,
|
|
77
|
+
mouseup: this._onMouseUp,
|
|
78
|
+
keydown: this._onKeyDown
|
|
79
|
+
}, this);
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
_onMouseMove: function (e) {
|
|
83
|
+
if (!this._moved) {
|
|
84
|
+
this._moved = true;
|
|
85
|
+
|
|
86
|
+
this._box = DomUtil.create('div', 'leaflet-zoom-box', this._container);
|
|
87
|
+
DomUtil.addClass(this._container, 'leaflet-crosshair');
|
|
88
|
+
|
|
89
|
+
this._map.fire('boxzoomstart');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this._point = this._map.mouseEventToContainerPoint(e);
|
|
93
|
+
|
|
94
|
+
var bounds = new Bounds(this._point, this._startPoint),
|
|
95
|
+
size = bounds.getSize();
|
|
96
|
+
|
|
97
|
+
DomUtil.setPosition(this._box, bounds.min);
|
|
98
|
+
|
|
99
|
+
this._box.style.width = size.x + 'px';
|
|
100
|
+
this._box.style.height = size.y + 'px';
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
_finish: function () {
|
|
104
|
+
if (this._moved) {
|
|
105
|
+
DomUtil.remove(this._box);
|
|
106
|
+
DomUtil.removeClass(this._container, 'leaflet-crosshair');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
DomUtil.enableTextSelection();
|
|
110
|
+
DomUtil.enableImageDrag();
|
|
111
|
+
|
|
112
|
+
DomEvent.off(document, {
|
|
113
|
+
contextmenu: DomEvent.stop,
|
|
114
|
+
mousemove: this._onMouseMove,
|
|
115
|
+
mouseup: this._onMouseUp,
|
|
116
|
+
keydown: this._onKeyDown
|
|
117
|
+
}, this);
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
_onMouseUp: function (e) {
|
|
121
|
+
if ((e.which !== 1) && (e.button !== 1)) { return; }
|
|
122
|
+
|
|
123
|
+
this._finish();
|
|
124
|
+
|
|
125
|
+
if (!this._moved) { return; }
|
|
126
|
+
// Postpone to next JS tick so internal click event handling
|
|
127
|
+
// still see it as "moved".
|
|
128
|
+
this._clearDeferredResetState();
|
|
129
|
+
this._resetStateTimeout = setTimeout(Util.bind(this._resetState, this), 0);
|
|
130
|
+
|
|
131
|
+
var bounds = new LatLngBounds(
|
|
132
|
+
this._map.containerPointToLatLng(this._startPoint),
|
|
133
|
+
this._map.containerPointToLatLng(this._point));
|
|
134
|
+
|
|
135
|
+
this._map
|
|
136
|
+
.fitBounds(bounds)
|
|
137
|
+
.fire('boxzoomend', {boxZoomBounds: bounds});
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
_onKeyDown: function (e) {
|
|
141
|
+
if (e.keyCode === 27) {
|
|
142
|
+
this._finish();
|
|
143
|
+
this._clearDeferredResetState();
|
|
144
|
+
this._resetState();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// @section Handlers
|
|
150
|
+
// @property boxZoom: Handler
|
|
151
|
+
// Box (shift-drag with mouse) zoom handler.
|
|
152
|
+
Map.addInitHook('addHandler', 'boxZoom', BoxZoom);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {Map} from '../Map';
|
|
2
|
+
import {Handler} from '../../core/Handler';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// @namespace Map
|
|
9
|
+
// @section Interaction Options
|
|
10
|
+
|
|
11
|
+
Map.mergeOptions({
|
|
12
|
+
// @option doubleClickZoom: Boolean|String = true
|
|
13
|
+
// Whether the map can be zoomed in by double clicking on it and
|
|
14
|
+
// zoomed out by double clicking while holding shift. If passed
|
|
15
|
+
// `'center'`, double-click zoom will zoom to the center of the
|
|
16
|
+
// view regardless of where the mouse was.
|
|
17
|
+
doubleClickZoom: true
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export var DoubleClickZoom = Handler.extend({
|
|
21
|
+
addHooks: function () {
|
|
22
|
+
this._map.on('dblclick', this._onDoubleClick, this);
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
removeHooks: function () {
|
|
26
|
+
this._map.off('dblclick', this._onDoubleClick, this);
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
_onDoubleClick: function (e) {
|
|
30
|
+
var map = this._map,
|
|
31
|
+
oldZoom = map.getZoom(),
|
|
32
|
+
delta = map.options.zoomDelta,
|
|
33
|
+
zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta;
|
|
34
|
+
|
|
35
|
+
if (map.options.doubleClickZoom === 'center') {
|
|
36
|
+
map.setZoom(zoom);
|
|
37
|
+
} else {
|
|
38
|
+
map.setZoomAround(e.containerPoint, zoom);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// @section Handlers
|
|
44
|
+
//
|
|
45
|
+
// Map properties include interaction handlers that allow you to control
|
|
46
|
+
// interaction behavior in runtime, enabling or disabling certain features such
|
|
47
|
+
// as dragging or touch zoom (see `Handler` methods). For example:
|
|
48
|
+
//
|
|
49
|
+
// ```js
|
|
50
|
+
// map.doubleClickZoom.disable();
|
|
51
|
+
// ```
|
|
52
|
+
//
|
|
53
|
+
// @property doubleClickZoom: Handler
|
|
54
|
+
// Double click zoom handler.
|
|
55
|
+
Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom);
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import {Map} from '../Map';
|
|
2
|
+
import {Handler} from '../../core/Handler';
|
|
3
|
+
import {Draggable} from '../../dom/Draggable';
|
|
4
|
+
import * as Util from '../../core/Util';
|
|
5
|
+
import * as DomUtil from '../../dom/DomUtil';
|
|
6
|
+
import {toLatLngBounds as latLngBounds} from '../../geo/LatLngBounds';
|
|
7
|
+
import {toBounds} from '../../geometry/Bounds';
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// @namespace Map
|
|
14
|
+
// @section Interaction Options
|
|
15
|
+
Map.mergeOptions({
|
|
16
|
+
// @option dragging: Boolean = true
|
|
17
|
+
// Whether the map is draggable with mouse/touch or not.
|
|
18
|
+
dragging: true,
|
|
19
|
+
|
|
20
|
+
// @section Panning Inertia Options
|
|
21
|
+
// @option inertia: Boolean = *
|
|
22
|
+
// If enabled, panning of the map will have an inertia effect where
|
|
23
|
+
// the map builds momentum while dragging and continues moving in
|
|
24
|
+
// the same direction for some time. Feels especially nice on touch
|
|
25
|
+
// devices. Enabled by default.
|
|
26
|
+
inertia: true,
|
|
27
|
+
|
|
28
|
+
// @option inertiaDeceleration: Number = 3000
|
|
29
|
+
// The rate with which the inertial movement slows down, in pixels/second².
|
|
30
|
+
inertiaDeceleration: 3400, // px/s^2
|
|
31
|
+
|
|
32
|
+
// @option inertiaMaxSpeed: Number = Infinity
|
|
33
|
+
// Max speed of the inertial movement, in pixels/second.
|
|
34
|
+
inertiaMaxSpeed: Infinity, // px/s
|
|
35
|
+
|
|
36
|
+
// @option easeLinearity: Number = 0.2
|
|
37
|
+
easeLinearity: 0.2,
|
|
38
|
+
|
|
39
|
+
// TODO refactor, move to CRS
|
|
40
|
+
// @option worldCopyJump: Boolean = false
|
|
41
|
+
// With this option enabled, the map tracks when you pan to another "copy"
|
|
42
|
+
// of the world and seamlessly jumps to the original one so that all overlays
|
|
43
|
+
// like markers and vector layers are still visible.
|
|
44
|
+
worldCopyJump: false,
|
|
45
|
+
|
|
46
|
+
// @option maxBoundsViscosity: Number = 0.0
|
|
47
|
+
// If `maxBounds` is set, this option will control how solid the bounds
|
|
48
|
+
// are when dragging the map around. The default value of `0.0` allows the
|
|
49
|
+
// user to drag outside the bounds at normal speed, higher values will
|
|
50
|
+
// slow down map dragging outside bounds, and `1.0` makes the bounds fully
|
|
51
|
+
// solid, preventing the user from dragging outside the bounds.
|
|
52
|
+
maxBoundsViscosity: 0.0
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export var Drag = Handler.extend({
|
|
56
|
+
addHooks: function () {
|
|
57
|
+
if (!this._draggable) {
|
|
58
|
+
var map = this._map;
|
|
59
|
+
|
|
60
|
+
this._draggable = new Draggable(map._mapPane, map._container);
|
|
61
|
+
|
|
62
|
+
this._draggable.on({
|
|
63
|
+
dragstart: this._onDragStart,
|
|
64
|
+
drag: this._onDrag,
|
|
65
|
+
dragend: this._onDragEnd
|
|
66
|
+
}, this);
|
|
67
|
+
|
|
68
|
+
this._draggable.on('predrag', this._onPreDragLimit, this);
|
|
69
|
+
if (map.options.worldCopyJump) {
|
|
70
|
+
this._draggable.on('predrag', this._onPreDragWrap, this);
|
|
71
|
+
map.on('zoomend', this._onZoomEnd, this);
|
|
72
|
+
|
|
73
|
+
map.whenReady(this._onZoomEnd, this);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
DomUtil.addClass(this._map._container, 'leaflet-grab leaflet-touch-drag');
|
|
77
|
+
this._draggable.enable();
|
|
78
|
+
this._positions = [];
|
|
79
|
+
this._times = [];
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
removeHooks: function () {
|
|
83
|
+
DomUtil.removeClass(this._map._container, 'leaflet-grab');
|
|
84
|
+
DomUtil.removeClass(this._map._container, 'leaflet-touch-drag');
|
|
85
|
+
this._draggable.disable();
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
moved: function () {
|
|
89
|
+
return this._draggable && this._draggable._moved;
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
moving: function () {
|
|
93
|
+
return this._draggable && this._draggable._moving;
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
_onDragStart: function () {
|
|
97
|
+
var map = this._map;
|
|
98
|
+
|
|
99
|
+
map._stop();
|
|
100
|
+
if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
|
|
101
|
+
var bounds = latLngBounds(this._map.options.maxBounds);
|
|
102
|
+
|
|
103
|
+
this._offsetLimit = toBounds(
|
|
104
|
+
this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
|
|
105
|
+
this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1)
|
|
106
|
+
.add(this._map.getSize()));
|
|
107
|
+
|
|
108
|
+
this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
|
|
109
|
+
} else {
|
|
110
|
+
this._offsetLimit = null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
map
|
|
114
|
+
.fire('movestart')
|
|
115
|
+
.fire('dragstart');
|
|
116
|
+
|
|
117
|
+
if (map.options.inertia) {
|
|
118
|
+
this._positions = [];
|
|
119
|
+
this._times = [];
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
_onDrag: function (e) {
|
|
124
|
+
if (this._map.options.inertia) {
|
|
125
|
+
var time = this._lastTime = +new Date(),
|
|
126
|
+
pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
|
|
127
|
+
|
|
128
|
+
this._positions.push(pos);
|
|
129
|
+
this._times.push(time);
|
|
130
|
+
|
|
131
|
+
this._prunePositions(time);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
this._map
|
|
135
|
+
.fire('move', e)
|
|
136
|
+
.fire('drag', e);
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
_prunePositions: function (time) {
|
|
140
|
+
while (this._positions.length > 1 && time - this._times[0] > 50) {
|
|
141
|
+
this._positions.shift();
|
|
142
|
+
this._times.shift();
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
_onZoomEnd: function () {
|
|
147
|
+
var pxCenter = this._map.getSize().divideBy(2),
|
|
148
|
+
pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
|
|
149
|
+
|
|
150
|
+
this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
|
|
151
|
+
this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
_viscousLimit: function (value, threshold) {
|
|
155
|
+
return value - (value - threshold) * this._viscosity;
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
_onPreDragLimit: function () {
|
|
159
|
+
if (!this._viscosity || !this._offsetLimit) { return; }
|
|
160
|
+
|
|
161
|
+
var offset = this._draggable._newPos.subtract(this._draggable._startPos);
|
|
162
|
+
|
|
163
|
+
var limit = this._offsetLimit;
|
|
164
|
+
if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); }
|
|
165
|
+
if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); }
|
|
166
|
+
if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); }
|
|
167
|
+
if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); }
|
|
168
|
+
|
|
169
|
+
this._draggable._newPos = this._draggable._startPos.add(offset);
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
_onPreDragWrap: function () {
|
|
173
|
+
// TODO refactor to be able to adjust map pane position after zoom
|
|
174
|
+
var worldWidth = this._worldWidth,
|
|
175
|
+
halfWidth = Math.round(worldWidth / 2),
|
|
176
|
+
dx = this._initialWorldOffset,
|
|
177
|
+
x = this._draggable._newPos.x,
|
|
178
|
+
newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
|
|
179
|
+
newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
|
|
180
|
+
newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
|
|
181
|
+
|
|
182
|
+
this._draggable._absPos = this._draggable._newPos.clone();
|
|
183
|
+
this._draggable._newPos.x = newX;
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
_onDragEnd: function (e) {
|
|
187
|
+
var map = this._map,
|
|
188
|
+
options = map.options,
|
|
189
|
+
|
|
190
|
+
noInertia = !options.inertia || e.noInertia || this._times.length < 2;
|
|
191
|
+
|
|
192
|
+
map.fire('dragend', e);
|
|
193
|
+
|
|
194
|
+
if (noInertia) {
|
|
195
|
+
map.fire('moveend');
|
|
196
|
+
|
|
197
|
+
} else {
|
|
198
|
+
this._prunePositions(+new Date());
|
|
199
|
+
|
|
200
|
+
var direction = this._lastPos.subtract(this._positions[0]),
|
|
201
|
+
duration = (this._lastTime - this._times[0]) / 1000,
|
|
202
|
+
ease = options.easeLinearity,
|
|
203
|
+
|
|
204
|
+
speedVector = direction.multiplyBy(ease / duration),
|
|
205
|
+
speed = speedVector.distanceTo([0, 0]),
|
|
206
|
+
|
|
207
|
+
limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
|
|
208
|
+
limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
|
|
209
|
+
|
|
210
|
+
decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
|
|
211
|
+
offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
|
|
212
|
+
|
|
213
|
+
if (!offset.x && !offset.y) {
|
|
214
|
+
map.fire('moveend');
|
|
215
|
+
|
|
216
|
+
} else {
|
|
217
|
+
offset = map._limitOffset(offset, map.options.maxBounds);
|
|
218
|
+
|
|
219
|
+
Util.requestAnimFrame(function () {
|
|
220
|
+
map.panBy(offset, {
|
|
221
|
+
duration: decelerationDuration,
|
|
222
|
+
easeLinearity: ease,
|
|
223
|
+
noMoveStart: true,
|
|
224
|
+
animate: true
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// @section Handlers
|
|
233
|
+
// @property dragging: Handler
|
|
234
|
+
// Map dragging handler (by both mouse and touch).
|
|
235
|
+
Map.addInitHook('addHandler', 'dragging', Drag);
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {Map} from '../Map';
|
|
2
|
+
import {Handler} from '../../core/Handler';
|
|
3
|
+
import {on, off, stop} from '../../dom/DomEvent';
|
|
4
|
+
import {toPoint} from '../../geometry/Point';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// @namespace Map
|
|
12
|
+
// @section Keyboard Navigation Options
|
|
13
|
+
Map.mergeOptions({
|
|
14
|
+
// @option keyboard: Boolean = true
|
|
15
|
+
// Makes the map focusable and allows users to navigate the map with keyboard
|
|
16
|
+
// arrows and `+`/`-` keys.
|
|
17
|
+
keyboard: true,
|
|
18
|
+
|
|
19
|
+
// @option keyboardPanDelta: Number = 80
|
|
20
|
+
// Amount of pixels to pan when pressing an arrow key.
|
|
21
|
+
keyboardPanDelta: 80
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export var Keyboard = Handler.extend({
|
|
25
|
+
|
|
26
|
+
keyCodes: {
|
|
27
|
+
left: [37],
|
|
28
|
+
right: [39],
|
|
29
|
+
down: [40],
|
|
30
|
+
up: [38],
|
|
31
|
+
zoomIn: [187, 107, 61, 171],
|
|
32
|
+
zoomOut: [189, 109, 54, 173]
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
initialize: function (map) {
|
|
36
|
+
this._map = map;
|
|
37
|
+
|
|
38
|
+
this._setPanDelta(map.options.keyboardPanDelta);
|
|
39
|
+
this._setZoomDelta(map.options.zoomDelta);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
addHooks: function () {
|
|
43
|
+
var container = this._map._container;
|
|
44
|
+
|
|
45
|
+
// make the container focusable by tabbing
|
|
46
|
+
if (container.tabIndex <= 0) {
|
|
47
|
+
container.tabIndex = '0';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
on(container, {
|
|
51
|
+
focus: this._onFocus,
|
|
52
|
+
blur: this._onBlur,
|
|
53
|
+
mousedown: this._onMouseDown
|
|
54
|
+
}, this);
|
|
55
|
+
|
|
56
|
+
this._map.on({
|
|
57
|
+
focus: this._addHooks,
|
|
58
|
+
blur: this._removeHooks
|
|
59
|
+
}, this);
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
removeHooks: function () {
|
|
63
|
+
this._removeHooks();
|
|
64
|
+
|
|
65
|
+
off(this._map._container, {
|
|
66
|
+
focus: this._onFocus,
|
|
67
|
+
blur: this._onBlur,
|
|
68
|
+
mousedown: this._onMouseDown
|
|
69
|
+
}, this);
|
|
70
|
+
|
|
71
|
+
this._map.off({
|
|
72
|
+
focus: this._addHooks,
|
|
73
|
+
blur: this._removeHooks
|
|
74
|
+
}, this);
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
_onMouseDown: function () {
|
|
78
|
+
if (this._focused) { return; }
|
|
79
|
+
|
|
80
|
+
var body = document.body,
|
|
81
|
+
docEl = document.documentElement,
|
|
82
|
+
top = body.scrollTop || docEl.scrollTop,
|
|
83
|
+
left = body.scrollLeft || docEl.scrollLeft;
|
|
84
|
+
|
|
85
|
+
this._map._container.focus();
|
|
86
|
+
|
|
87
|
+
window.scrollTo(left, top);
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
_onFocus: function () {
|
|
91
|
+
this._focused = true;
|
|
92
|
+
this._map.fire('focus');
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
_onBlur: function () {
|
|
96
|
+
this._focused = false;
|
|
97
|
+
this._map.fire('blur');
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
_setPanDelta: function (panDelta) {
|
|
101
|
+
var keys = this._panKeys = {},
|
|
102
|
+
codes = this.keyCodes,
|
|
103
|
+
i, len;
|
|
104
|
+
|
|
105
|
+
for (i = 0, len = codes.left.length; i < len; i++) {
|
|
106
|
+
keys[codes.left[i]] = [-1 * panDelta, 0];
|
|
107
|
+
}
|
|
108
|
+
for (i = 0, len = codes.right.length; i < len; i++) {
|
|
109
|
+
keys[codes.right[i]] = [panDelta, 0];
|
|
110
|
+
}
|
|
111
|
+
for (i = 0, len = codes.down.length; i < len; i++) {
|
|
112
|
+
keys[codes.down[i]] = [0, panDelta];
|
|
113
|
+
}
|
|
114
|
+
for (i = 0, len = codes.up.length; i < len; i++) {
|
|
115
|
+
keys[codes.up[i]] = [0, -1 * panDelta];
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
_setZoomDelta: function (zoomDelta) {
|
|
120
|
+
var keys = this._zoomKeys = {},
|
|
121
|
+
codes = this.keyCodes,
|
|
122
|
+
i, len;
|
|
123
|
+
|
|
124
|
+
for (i = 0, len = codes.zoomIn.length; i < len; i++) {
|
|
125
|
+
keys[codes.zoomIn[i]] = zoomDelta;
|
|
126
|
+
}
|
|
127
|
+
for (i = 0, len = codes.zoomOut.length; i < len; i++) {
|
|
128
|
+
keys[codes.zoomOut[i]] = -zoomDelta;
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
_addHooks: function () {
|
|
133
|
+
on(document, 'keydown', this._onKeyDown, this);
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
_removeHooks: function () {
|
|
137
|
+
off(document, 'keydown', this._onKeyDown, this);
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
_onKeyDown: function (e) {
|
|
141
|
+
if (e.altKey || e.ctrlKey || e.metaKey) { return; }
|
|
142
|
+
|
|
143
|
+
var key = e.keyCode,
|
|
144
|
+
map = this._map,
|
|
145
|
+
offset;
|
|
146
|
+
|
|
147
|
+
if (key in this._panKeys) {
|
|
148
|
+
if (!map._panAnim || !map._panAnim._inProgress) {
|
|
149
|
+
offset = this._panKeys[key];
|
|
150
|
+
if (e.shiftKey) {
|
|
151
|
+
offset = toPoint(offset).multiplyBy(3);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (map.options.maxBounds) {
|
|
155
|
+
offset = map._limitOffset(toPoint(offset), map.options.maxBounds);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (map.options.worldCopyJump) {
|
|
159
|
+
var newLatLng = map.wrapLatLng(map.unproject(map.project(map.getCenter()).add(offset)));
|
|
160
|
+
map.panTo(newLatLng);
|
|
161
|
+
} else {
|
|
162
|
+
map.panBy(offset);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} else if (key in this._zoomKeys) {
|
|
166
|
+
map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]);
|
|
167
|
+
|
|
168
|
+
} else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) {
|
|
169
|
+
map.closePopup();
|
|
170
|
+
|
|
171
|
+
} else {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
stop(e);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// @section Handlers
|
|
180
|
+
// @section Handlers
|
|
181
|
+
// @property keyboard: Handler
|
|
182
|
+
// Keyboard navigation handler.
|
|
183
|
+
Map.addInitHook('addHandler', 'keyboard', Keyboard);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {Map} from '../Map';
|
|
2
|
+
import {Handler} from '../../core/Handler';
|
|
3
|
+
import * as DomEvent from '../../dom/DomEvent';
|
|
4
|
+
import * as Util from '../../core/Util';
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// @namespace Map
|
|
11
|
+
// @section Interaction Options
|
|
12
|
+
Map.mergeOptions({
|
|
13
|
+
// @section Mouse wheel options
|
|
14
|
+
// @option scrollWheelZoom: Boolean|String = true
|
|
15
|
+
// Whether the map can be zoomed by using the mouse wheel. If passed `'center'`,
|
|
16
|
+
// it will zoom to the center of the view regardless of where the mouse was.
|
|
17
|
+
scrollWheelZoom: true,
|
|
18
|
+
|
|
19
|
+
// @option wheelDebounceTime: Number = 40
|
|
20
|
+
// Limits the rate at which a wheel can fire (in milliseconds). By default
|
|
21
|
+
// user can't zoom via wheel more often than once per 40 ms.
|
|
22
|
+
wheelDebounceTime: 40,
|
|
23
|
+
|
|
24
|
+
// @option wheelPxPerZoomLevel: Number = 60
|
|
25
|
+
// How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta))
|
|
26
|
+
// mean a change of one full zoom level. Smaller values will make wheel-zooming
|
|
27
|
+
// faster (and vice versa).
|
|
28
|
+
wheelPxPerZoomLevel: 60
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export var ScrollWheelZoom = Handler.extend({
|
|
32
|
+
addHooks: function () {
|
|
33
|
+
DomEvent.on(this._map._container, 'wheel', this._onWheelScroll, this);
|
|
34
|
+
|
|
35
|
+
this._delta = 0;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
removeHooks: function () {
|
|
39
|
+
DomEvent.off(this._map._container, 'wheel', this._onWheelScroll, this);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
_onWheelScroll: function (e) {
|
|
43
|
+
var delta = DomEvent.getWheelDelta(e);
|
|
44
|
+
|
|
45
|
+
var debounce = this._map.options.wheelDebounceTime;
|
|
46
|
+
|
|
47
|
+
this._delta += delta;
|
|
48
|
+
this._lastMousePos = this._map.mouseEventToContainerPoint(e);
|
|
49
|
+
|
|
50
|
+
if (!this._startTime) {
|
|
51
|
+
this._startTime = +new Date();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
var left = Math.max(debounce - (+new Date() - this._startTime), 0);
|
|
55
|
+
|
|
56
|
+
clearTimeout(this._timer);
|
|
57
|
+
this._timer = setTimeout(Util.bind(this._performZoom, this), left);
|
|
58
|
+
|
|
59
|
+
DomEvent.stop(e);
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
_performZoom: function () {
|
|
63
|
+
var map = this._map,
|
|
64
|
+
zoom = map.getZoom(),
|
|
65
|
+
snap = this._map.options.zoomSnap || 0;
|
|
66
|
+
|
|
67
|
+
map._stop(); // stop panning and fly animations if any
|
|
68
|
+
|
|
69
|
+
// map the delta with a sigmoid function to -4..4 range leaning on -1..1
|
|
70
|
+
var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
|
|
71
|
+
d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
|
|
72
|
+
d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
|
|
73
|
+
delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;
|
|
74
|
+
|
|
75
|
+
this._delta = 0;
|
|
76
|
+
this._startTime = null;
|
|
77
|
+
|
|
78
|
+
if (!delta) { return; }
|
|
79
|
+
|
|
80
|
+
if (map.options.scrollWheelZoom === 'center') {
|
|
81
|
+
map.setZoom(zoom + delta);
|
|
82
|
+
} else {
|
|
83
|
+
map.setZoomAround(this._lastMousePos, zoom + delta);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// @section Handlers
|
|
89
|
+
// @property scrollWheelZoom: Handler
|
|
90
|
+
// Scroll wheel zoom handler.
|
|
91
|
+
Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);
|