leaflet-rails 0.4.0.alpha5 → 0.4.0.alpha6
Sign up to get free protection for your applications and to get access to all the features.
@@ -10,13 +10,12 @@ var L, originalL;
|
|
10
10
|
if (typeof exports !== 'undefined') {
|
11
11
|
L = exports;
|
12
12
|
} else {
|
13
|
-
L = {};
|
14
|
-
|
15
13
|
originalL = window.L;
|
14
|
+
L = {};
|
16
15
|
|
17
16
|
L.noConflict = function () {
|
18
17
|
window.L = originalL;
|
19
|
-
return
|
18
|
+
return this;
|
20
19
|
};
|
21
20
|
|
22
21
|
window.L = L;
|
@@ -99,7 +98,7 @@ L.Util = {
|
|
99
98
|
|
100
99
|
limitExecByInterval: function (fn, time, context) {
|
101
100
|
var lock, execOnUnlock;
|
102
|
-
|
101
|
+
|
103
102
|
return function wrapperFn() {
|
104
103
|
var args = arguments;
|
105
104
|
|
@@ -109,10 +108,10 @@ L.Util = {
|
|
109
108
|
}
|
110
109
|
|
111
110
|
lock = true;
|
112
|
-
|
111
|
+
|
113
112
|
setTimeout(function () {
|
114
113
|
lock = false;
|
115
|
-
|
114
|
+
|
116
115
|
if (execOnUnlock) {
|
117
116
|
wrapperFn.apply(context, args);
|
118
117
|
execOnUnlock = false;
|
@@ -292,54 +291,65 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
|
|
292
291
|
(function () {
|
293
292
|
var ua = navigator.userAgent.toLowerCase(),
|
294
293
|
ie = !!window.ActiveXObject,
|
294
|
+
ie6 = ie && !window.XMLHttpRequest,
|
295
295
|
webkit = ua.indexOf("webkit") !== -1,
|
296
|
-
|
296
|
+
gecko = ua.indexOf("gecko") !== -1,
|
297
|
+
opera = window.opera,
|
297
298
|
android = ua.indexOf("android") !== -1,
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
299
|
+
mobile = typeof orientation !== 'undefined' ? true : false,
|
300
|
+
doc = document.documentElement,
|
301
|
+
ie3d = ie && ('transition' in doc.style),
|
302
|
+
webkit3d = webkit && ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()),
|
303
|
+
gecko3d = gecko && ('MozPerspective' in doc.style),
|
304
|
+
opera3d = opera && ('OTransition' in doc.style);
|
303
305
|
|
304
|
-
|
305
|
-
|
306
|
+
var touch = (function () {
|
307
|
+
var startName = 'ontouchstart';
|
306
308
|
|
307
|
-
|
309
|
+
// WebKit, etc
|
310
|
+
if (startName in doc) {
|
311
|
+
return true;
|
312
|
+
}
|
308
313
|
|
309
|
-
|
314
|
+
// Firefox/Gecko
|
315
|
+
var div = document.createElement('div'),
|
316
|
+
supported = false;
|
310
317
|
|
311
|
-
|
312
|
-
|
313
|
-
|
318
|
+
if (!div.setAttribute) {
|
319
|
+
return false;
|
320
|
+
}
|
321
|
+
div.setAttribute(startName, 'return;');
|
314
322
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
startName = 'ontouchstart';
|
323
|
+
if (typeof div[startName] === 'function') {
|
324
|
+
supported = true;
|
325
|
+
}
|
319
326
|
|
320
|
-
|
321
|
-
|
322
|
-
return true;
|
323
|
-
}
|
327
|
+
div.removeAttribute(startName);
|
328
|
+
div = null;
|
324
329
|
|
325
|
-
|
326
|
-
|
330
|
+
return supported;
|
331
|
+
}());
|
327
332
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
333
|
+
L.Browser = {
|
334
|
+
ie: ie,
|
335
|
+
ie6: ie6,
|
336
|
+
webkit: webkit,
|
337
|
+
gecko: gecko,
|
338
|
+
opera: opera,
|
339
|
+
android: android,
|
332
340
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
341
|
+
ie3d: ie3d,
|
342
|
+
webkit3d: webkit3d,
|
343
|
+
gecko3d: gecko3d,
|
344
|
+
opera3d: opera3d,
|
345
|
+
any3d: ie3d || webkit3d || gecko3d || opera3d,
|
337
346
|
|
338
|
-
|
339
|
-
|
347
|
+
mobile: mobile,
|
348
|
+
mobileWebkit: mobile && webkit,
|
349
|
+
mobileWebkit3d: mobile && webkit3d,
|
350
|
+
mobileOpera: mobile && opera,
|
340
351
|
|
341
|
-
|
342
|
-
}())
|
352
|
+
touch: touch
|
343
353
|
};
|
344
354
|
}());
|
345
355
|
|
@@ -622,8 +632,6 @@ L.DomUtil = {
|
|
622
632
|
}
|
623
633
|
},
|
624
634
|
|
625
|
-
//TODO refactor away this ugly translate/position mess
|
626
|
-
|
627
635
|
testProp: function (props) {
|
628
636
|
var style = document.documentElement.style;
|
629
637
|
|
@@ -636,9 +644,15 @@ L.DomUtil = {
|
|
636
644
|
},
|
637
645
|
|
638
646
|
getTranslateString: function (point) {
|
639
|
-
|
640
|
-
|
641
|
-
|
647
|
+
// On webkit browsers (Chrome/Safari/MobileSafari/Android) using translate3d instead of translate
|
648
|
+
// makes animation smoother as it ensures HW accel is used. Firefox 13 doesn't care
|
649
|
+
// (same speed either way), Opera 12 doesn't support translate3d
|
650
|
+
|
651
|
+
var is3d = L.Browser.webkit3d,
|
652
|
+
open = 'translate' + (is3d ? '3d' : '') + '(',
|
653
|
+
close = (is3d ? ',0' : '') + ')';
|
654
|
+
|
655
|
+
return open + point.x + 'px,' + point.y + 'px' + close;
|
642
656
|
},
|
643
657
|
|
644
658
|
getScaleString: function (scale, origin) {
|
@@ -649,11 +663,15 @@ L.DomUtil = {
|
|
649
663
|
return preTranslateStr + scaleStr + postTranslateStr;
|
650
664
|
},
|
651
665
|
|
652
|
-
setPosition: function (el, point) {
|
666
|
+
setPosition: function (el, point, disable3D) {
|
653
667
|
el._leaflet_pos = point;
|
654
|
-
if (L.Browser.
|
668
|
+
if (!disable3D && L.Browser.any3d) {
|
655
669
|
el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point);
|
656
|
-
|
670
|
+
|
671
|
+
// workaround for Android 2/3 stability (https://github.com/CloudMade/Leaflet/issues/69)
|
672
|
+
if (L.Browser.mobileWebkit3d) {
|
673
|
+
el.style.WebkitBackfaceVisibility = 'hidden';
|
674
|
+
}
|
657
675
|
} else {
|
658
676
|
el.style.left = point.x + 'px';
|
659
677
|
el.style.top = point.y + 'px';
|
@@ -667,10 +685,7 @@ L.DomUtil = {
|
|
667
685
|
|
668
686
|
L.Util.extend(L.DomUtil, {
|
669
687
|
TRANSITION: L.DomUtil.testProp(['transition', 'webkitTransition', 'OTransition', 'MozTransition', 'msTransition']),
|
670
|
-
TRANSFORM: L.DomUtil.testProp(['
|
671
|
-
|
672
|
-
TRANSLATE_OPEN: 'translate' + (L.Browser.webkit3d ? '3d(' : '('),
|
673
|
-
TRANSLATE_CLOSE: L.Browser.webkit3d ? ',0)' : ')'
|
688
|
+
TRANSFORM: L.DomUtil.testProp(['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform'])
|
674
689
|
});
|
675
690
|
|
676
691
|
|
@@ -869,12 +884,13 @@ L.Projection.SphericalMercator = {
|
|
869
884
|
return new L.Point(x, y);
|
870
885
|
},
|
871
886
|
|
872
|
-
unproject: function (point
|
887
|
+
unproject: function (point) { // (Point, Boolean) -> LatLng
|
873
888
|
var d = L.LatLng.RAD_TO_DEG,
|
874
889
|
lng = point.x * d,
|
875
890
|
lat = (2 * Math.atan(Math.exp(point.y)) - (Math.PI / 2)) * d;
|
876
891
|
|
877
|
-
|
892
|
+
// TODO refactor LatLng wrapping
|
893
|
+
return new L.LatLng(lat, lng, true);
|
878
894
|
}
|
879
895
|
};
|
880
896
|
|
@@ -885,8 +901,8 @@ L.Projection.LonLat = {
|
|
885
901
|
return new L.Point(latlng.lng, latlng.lat);
|
886
902
|
},
|
887
903
|
|
888
|
-
unproject: function (point
|
889
|
-
return new L.LatLng(point.y, point.x,
|
904
|
+
unproject: function (point) {
|
905
|
+
return new L.LatLng(point.y, point.x, true);
|
890
906
|
}
|
891
907
|
};
|
892
908
|
|
@@ -900,12 +916,11 @@ L.CRS = {
|
|
900
916
|
return this.transformation._transform(projectedPoint, scale);
|
901
917
|
},
|
902
918
|
|
903
|
-
pointToLatLng: function (point, zoom
|
919
|
+
pointToLatLng: function (point, zoom) { // (Point, Number[, Boolean]) -> LatLng
|
904
920
|
var scale = this.scale(zoom),
|
905
921
|
untransformedPoint = this.transformation.untransform(point, scale);
|
906
922
|
|
907
|
-
return this.projection.unproject(untransformedPoint
|
908
|
-
//TODO get rid of 'unbounded' everywhere
|
923
|
+
return this.projection.unproject(untransformedPoint);
|
909
924
|
},
|
910
925
|
|
911
926
|
project: function (latlng) {
|
@@ -963,7 +978,8 @@ L.Map = L.Class.extend({
|
|
963
978
|
*/
|
964
979
|
|
965
980
|
fadeAnimation: L.DomUtil.TRANSITION && !L.Browser.android,
|
966
|
-
trackResize: true
|
981
|
+
trackResize: true,
|
982
|
+
markerZoomAnimation: true
|
967
983
|
},
|
968
984
|
|
969
985
|
initialize: function (id, options) { // (HTMLElement or String, Object)
|
@@ -1180,11 +1196,11 @@ L.Map = L.Class.extend({
|
|
1180
1196
|
|
1181
1197
|
// public methods for getting map state
|
1182
1198
|
|
1183
|
-
getCenter: function (
|
1199
|
+
getCenter: function () { // (Boolean) -> LatLng
|
1184
1200
|
var viewHalf = this.getSize().divideBy(2),
|
1185
1201
|
centerPoint = this._getTopLeftPoint().add(viewHalf);
|
1186
1202
|
|
1187
|
-
return this.unproject(centerPoint, this._zoom
|
1203
|
+
return this.unproject(centerPoint, this._zoom);
|
1188
1204
|
},
|
1189
1205
|
|
1190
1206
|
getZoom: function () {
|
@@ -1272,7 +1288,7 @@ L.Map = L.Class.extend({
|
|
1272
1288
|
getPanes: function () {
|
1273
1289
|
return this._panes;
|
1274
1290
|
},
|
1275
|
-
|
1291
|
+
|
1276
1292
|
getContainer: function () {
|
1277
1293
|
return this._container;
|
1278
1294
|
},
|
@@ -1321,10 +1337,9 @@ L.Map = L.Class.extend({
|
|
1321
1337
|
return this.options.crs.latLngToPoint(latlng, zoom);
|
1322
1338
|
},
|
1323
1339
|
|
1324
|
-
unproject: function (point, zoom
|
1325
|
-
// TODO remove unbounded, making it true all the time?
|
1340
|
+
unproject: function (point, zoom) { // (Point[, Number, Boolean]) -> LatLng
|
1326
1341
|
zoom = typeof zoom === 'undefined' ? this._zoom : zoom;
|
1327
|
-
return this.options.crs.pointToLatLng(point, zoom
|
1342
|
+
return this.options.crs.pointToLatLng(point, zoom);
|
1328
1343
|
},
|
1329
1344
|
|
1330
1345
|
|
@@ -1356,7 +1371,7 @@ L.Map = L.Class.extend({
|
|
1356
1371
|
|
1357
1372
|
var position = L.DomUtil.getStyle(container, 'position');
|
1358
1373
|
|
1359
|
-
if (position !== 'absolute' && position !== 'relative') {
|
1374
|
+
if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {
|
1360
1375
|
container.style.position = 'relative';
|
1361
1376
|
}
|
1362
1377
|
|
@@ -1379,6 +1394,12 @@ L.Map = L.Class.extend({
|
|
1379
1394
|
panes.overlayPane = this._createPane('leaflet-overlay-pane');
|
1380
1395
|
panes.markerPane = this._createPane('leaflet-marker-pane');
|
1381
1396
|
panes.popupPane = this._createPane('leaflet-popup-pane');
|
1397
|
+
|
1398
|
+
if (!this.options.markerZoomAnimation) {
|
1399
|
+
panes.markerPane.className += ' leaflet-zoom-hide';
|
1400
|
+
panes.shadowPane.className += ' leaflet-zoom-hide';
|
1401
|
+
panes.popupPane.className += ' leaflet-zoom-hide';
|
1402
|
+
}
|
1382
1403
|
},
|
1383
1404
|
|
1384
1405
|
_createPane: function (className, container) {
|
@@ -1531,10 +1552,17 @@ L.Map = L.Class.extend({
|
|
1531
1552
|
return this._initialTopLeftPoint.subtract(mapPanePos);
|
1532
1553
|
},
|
1533
1554
|
|
1534
|
-
_getNewTopLeftPoint: function (center) {
|
1555
|
+
_getNewTopLeftPoint: function (center, zoom) {
|
1535
1556
|
var viewHalf = this.getSize().divideBy(2);
|
1536
1557
|
// TODO round on display, not calculation to increase precision?
|
1537
|
-
return this.project(center)._subtract(viewHalf)._round();
|
1558
|
+
return this.project(center, zoom)._subtract(viewHalf)._round();
|
1559
|
+
},
|
1560
|
+
|
1561
|
+
_latLngToNewLayerPoint: function (latlng, newZoom, newCenter) {
|
1562
|
+
var mapPaneOffset = L.DomUtil.getPosition(this._mapPane),
|
1563
|
+
topLeft = this._getNewTopLeftPoint(newCenter, newZoom).add(mapPaneOffset);
|
1564
|
+
|
1565
|
+
return this.project(latlng, newZoom)._round()._subtract(topLeft);
|
1538
1566
|
},
|
1539
1567
|
|
1540
1568
|
_limitZoom: function (zoom) {
|
@@ -1582,7 +1610,7 @@ L.Projection.Mercator = {
|
|
1582
1610
|
return new L.Point(x, y);
|
1583
1611
|
},
|
1584
1612
|
|
1585
|
-
unproject: function (point
|
1613
|
+
unproject: function (point) { // (Point, Boolean) -> LatLng
|
1586
1614
|
var d = L.LatLng.RAD_TO_DEG,
|
1587
1615
|
r = this.R_MAJOR,
|
1588
1616
|
r2 = this.R_MINOR,
|
@@ -1603,7 +1631,7 @@ L.Projection.Mercator = {
|
|
1603
1631
|
phi += dphi;
|
1604
1632
|
}
|
1605
1633
|
|
1606
|
-
return new L.LatLng(phi * d, lng,
|
1634
|
+
return new L.LatLng(phi * d, lng, true);
|
1607
1635
|
}
|
1608
1636
|
};
|
1609
1637
|
|
@@ -1712,6 +1740,19 @@ L.TileLayer = L.Class.extend({
|
|
1712
1740
|
this._map = null;
|
1713
1741
|
},
|
1714
1742
|
|
1743
|
+
bringToFront: function () {
|
1744
|
+
if (this._container) {
|
1745
|
+
this._map._panes.tilePane.appendChild(this._container);
|
1746
|
+
}
|
1747
|
+
},
|
1748
|
+
|
1749
|
+
bringToBack: function () {
|
1750
|
+
var pane = this._map._panes.tilePane;
|
1751
|
+
if (this._container) {
|
1752
|
+
pane.insertBefore(this._container, pane.firstChild);
|
1753
|
+
}
|
1754
|
+
},
|
1755
|
+
|
1715
1756
|
getAttribution: function () {
|
1716
1757
|
return this.options.attribution;
|
1717
1758
|
},
|
@@ -1722,6 +1763,10 @@ L.TileLayer = L.Class.extend({
|
|
1722
1763
|
if (this._map) {
|
1723
1764
|
this._updateOpacity();
|
1724
1765
|
}
|
1766
|
+
},
|
1767
|
+
|
1768
|
+
_updateOpacity: function () {
|
1769
|
+
L.DomUtil.setOpacity(this._container, this.options.opacity);
|
1725
1770
|
|
1726
1771
|
// stupid webkit hack to force redrawing of tiles
|
1727
1772
|
var i,
|
@@ -1736,10 +1781,6 @@ L.TileLayer = L.Class.extend({
|
|
1736
1781
|
}
|
1737
1782
|
},
|
1738
1783
|
|
1739
|
-
_updateOpacity: function () {
|
1740
|
-
L.DomUtil.setOpacity(this._container, this.options.opacity);
|
1741
|
-
},
|
1742
|
-
|
1743
1784
|
_initContainer: function () {
|
1744
1785
|
var tilePane = this._map._panes.tilePane,
|
1745
1786
|
first = tilePane.firstChild;
|
@@ -1825,6 +1866,8 @@ L.TileLayer = L.Class.extend({
|
|
1825
1866
|
}
|
1826
1867
|
}
|
1827
1868
|
|
1869
|
+
if (queue.length === 0) { return; }
|
1870
|
+
|
1828
1871
|
// load tiles in order of their distance to center
|
1829
1872
|
queue.sort(function (a, b) {
|
1830
1873
|
return a.distanceTo(center) - b.distanceTo(center);
|
@@ -1843,7 +1886,7 @@ L.TileLayer = L.Class.extend({
|
|
1843
1886
|
},
|
1844
1887
|
|
1845
1888
|
_removeOtherTiles: function (bounds) {
|
1846
|
-
var kArr, x, y, key
|
1889
|
+
var kArr, x, y, key;
|
1847
1890
|
|
1848
1891
|
for (key in this._tiles) {
|
1849
1892
|
if (this._tiles.hasOwnProperty(key)) {
|
@@ -1864,11 +1907,11 @@ L.TileLayer = L.Class.extend({
|
|
1864
1907
|
|
1865
1908
|
this.fire("tileunload", {tile: tile, url: tile.src});
|
1866
1909
|
|
1867
|
-
if (tile.parentNode === this._container) {
|
1868
|
-
this._container.removeChild(tile);
|
1869
|
-
}
|
1870
1910
|
if (this.options.reuseTiles) {
|
1911
|
+
tile.className = tile.className.replace(' leaflet-tile-loaded', '');
|
1871
1912
|
this._unusedTiles.push(tile);
|
1913
|
+
} else if (tile.parentNode === this._container) {
|
1914
|
+
this._container.removeChild(tile);
|
1872
1915
|
}
|
1873
1916
|
|
1874
1917
|
tile.src = L.Util.emptyImageUrl;
|
@@ -1899,7 +1942,7 @@ L.TileLayer = L.Class.extend({
|
|
1899
1942
|
|
1900
1943
|
// get unused tile - or create a new tile
|
1901
1944
|
var tile = this._getTile();
|
1902
|
-
L.DomUtil.setPosition(tile, tilePos);
|
1945
|
+
L.DomUtil.setPosition(tile, tilePos, true);
|
1903
1946
|
|
1904
1947
|
this._tiles[key] = tile;
|
1905
1948
|
|
@@ -1909,7 +1952,9 @@ L.TileLayer = L.Class.extend({
|
|
1909
1952
|
|
1910
1953
|
this._loadTile(tile, tilePoint, zoom);
|
1911
1954
|
|
1912
|
-
|
1955
|
+
if (tile.parentNode !== this._container) {
|
1956
|
+
container.appendChild(tile);
|
1957
|
+
}
|
1913
1958
|
},
|
1914
1959
|
|
1915
1960
|
_getOffsetZoom: function (zoom) {
|
@@ -1986,14 +2031,17 @@ L.TileLayer = L.Class.extend({
|
|
1986
2031
|
_tileOnLoad: function (e) {
|
1987
2032
|
var layer = this._layer;
|
1988
2033
|
|
1989
|
-
|
2034
|
+
//Only if we are loading an actual image
|
2035
|
+
if (this.src !== L.Util.emptyImageUrl) {
|
2036
|
+
this.className += ' leaflet-tile-loaded';
|
1990
2037
|
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
2038
|
+
layer.fire('tileload', {
|
2039
|
+
tile: this,
|
2040
|
+
url: this.src
|
2041
|
+
});
|
2042
|
+
}
|
1995
2043
|
|
1996
|
-
|
2044
|
+
layer._tileLoaded();
|
1997
2045
|
},
|
1998
2046
|
|
1999
2047
|
_tileOnError: function (e) {
|
@@ -2135,9 +2183,15 @@ L.TileLayer.Canvas = L.TileLayer.extend({
|
|
2135
2183
|
L.ImageOverlay = L.Class.extend({
|
2136
2184
|
includes: L.Mixin.Events,
|
2137
2185
|
|
2138
|
-
|
2186
|
+
options: {
|
2187
|
+
opacity: 1
|
2188
|
+
},
|
2189
|
+
|
2190
|
+
initialize: function (url, bounds, options) { // (String, LatLngBounds)
|
2139
2191
|
this._url = url;
|
2140
2192
|
this._bounds = bounds;
|
2193
|
+
|
2194
|
+
L.Util.setOptions(this, options);
|
2141
2195
|
},
|
2142
2196
|
|
2143
2197
|
onAdd: function (map) {
|
@@ -2149,6 +2203,7 @@ L.ImageOverlay = L.Class.extend({
|
|
2149
2203
|
|
2150
2204
|
map._panes.overlayPane.appendChild(this._image);
|
2151
2205
|
|
2206
|
+
map.on('zoomanim', this._zoomAnimation, this);
|
2152
2207
|
map.on('viewreset', this._reset, this);
|
2153
2208
|
this._reset();
|
2154
2209
|
},
|
@@ -2158,11 +2213,17 @@ L.ImageOverlay = L.Class.extend({
|
|
2158
2213
|
map.off('viewreset', this._reset, this);
|
2159
2214
|
},
|
2160
2215
|
|
2216
|
+
setOpacity: function (opacity) {
|
2217
|
+
this.options.opacity = opacity;
|
2218
|
+
this._updateOpacity();
|
2219
|
+
},
|
2220
|
+
|
2161
2221
|
_initImage: function () {
|
2162
|
-
this._image = L.DomUtil.create('img', 'leaflet-image-layer');
|
2222
|
+
this._image = L.DomUtil.create('img', 'leaflet-image-layer leaflet-zoom-animated');
|
2163
2223
|
|
2164
2224
|
this._image.style.visibility = 'hidden';
|
2165
|
-
|
2225
|
+
|
2226
|
+
this._updateOpacity();
|
2166
2227
|
|
2167
2228
|
//TODO createImage util method to remove duplication
|
2168
2229
|
L.Util.extend(this._image, {
|
@@ -2174,6 +2235,16 @@ L.ImageOverlay = L.Class.extend({
|
|
2174
2235
|
});
|
2175
2236
|
},
|
2176
2237
|
|
2238
|
+
_zoomAnimation: function (opt) {
|
2239
|
+
var image = this._image,
|
2240
|
+
scale = Math.pow(2, opt.zoom - this._map._zoom),
|
2241
|
+
topLeft = this._map._latLngToNewLayerPoint(this._bounds.getNorthWest(), opt.zoom, opt.center),
|
2242
|
+
size = this._map._latLngToNewLayerPoint(this._bounds.getSouthEast(), opt.zoom, opt.center).subtract(topLeft),
|
2243
|
+
currentSize = this._map.latLngToLayerPoint(this._bounds.getSouthEast()).subtract(this._map.latLngToLayerPoint(this._bounds.getNorthWest()));
|
2244
|
+
|
2245
|
+
image.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(topLeft.add(size.subtract(currentSize).divideBy(2))) + ' scale(' + scale + ') ';
|
2246
|
+
},
|
2247
|
+
|
2177
2248
|
_reset: function () {
|
2178
2249
|
var image = this._image,
|
2179
2250
|
topLeft = this._map.latLngToLayerPoint(this._bounds.getNorthWest()),
|
@@ -2188,6 +2259,10 @@ L.ImageOverlay = L.Class.extend({
|
|
2188
2259
|
_onImageLoad: function () {
|
2189
2260
|
this._image.style.visibility = '';
|
2190
2261
|
this.fire('load');
|
2262
|
+
},
|
2263
|
+
|
2264
|
+
_updateOpacity: function () {
|
2265
|
+
L.DomUtil.setOpacity(this._image, this.options.opacity);
|
2191
2266
|
}
|
2192
2267
|
});
|
2193
2268
|
|
@@ -2221,7 +2296,7 @@ L.Icon = L.Class.extend({
|
|
2221
2296
|
var src = this._getIconUrl(name);
|
2222
2297
|
|
2223
2298
|
if (!src) { return null; }
|
2224
|
-
|
2299
|
+
|
2225
2300
|
var img = this._createImg(src);
|
2226
2301
|
this._setIconStyles(img, name);
|
2227
2302
|
|
@@ -2241,7 +2316,7 @@ L.Icon = L.Class.extend({
|
|
2241
2316
|
anchor._add(options.shadowOffset);
|
2242
2317
|
}
|
2243
2318
|
|
2244
|
-
img.className = 'leaflet-marker-' + name + ' ' + options.className;
|
2319
|
+
img.className = 'leaflet-marker-' + name + ' ' + options.className + ' leaflet-zoom-animated';
|
2245
2320
|
|
2246
2321
|
if (anchor) {
|
2247
2322
|
img.style.marginLeft = (-anchor.x) + 'px';
|
@@ -2335,10 +2410,14 @@ L.Marker = L.Class.extend({
|
|
2335
2410
|
onAdd: function (map) {
|
2336
2411
|
this._map = map;
|
2337
2412
|
|
2338
|
-
map.on('viewreset', this.
|
2413
|
+
map.on('viewreset', this.update, this);
|
2414
|
+
|
2415
|
+
if (map.options.zoomAnimation && map.options.markerZoomAnimation) {
|
2416
|
+
map.on('zoomanim', this._zoomAnimation, this);
|
2417
|
+
}
|
2339
2418
|
|
2340
2419
|
this._initIcon();
|
2341
|
-
this.
|
2420
|
+
this.update();
|
2342
2421
|
},
|
2343
2422
|
|
2344
2423
|
onRemove: function (map) {
|
@@ -2349,7 +2428,8 @@ L.Marker = L.Class.extend({
|
|
2349
2428
|
this.closePopup();
|
2350
2429
|
}
|
2351
2430
|
|
2352
|
-
map.off('viewreset', this.
|
2431
|
+
map.off('viewreset', this.update, this)
|
2432
|
+
.off('zoomanim', this._zoomAnimation, this);
|
2353
2433
|
|
2354
2434
|
this._map = null;
|
2355
2435
|
},
|
@@ -2361,7 +2441,7 @@ L.Marker = L.Class.extend({
|
|
2361
2441
|
setLatLng: function (latlng) {
|
2362
2442
|
this._latlng = latlng;
|
2363
2443
|
|
2364
|
-
this.
|
2444
|
+
this.update();
|
2365
2445
|
|
2366
2446
|
if (this._popup) {
|
2367
2447
|
this._popup.setLatLng(latlng);
|
@@ -2370,7 +2450,7 @@ L.Marker = L.Class.extend({
|
|
2370
2450
|
|
2371
2451
|
setZIndexOffset: function (offset) {
|
2372
2452
|
this.options.zIndexOffset = offset;
|
2373
|
-
this.
|
2453
|
+
this.update();
|
2374
2454
|
},
|
2375
2455
|
|
2376
2456
|
setIcon: function (icon) {
|
@@ -2382,10 +2462,17 @@ L.Marker = L.Class.extend({
|
|
2382
2462
|
|
2383
2463
|
if (this._map) {
|
2384
2464
|
this._initIcon();
|
2385
|
-
this.
|
2465
|
+
this.update();
|
2386
2466
|
}
|
2387
2467
|
},
|
2388
2468
|
|
2469
|
+
update: function () {
|
2470
|
+
if (!this._icon) { return; }
|
2471
|
+
|
2472
|
+
var pos = this._map.latLngToLayerPoint(this._latlng).round();
|
2473
|
+
this._setPos(pos);
|
2474
|
+
},
|
2475
|
+
|
2389
2476
|
_initIcon: function () {
|
2390
2477
|
var options = this.options;
|
2391
2478
|
|
@@ -2424,22 +2511,20 @@ L.Marker = L.Class.extend({
|
|
2424
2511
|
this._icon = this._shadow = null;
|
2425
2512
|
},
|
2426
2513
|
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
if (!icon) {
|
2431
|
-
return;
|
2432
|
-
}
|
2433
|
-
|
2434
|
-
var pos = this._map.latLngToLayerPoint(this._latlng).round();
|
2435
|
-
|
2436
|
-
L.DomUtil.setPosition(icon, pos);
|
2514
|
+
_setPos: function (pos) {
|
2515
|
+
L.DomUtil.setPosition(this._icon, pos);
|
2437
2516
|
|
2438
2517
|
if (this._shadow) {
|
2439
2518
|
L.DomUtil.setPosition(this._shadow, pos);
|
2440
2519
|
}
|
2441
2520
|
|
2442
|
-
|
2521
|
+
this._icon.style.zIndex = pos.y + this.options.zIndexOffset;
|
2522
|
+
},
|
2523
|
+
|
2524
|
+
_zoomAnimation: function (opt) {
|
2525
|
+
var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center);
|
2526
|
+
|
2527
|
+
this._setPos(pos);
|
2443
2528
|
},
|
2444
2529
|
|
2445
2530
|
_initInteraction: function () {
|
@@ -2557,6 +2642,10 @@ L.Popup = L.Class.extend({
|
|
2557
2642
|
|
2558
2643
|
map.on('viewreset', this._updatePosition, this);
|
2559
2644
|
|
2645
|
+
if (L.Browser.any3d) {
|
2646
|
+
map.on('zoomanim', this._zoomAnimation, this);
|
2647
|
+
}
|
2648
|
+
|
2560
2649
|
if (map.options.closePopupOnClick) {
|
2561
2650
|
map.on('preclick', this._close, this);
|
2562
2651
|
}
|
@@ -2572,7 +2661,8 @@ L.Popup = L.Class.extend({
|
|
2572
2661
|
L.Util.falseFn(this._container.offsetWidth);
|
2573
2662
|
|
2574
2663
|
map.off('viewreset', this._updatePosition, this)
|
2575
|
-
.off('preclick', this._close, this)
|
2664
|
+
.off('preclick', this._close, this)
|
2665
|
+
.off('zoomanim', this._zoomAnimation, this);
|
2576
2666
|
|
2577
2667
|
this._container.style.opacity = '0';
|
2578
2668
|
|
@@ -2605,7 +2695,7 @@ L.Popup = L.Class.extend({
|
|
2605
2695
|
|
2606
2696
|
_initLayout: function () {
|
2607
2697
|
var prefix = 'leaflet-popup',
|
2608
|
-
container = this._container = L.DomUtil.create('div', prefix + ' ' + this.options.className),
|
2698
|
+
container = this._container = L.DomUtil.create('div', prefix + ' ' + this.options.className + ' leaflet-zoom-animated'),
|
2609
2699
|
closeButton;
|
2610
2700
|
|
2611
2701
|
if (this.options.closeButton) {
|
@@ -2645,7 +2735,9 @@ L.Popup = L.Class.extend({
|
|
2645
2735
|
if (typeof this._content === 'string') {
|
2646
2736
|
this._contentNode.innerHTML = this._content;
|
2647
2737
|
} else {
|
2648
|
-
this._contentNode.
|
2738
|
+
while (this._contentNode.hasChildNodes()) {
|
2739
|
+
this._contentNode.removeChild(this._contentNode.firstChild);
|
2740
|
+
}
|
2649
2741
|
this._contentNode.appendChild(this._content);
|
2650
2742
|
}
|
2651
2743
|
this.fire('contentupdate');
|
@@ -2681,15 +2773,28 @@ L.Popup = L.Class.extend({
|
|
2681
2773
|
},
|
2682
2774
|
|
2683
2775
|
_updatePosition: function () {
|
2684
|
-
var pos = this._map.latLngToLayerPoint(this._latlng)
|
2776
|
+
var pos = this._map.latLngToLayerPoint(this._latlng),
|
2777
|
+
is3d = L.Browser.any3d,
|
2778
|
+
offset = this.options.offset;
|
2685
2779
|
|
2686
|
-
|
2687
|
-
|
2780
|
+
if (is3d) {
|
2781
|
+
L.DomUtil.setPosition(this._container, pos);
|
2782
|
+
}
|
2783
|
+
|
2784
|
+
this._containerBottom = -offset.y - (is3d ? 0 : pos.y);
|
2785
|
+
this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x + (is3d ? 0 : pos.x);
|
2688
2786
|
|
2787
|
+
//Bottom position the popup in case the height of the popup changes (images loading etc)
|
2689
2788
|
this._container.style.bottom = this._containerBottom + 'px';
|
2690
2789
|
this._container.style.left = this._containerLeft + 'px';
|
2691
2790
|
},
|
2692
2791
|
|
2792
|
+
_zoomAnimation: function (opt) {
|
2793
|
+
var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center)._round();
|
2794
|
+
|
2795
|
+
L.DomUtil.setPosition(this._container, pos);
|
2796
|
+
},
|
2797
|
+
|
2693
2798
|
_adjustPan: function () {
|
2694
2799
|
if (!this.options.autoPan) { return; }
|
2695
2800
|
|
@@ -2697,30 +2802,33 @@ L.Popup = L.Class.extend({
|
|
2697
2802
|
containerHeight = this._container.offsetHeight,
|
2698
2803
|
containerWidth = this._containerWidth,
|
2699
2804
|
|
2700
|
-
layerPos = new L.Point(
|
2701
|
-
|
2702
|
-
|
2805
|
+
layerPos = new L.Point(this._containerLeft, -containerHeight - this._containerBottom);
|
2806
|
+
|
2807
|
+
if (L.Browser.any3d) {
|
2808
|
+
layerPos._add(L.DomUtil.getPosition(this._container));
|
2809
|
+
}
|
2703
2810
|
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2811
|
+
var containerPos = map.layerPointToContainerPoint(layerPos),
|
2812
|
+
padding = this.options.autoPanPadding,
|
2813
|
+
size = map.getSize(),
|
2814
|
+
dx = 0,
|
2815
|
+
dy = 0;
|
2708
2816
|
|
2709
2817
|
if (containerPos.x < 0) {
|
2710
|
-
|
2818
|
+
dx = containerPos.x - padding.x;
|
2711
2819
|
}
|
2712
2820
|
if (containerPos.x + containerWidth > size.x) {
|
2713
|
-
|
2821
|
+
dx = containerPos.x + containerWidth - size.x + padding.x;
|
2714
2822
|
}
|
2715
2823
|
if (containerPos.y < 0) {
|
2716
|
-
|
2824
|
+
dy = containerPos.y - padding.y;
|
2717
2825
|
}
|
2718
2826
|
if (containerPos.y + containerHeight > size.y) {
|
2719
|
-
|
2827
|
+
dy = containerPos.y + containerHeight - size.y + padding.y;
|
2720
2828
|
}
|
2721
2829
|
|
2722
|
-
if (
|
2723
|
-
map.panBy(
|
2830
|
+
if (dx || dy) {
|
2831
|
+
map.panBy(new L.Point(dx, dy));
|
2724
2832
|
}
|
2725
2833
|
},
|
2726
2834
|
|
@@ -3034,6 +3142,19 @@ L.Path = L.Path.extend({
|
|
3034
3142
|
SVG: L.Browser.svg
|
3035
3143
|
},
|
3036
3144
|
|
3145
|
+
bringToFront: function () {
|
3146
|
+
if (this._container) {
|
3147
|
+
this._map._pathRoot.appendChild(this._container);
|
3148
|
+
}
|
3149
|
+
},
|
3150
|
+
|
3151
|
+
bringToBack: function () {
|
3152
|
+
if (this._container) {
|
3153
|
+
var root = this._map._pathRoot;
|
3154
|
+
root.insertBefore(this._container, root.firstChild);
|
3155
|
+
}
|
3156
|
+
},
|
3157
|
+
|
3037
3158
|
getPathString: function () {
|
3038
3159
|
// form path string here
|
3039
3160
|
},
|
@@ -3147,12 +3268,43 @@ L.Map.include({
|
|
3147
3268
|
this._pathRoot = L.Path.prototype._createElement('svg');
|
3148
3269
|
this._panes.overlayPane.appendChild(this._pathRoot);
|
3149
3270
|
|
3271
|
+
if (this.options.zoomAnimation) {
|
3272
|
+
this._pathRoot.setAttribute('class', ' leaflet-zoom-animated');
|
3273
|
+
this.on('zoomanim', this._animatePathZoom);
|
3274
|
+
this.on('zoomend', this._endPathZoom);
|
3275
|
+
}
|
3276
|
+
|
3150
3277
|
this.on('moveend', this._updateSvgViewport);
|
3151
3278
|
this._updateSvgViewport();
|
3152
3279
|
}
|
3153
3280
|
},
|
3154
3281
|
|
3282
|
+
_animatePathZoom: function (opt) {
|
3283
|
+
// TODO refactor into something more manageable
|
3284
|
+
var centerOffset = this._getNewTopLeftPoint(opt.center).subtract(this._getTopLeftPoint()),
|
3285
|
+
scale = Math.pow(2, opt.zoom - this._zoom),
|
3286
|
+
offset = centerOffset.divideBy(1 - 1 / scale),
|
3287
|
+
centerPoint = this.containerPointToLayerPoint(this.getSize().divideBy(-2)),
|
3288
|
+
origin = centerPoint.add(offset).round(),
|
3289
|
+
pathRootStyle = this._pathRoot.style;
|
3290
|
+
|
3291
|
+
pathRootStyle[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString((origin.multiplyBy(-1).add(L.DomUtil.getPosition(this._pathRoot)).multiplyBy(scale).add(origin))) + ' scale(' + scale + ') ';
|
3292
|
+
|
3293
|
+
this._pathZooming = true;
|
3294
|
+
},
|
3295
|
+
|
3296
|
+
_endPathZoom: function () {
|
3297
|
+
this._pathZooming = false;
|
3298
|
+
},
|
3299
|
+
|
3155
3300
|
_updateSvgViewport: function () {
|
3301
|
+
if (this._pathZooming) {
|
3302
|
+
//Do not update SVGs while a zoom animation is going on otherwise the animation will break.
|
3303
|
+
//When the zoom animation ends we will be updated again anyway
|
3304
|
+
//This fixes the case where you do a momentum move and zoom while the move is still ongoing.
|
3305
|
+
return;
|
3306
|
+
}
|
3307
|
+
|
3156
3308
|
this._updatePathViewport();
|
3157
3309
|
|
3158
3310
|
var vp = this._pathViewport,
|
@@ -3165,7 +3317,7 @@ L.Map.include({
|
|
3165
3317
|
|
3166
3318
|
// Hack to make flicker on drag end on mobile webkit less irritating
|
3167
3319
|
// Unfortunately I haven't found a good workaround for this yet
|
3168
|
-
if (L.Browser.
|
3320
|
+
if (L.Browser.mobileWebkit) {
|
3169
3321
|
pane.removeChild(root);
|
3170
3322
|
}
|
3171
3323
|
|
@@ -3174,7 +3326,7 @@ L.Map.include({
|
|
3174
3326
|
root.setAttribute('height', height);
|
3175
3327
|
root.setAttribute('viewBox', [min.x, min.y, width, height].join(' '));
|
3176
3328
|
|
3177
|
-
if (L.Browser.
|
3329
|
+
if (L.Browser.mobileWebkit) {
|
3178
3330
|
pane.appendChild(root);
|
3179
3331
|
}
|
3180
3332
|
}
|
@@ -3254,21 +3406,6 @@ L.Path = L.Browser.svg || !L.Browser.vml ? L.Path : L.Path.extend({
|
|
3254
3406
|
},
|
3255
3407
|
|
3256
3408
|
_initStyle: function () {
|
3257
|
-
var container = this._container,
|
3258
|
-
stroke,
|
3259
|
-
fill;
|
3260
|
-
|
3261
|
-
if (this.options.stroke) {
|
3262
|
-
stroke = this._stroke = this._createElement('stroke');
|
3263
|
-
stroke.endcap = 'round';
|
3264
|
-
container.appendChild(stroke);
|
3265
|
-
}
|
3266
|
-
|
3267
|
-
if (this.options.fill) {
|
3268
|
-
fill = this._fill = this._createElement('fill');
|
3269
|
-
container.appendChild(fill);
|
3270
|
-
}
|
3271
|
-
|
3272
3409
|
this._updateStyle();
|
3273
3410
|
},
|
3274
3411
|
|
@@ -3282,14 +3419,29 @@ L.Path = L.Browser.svg || !L.Browser.vml ? L.Path : L.Path.extend({
|
|
3282
3419
|
container.filled = options.fill;
|
3283
3420
|
|
3284
3421
|
if (options.stroke) {
|
3285
|
-
stroke
|
3286
|
-
|
3422
|
+
if (!stroke) {
|
3423
|
+
stroke = this._stroke = this._createElement('stroke');
|
3424
|
+
stroke.endcap = 'round';
|
3425
|
+
container.appendChild(stroke);
|
3426
|
+
}
|
3427
|
+
stroke.weight = options.weight + 'px';
|
3428
|
+
stroke.color = options.color;
|
3287
3429
|
stroke.opacity = options.opacity;
|
3430
|
+
} else if (stroke) {
|
3431
|
+
container.removeChild(stroke);
|
3432
|
+
this._stroke = null;
|
3288
3433
|
}
|
3289
3434
|
|
3290
3435
|
if (options.fill) {
|
3291
|
-
fill
|
3436
|
+
if (!fill) {
|
3437
|
+
fill = this._fill = this._createElement('fill');
|
3438
|
+
container.appendChild(fill);
|
3439
|
+
}
|
3440
|
+
fill.color = options.fillColor || options.color;
|
3292
3441
|
fill.opacity = options.fillOpacity;
|
3442
|
+
} else if (fill) {
|
3443
|
+
container.removeChild(fill);
|
3444
|
+
this._fill = null;
|
3293
3445
|
}
|
3294
3446
|
},
|
3295
3447
|
|
@@ -3437,12 +3589,21 @@ L.Map.include((L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? {}
|
|
3437
3589
|
|
3438
3590
|
this._panes.overlayPane.appendChild(root);
|
3439
3591
|
|
3592
|
+
if (this.options.zoomAnimation) {
|
3593
|
+
this._pathRoot.className = 'leaflet-zoom-animated';
|
3594
|
+
this.on('zoomanim', this._animatePathZoom);
|
3595
|
+
this.on('zoomend', this._endPathZoom);
|
3596
|
+
}
|
3440
3597
|
this.on('moveend', this._updateCanvasViewport);
|
3441
3598
|
this._updateCanvasViewport();
|
3442
3599
|
}
|
3443
3600
|
},
|
3444
3601
|
|
3445
3602
|
_updateCanvasViewport: function () {
|
3603
|
+
if (this._pathZooming) {
|
3604
|
+
//Don't redraw while zooming. See _updateSvgViewport for more details
|
3605
|
+
return;
|
3606
|
+
}
|
3446
3607
|
this._updatePathViewport();
|
3447
3608
|
|
3448
3609
|
var vp = this._pathViewport,
|
@@ -3731,10 +3892,10 @@ L.Polyline = L.Path.extend({
|
|
3731
3892
|
for (var i = 1, len = points.length; i < len; i++) {
|
3732
3893
|
p1 = points[i - 1];
|
3733
3894
|
p2 = points[i];
|
3734
|
-
var
|
3735
|
-
if (
|
3736
|
-
minDistance =
|
3737
|
-
minPoint =
|
3895
|
+
var sqDist = L.LineUtil._sqClosestPointOnSegment(p, p1, p2, true);
|
3896
|
+
if (sqDist < minDistance) {
|
3897
|
+
minDistance = sqDist;
|
3898
|
+
minPoint = L.LineUtil._sqClosestPointOnSegment(p, p1, p2);
|
3738
3899
|
}
|
3739
3900
|
}
|
3740
3901
|
}
|
@@ -4016,7 +4177,7 @@ L.Rectangle = L.Polygon.extend({
|
|
4016
4177
|
setBounds: function (latLngBounds) {
|
4017
4178
|
this.setLatLngs(this._boundsToLatLngs(latLngBounds));
|
4018
4179
|
},
|
4019
|
-
|
4180
|
+
|
4020
4181
|
_boundsToLatLngs: function (latLngBounds) {
|
4021
4182
|
return [
|
4022
4183
|
latLngBounds.getSouthWest(),
|
@@ -4076,7 +4237,7 @@ L.Circle = L.Path.extend({
|
|
4076
4237
|
|
4077
4238
|
return new L.LatLngBounds(sw, ne);
|
4078
4239
|
},
|
4079
|
-
|
4240
|
+
|
4080
4241
|
getLatLng: function () {
|
4081
4242
|
return this._latlng;
|
4082
4243
|
},
|
@@ -4099,7 +4260,7 @@ L.Circle = L.Path.extend({
|
|
4099
4260
|
return "AL " + p.x + "," + p.y + " " + r + "," + r + " 0," + (65535 * 360);
|
4100
4261
|
}
|
4101
4262
|
},
|
4102
|
-
|
4263
|
+
|
4103
4264
|
getRadius: function () {
|
4104
4265
|
return this._mRadius;
|
4105
4266
|
},
|
@@ -4236,7 +4397,6 @@ L.Circle.include(!L.Path.CANVAS ? {} : {
|
|
4236
4397
|
});
|
4237
4398
|
|
4238
4399
|
|
4239
|
-
|
4240
4400
|
L.GeoJSON = L.FeatureGroup.extend({
|
4241
4401
|
initialize: function (geojson, options) {
|
4242
4402
|
L.Util.setOptions(this, options);
|
@@ -4269,7 +4429,8 @@ L.GeoJSON = L.FeatureGroup.extend({
|
|
4269
4429
|
properties: geojson.properties,
|
4270
4430
|
geometryType: geometry.type,
|
4271
4431
|
bbox: geojson.bbox,
|
4272
|
-
id: geojson.id
|
4432
|
+
id: geojson.id,
|
4433
|
+
geometry: geojson.geometry
|
4273
4434
|
});
|
4274
4435
|
|
4275
4436
|
this.addLayer(layer);
|
@@ -4587,22 +4748,23 @@ L.Draggable = L.Class.extend({
|
|
4587
4748
|
},
|
4588
4749
|
|
4589
4750
|
_onMove: function (e) {
|
4590
|
-
if (e.touches && e.touches.length > 1) {
|
4591
|
-
return;
|
4592
|
-
}
|
4751
|
+
if (e.touches && e.touches.length > 1) { return; }
|
4593
4752
|
|
4594
|
-
|
4753
|
+
var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e),
|
4754
|
+
newPoint = new L.Point(first.clientX, first.clientY),
|
4755
|
+
diffVec = newPoint.subtract(this._startPoint);
|
4595
4756
|
|
4596
|
-
|
4757
|
+
if (!diffVec.x && !diffVec.y) { return; }
|
4758
|
+
|
4759
|
+
L.DomEvent.preventDefault(e);
|
4597
4760
|
|
4598
4761
|
if (!this._moved) {
|
4599
4762
|
this.fire('dragstart');
|
4600
4763
|
this._moved = true;
|
4601
4764
|
}
|
4602
|
-
this._moving = true;
|
4603
4765
|
|
4604
|
-
|
4605
|
-
this.
|
4766
|
+
this._newPos = this._startPos.add(diffVec);
|
4767
|
+
this._moving = true;
|
4606
4768
|
|
4607
4769
|
L.Util.cancelAnimFrame(this._animRequest);
|
4608
4770
|
this._animRequest = L.Util.requestAnimFrame(this._updatePosition, this, true, this._dragStartTarget);
|
@@ -4638,6 +4800,9 @@ L.Draggable = L.Class.extend({
|
|
4638
4800
|
L.DomEvent.removeListener(document, L.Draggable.END, this._onUp);
|
4639
4801
|
|
4640
4802
|
if (this._moved) {
|
4803
|
+
// ensure drag is not fired after dragend
|
4804
|
+
L.Util.cancelAnimFrame(this._animRequest);
|
4805
|
+
|
4641
4806
|
this.fire('dragend');
|
4642
4807
|
}
|
4643
4808
|
this._moving = false;
|
@@ -5032,21 +5197,32 @@ L.Map.TouchZoom = L.Handler.extend({
|
|
5032
5197
|
|
5033
5198
|
if (this._scale === 1) { return; }
|
5034
5199
|
|
5200
|
+
var zoom = this._map._zoom + Math.log(this._scale) / Math.LN2;
|
5201
|
+
|
5202
|
+
var centerOffset = this._centerOffset.subtract(this._delta).divideBy(this._scale),
|
5203
|
+
centerPoint = this._map.getPixelOrigin().add(this._startCenter).add(centerOffset),
|
5204
|
+
center = this._map.unproject(centerPoint);
|
5205
|
+
|
5035
5206
|
if (!this._moved) {
|
5036
|
-
map._mapPane.className += ' leaflet-zoom-anim';
|
5207
|
+
map._mapPane.className += ' leaflet-zoom-anim leaflet-touching';
|
5037
5208
|
|
5038
5209
|
map
|
5039
|
-
.fire('zoomstart')
|
5040
5210
|
.fire('movestart')
|
5211
|
+
.fire('zoomstart')
|
5041
5212
|
._prepareTileBg();
|
5042
5213
|
|
5043
5214
|
this._moved = true;
|
5044
5215
|
}
|
5045
5216
|
|
5217
|
+
map.fire('zoomanim', {
|
5218
|
+
center: center,
|
5219
|
+
zoom: zoom
|
5220
|
+
});
|
5221
|
+
|
5046
5222
|
// Used 2 translates instead of transform-origin because of a very strange bug -
|
5047
5223
|
// it didn't count the origin on the first touch-zoom but worked correctly afterwards
|
5048
5224
|
|
5049
|
-
map._tileBg.style.
|
5225
|
+
map._tileBg.style[L.DomUtil.TRANSFORM] =
|
5050
5226
|
L.DomUtil.getTranslateString(this._delta) + ' ' +
|
5051
5227
|
L.DomUtil.getScaleString(this._scale, this._startCenter);
|
5052
5228
|
|
@@ -5057,6 +5233,7 @@ L.Map.TouchZoom = L.Handler.extend({
|
|
5057
5233
|
if (!this._moved || !this._zooming) { return; }
|
5058
5234
|
|
5059
5235
|
this._zooming = false;
|
5236
|
+
this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-touching', ''); //TODO toggleClass util
|
5060
5237
|
|
5061
5238
|
L.DomEvent
|
5062
5239
|
.removeListener(document, 'touchmove', this._onTouchMove)
|
@@ -5072,7 +5249,12 @@ L.Map.TouchZoom = L.Handler.extend({
|
|
5072
5249
|
zoom = this._map._limitZoom(oldZoom + roundZoomDelta),
|
5073
5250
|
finalScale = Math.pow(2, zoom - oldZoom);
|
5074
5251
|
|
5075
|
-
this._map.
|
5252
|
+
this._map.fire('zoomanim', {
|
5253
|
+
center: center,
|
5254
|
+
zoom: zoom
|
5255
|
+
});
|
5256
|
+
|
5257
|
+
this._map._runAnimation(center, zoom, finalScale / this._scale, this._startCenter.add(centerOffset), true);
|
5076
5258
|
}
|
5077
5259
|
});
|
5078
5260
|
|
@@ -5118,7 +5300,7 @@ L.Map.BoxZoom = L.Handler.extend({
|
|
5118
5300
|
.addListener(document, 'mousemove', this._onMouseMove, this)
|
5119
5301
|
.addListener(document, 'mouseup', this._onMouseUp, this)
|
5120
5302
|
.preventDefault(e);
|
5121
|
-
|
5303
|
+
|
5122
5304
|
this._map.fire("boxzoomstart");
|
5123
5305
|
},
|
5124
5306
|
|
@@ -5158,7 +5340,7 @@ L.Map.BoxZoom = L.Handler.extend({
|
|
5158
5340
|
map.layerPointToLatLng(layerPoint));
|
5159
5341
|
|
5160
5342
|
map.fitBounds(bounds);
|
5161
|
-
|
5343
|
+
|
5162
5344
|
map.fire("boxzoomend", {
|
5163
5345
|
boxZoomBounds: bounds
|
5164
5346
|
});
|
@@ -5261,7 +5443,9 @@ L.Handler.PolyEdit = L.Handler.extend({
|
|
5261
5443
|
},
|
5262
5444
|
|
5263
5445
|
_initMarkers: function () {
|
5264
|
-
this._markerGroup
|
5446
|
+
if (!this._markerGroup) {
|
5447
|
+
this._markerGroup = new L.LayerGroup();
|
5448
|
+
}
|
5265
5449
|
this._markers = [];
|
5266
5450
|
|
5267
5451
|
var latlngs = this._poly._latlngs,
|
@@ -5332,10 +5516,10 @@ L.Handler.PolyEdit = L.Handler.extend({
|
|
5332
5516
|
if (this._poly._latlngs.length < 3) {
|
5333
5517
|
return;
|
5334
5518
|
}
|
5335
|
-
|
5519
|
+
|
5336
5520
|
var marker = e.target,
|
5337
5521
|
i = marker._index;
|
5338
|
-
|
5522
|
+
|
5339
5523
|
// Check existence of previous and next markers since they wouldn't exist for edge points on the polyline
|
5340
5524
|
if (marker._prev && marker._next) {
|
5341
5525
|
this._createMiddleMarker(marker._prev, marker._next);
|
@@ -5351,6 +5535,7 @@ L.Handler.PolyEdit = L.Handler.extend({
|
|
5351
5535
|
if (marker._middleRight) {
|
5352
5536
|
this._markerGroup.removeLayer(marker._middleRight);
|
5353
5537
|
}
|
5538
|
+
this._markers.splice(i, 1);
|
5354
5539
|
this._poly.spliceLatLngs(i, 1);
|
5355
5540
|
this._updateIndexes(i, -1);
|
5356
5541
|
this._poly.fire('edit');
|
@@ -5384,6 +5569,8 @@ L.Handler.PolyEdit = L.Handler.extend({
|
|
5384
5569
|
.off('click', onClick)
|
5385
5570
|
.on('click', this._onMarkerClick, this);
|
5386
5571
|
|
5572
|
+
latlng.lat = marker.getLatLng().lat;
|
5573
|
+
latlng.lng = marker.getLatLng().lng;
|
5387
5574
|
this._poly.spliceLatLngs(i, 0, latlng);
|
5388
5575
|
this._markers.splice(i, 0, marker);
|
5389
5576
|
|
@@ -5710,14 +5897,17 @@ L.Control.Scale = L.Control.extend({
|
|
5710
5897
|
|
5711
5898
|
size = this._map.getSize(),
|
5712
5899
|
options = this.options,
|
5900
|
+
maxMeters = 0;
|
5713
5901
|
|
5714
|
-
|
5902
|
+
if (size.x > 0) {
|
5903
|
+
maxMeters = left.distanceTo(right) * (options.maxWidth / size.x);
|
5904
|
+
}
|
5715
5905
|
|
5716
|
-
if (options.metric) {
|
5906
|
+
if (options.metric && maxMeters) {
|
5717
5907
|
this._updateMetric(maxMeters);
|
5718
5908
|
}
|
5719
5909
|
|
5720
|
-
if (options.imperial) {
|
5910
|
+
if (options.imperial && maxMeters) {
|
5721
5911
|
this._updateImperial(maxMeters);
|
5722
5912
|
}
|
5723
5913
|
},
|
@@ -5764,6 +5954,7 @@ L.Control.Scale = L.Control.extend({
|
|
5764
5954
|
});
|
5765
5955
|
|
5766
5956
|
|
5957
|
+
|
5767
5958
|
L.Control.Layers = L.Control.extend({
|
5768
5959
|
options: {
|
5769
5960
|
collapsed: true,
|
@@ -5835,7 +6026,15 @@ L.Control.Layers = L.Control.extend({
|
|
5835
6026
|
link.href = '#';
|
5836
6027
|
link.title = 'Layers';
|
5837
6028
|
|
5838
|
-
|
6029
|
+
if (L.Browser.touch) {
|
6030
|
+
L.DomEvent
|
6031
|
+
.addListener(link, 'click', L.DomEvent.stopPropagation)
|
6032
|
+
.addListener(link, 'click', L.DomEvent.preventDefault)
|
6033
|
+
.addListener(link, 'click', this._expand, this);
|
6034
|
+
}
|
6035
|
+
else {
|
6036
|
+
L.DomEvent.addListener(link, 'focus', this._expand, this);
|
6037
|
+
}
|
5839
6038
|
|
5840
6039
|
this._map.on('movestart', this._collapse, this);
|
5841
6040
|
// TODO keyboard accessibility
|
@@ -5983,7 +6182,7 @@ L.Transition = L.Transition.extend({
|
|
5983
6182
|
|
5984
6183
|
// transition-property value to use with each particular custom property
|
5985
6184
|
CUSTOM_PROPS_PROPERTIES: {
|
5986
|
-
position: L.Browser.
|
6185
|
+
position: L.Browser.any3d ? L.DomUtil.TRANSFORM : 'top, left'
|
5987
6186
|
}
|
5988
6187
|
};
|
5989
6188
|
}()),
|
@@ -6056,7 +6255,7 @@ L.Transition = L.Transition.extend({
|
|
6056
6255
|
this._inProgress = false;
|
6057
6256
|
clearInterval(this._timer);
|
6058
6257
|
|
6059
|
-
this._el.style[L.Transition.
|
6258
|
+
this._el.style[L.Transition.TRANSITION] = '';
|
6060
6259
|
|
6061
6260
|
this.fire('step');
|
6062
6261
|
|
@@ -6301,22 +6500,37 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
|
6301
6500
|
|
6302
6501
|
this._mapPane.className += ' leaflet-zoom-anim';
|
6303
6502
|
|
6304
|
-
|
6503
|
+
this
|
6305
6504
|
.fire('movestart')
|
6306
6505
|
.fire('zoomstart');
|
6307
6506
|
|
6308
|
-
this
|
6507
|
+
//Hack: Disable this for android due to it not supporting double translate (mentioned in _runAnimation below)
|
6508
|
+
//if Foreground layer doesn't have many tiles but bg layer does, keep the existing bg layer
|
6509
|
+
if (!L.Browser.android && this._tileBg && this._getLoadedTilesPercentage(this._tileBg) > 0.5 && this._getLoadedTilesPercentage(this._tilePane) < 0.5) {
|
6510
|
+
//Leave current bg and just zoom it some more
|
6511
|
+
|
6512
|
+
this._tilePane.style.visibility = 'hidden';
|
6513
|
+
this._tilePane.empty = true;
|
6514
|
+
this._stopLoadingImages(this._tilePane);
|
6515
|
+
} else {
|
6516
|
+
this._prepareTileBg();
|
6517
|
+
}
|
6309
6518
|
|
6310
6519
|
var centerPoint = this.containerPointToLayerPoint(this.getSize().divideBy(2)),
|
6311
6520
|
origin = centerPoint.add(offset);
|
6312
6521
|
|
6522
|
+
this.fire('zoomanim', {
|
6523
|
+
center: center,
|
6524
|
+
zoom: zoom
|
6525
|
+
});
|
6526
|
+
|
6313
6527
|
this._runAnimation(center, zoom, scale, origin);
|
6314
6528
|
|
6315
6529
|
return true;
|
6316
6530
|
},
|
6317
6531
|
|
6318
6532
|
|
6319
|
-
_runAnimation: function (center, zoom, scale, origin) {
|
6533
|
+
_runAnimation: function (center, zoom, scale, origin, backwardsTransform) {
|
6320
6534
|
this._animatingZoom = true;
|
6321
6535
|
|
6322
6536
|
this._animateToCenter = center;
|
@@ -6348,7 +6562,11 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
|
6348
6562
|
L.Util.falseFn(tileBg.offsetWidth); //hack to make sure transform is updated before running animation
|
6349
6563
|
|
6350
6564
|
var options = {};
|
6351
|
-
|
6565
|
+
if (backwardsTransform) {
|
6566
|
+
options[transform] = tileBg.style[transform] + ' ' + scaleStr;
|
6567
|
+
} else {
|
6568
|
+
options[transform] = scaleStr + ' ' + tileBg.style[transform];
|
6569
|
+
}
|
6352
6570
|
|
6353
6571
|
tileBg.transition.run(options);
|
6354
6572
|
},
|
@@ -6367,9 +6585,10 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
|
6367
6585
|
tileBg.style.visibility = 'hidden';
|
6368
6586
|
|
6369
6587
|
// tells tile layers to reinitialize their containers
|
6370
|
-
tileBg.empty = true;
|
6371
|
-
tilePane.empty = false;
|
6588
|
+
tileBg.empty = true; //new FG
|
6589
|
+
tilePane.empty = false; //new BG
|
6372
6590
|
|
6591
|
+
//Switch out the current layer to be the new bg layer (And vice-versa)
|
6373
6592
|
this._tilePane = this._panes.tilePane = tileBg;
|
6374
6593
|
var newTileBg = this._tileBg = tilePane;
|
6375
6594
|
|
@@ -6385,6 +6604,18 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
|
6385
6604
|
this._stopLoadingImages(newTileBg);
|
6386
6605
|
},
|
6387
6606
|
|
6607
|
+
_getLoadedTilesPercentage: function (container) {
|
6608
|
+
var tiles = Array.prototype.slice.call(container.getElementsByTagName('img')),
|
6609
|
+
i, len, count = 0;
|
6610
|
+
|
6611
|
+
for (i = 0, len = tiles.length; i < len; i++) {
|
6612
|
+
if (tiles[i].complete) {
|
6613
|
+
count++;
|
6614
|
+
}
|
6615
|
+
}
|
6616
|
+
return count / len;
|
6617
|
+
},
|
6618
|
+
|
6388
6619
|
// stops loading all tiles in the background layer
|
6389
6620
|
_stopLoadingImages: function (container) {
|
6390
6621
|
var tiles = Array.prototype.slice.call(container.getElementsByTagName('img')),
|
@@ -6517,4 +6748,4 @@ L.Map.include({
|
|
6517
6748
|
|
6518
6749
|
|
6519
6750
|
|
6520
|
-
}());
|
6751
|
+
}());
|