|
12 | 12 | }(this, function (L, mapboxgl) {
|
13 | 13 | L.MapboxGL = L.Layer.extend({
|
14 | 14 | options: {
|
15 |
| - updateInterval: 32 |
| 15 | + updateInterval: 32, |
| 16 | + // How much to extend the overlay view (relative to map size) |
| 17 | + // e.g. 0.15 would be 15% of map view in each direction |
| 18 | + padding: 0.15 |
16 | 19 | },
|
17 | 20 |
|
18 | 21 | initialize: function (options) {
|
|
24 | 27 | throw new Error('You should provide a Mapbox GL access token as a token option.');
|
25 | 28 | }
|
26 | 29 |
|
27 |
| - /** |
28 |
| - * Create a version of `fn` that only fires once every `time` millseconds. |
29 |
| - * |
30 |
| - * @param {Function} fn the function to be throttled |
31 |
| - * @param {number} time millseconds required between function calls |
32 |
| - * @param {*} context the value of `this` with which the function is called |
33 |
| - * @returns {Function} debounced function |
34 |
| - * @private |
35 |
| - */ |
36 |
| - var throttle = function (fn, time, context) { |
37 |
| - var lock, args, wrapperFn, later; |
38 |
| - |
39 |
| - later = function () { |
40 |
| - // reset lock and call if queued |
41 |
| - lock = false; |
42 |
| - if (args) { |
43 |
| - wrapperFn.apply(context, args); |
44 |
| - args = false; |
45 |
| - } |
46 |
| - }; |
47 |
| - |
48 |
| - wrapperFn = function () { |
49 |
| - if (lock) { |
50 |
| - // called too soon, queue to call later |
51 |
| - args = arguments; |
52 |
| - |
53 |
| - } else { |
54 |
| - // call and lock until later |
55 |
| - fn.apply(context, arguments); |
56 |
| - setTimeout(later, time); |
57 |
| - lock = true; |
58 |
| - } |
59 |
| - }; |
60 |
| - |
61 |
| - return wrapperFn; |
62 |
| - }; |
63 |
| - |
64 | 30 | // setup throttling the update event when panning
|
65 |
| - this._throttledUpdate = throttle(L.Util.bind(this._update, this), this.options.updateInterval); |
| 31 | + this._throttledUpdate = L.Util.throttle(this._update, this.options.updateInterval, this); |
66 | 32 | },
|
67 | 33 |
|
68 | 34 | onAdd: function (map) {
|
|
102 | 68 | };
|
103 | 69 | },
|
104 | 70 |
|
| 71 | + _getSize: function () { |
| 72 | + return this._map.getSize().multiplyBy(1 + this.options.padding * 2); |
| 73 | + }, |
| 74 | + |
105 | 75 | _initContainer: function () {
|
106 | 76 | var container = this._glContainer = L.DomUtil.create('div', 'leaflet-gl-layer');
|
107 | 77 |
|
108 |
| - var size = this._map.getSize(); |
| 78 | + var size = this._getSize(); |
| 79 | + var offset = this._map.getSize().multiplyBy(this.options.padding); |
109 | 80 | container.style.width = size.x + 'px';
|
110 | 81 | container.style.height = size.y + 'px';
|
| 82 | + |
| 83 | + var topLeft = this._map.containerPointToLayerPoint([0, 0]).subtract(offset); |
| 84 | + |
| 85 | + L.DomUtil.setPosition(container, topLeft); |
111 | 86 | },
|
112 | 87 |
|
113 | 88 | _initGL: function () {
|
|
147 | 122 | return;
|
148 | 123 | }
|
149 | 124 |
|
150 |
| - var size = this._map.getSize(), |
| 125 | + var size = this._getSize(), |
151 | 126 | container = this._glContainer,
|
152 | 127 | gl = this._glMap,
|
153 |
| - topLeft = this._map.containerPointToLayerPoint([0, 0]); |
| 128 | + offset = this._map.getSize().multiplyBy(this.options.padding), |
| 129 | + topLeft = this._map.containerPointToLayerPoint([0, 0]).subtract(offset); |
154 | 130 |
|
155 | 131 | L.DomUtil.setPosition(container, topLeft);
|
156 | 132 |
|
|
191 | 167 |
|
192 | 168 | // borrowed from L.ImageOverlay https://github.com/Leaflet/Leaflet/blob/master/src/layer/ImageOverlay.js#L139-L144
|
193 | 169 | _animateZoom: function (e) {
|
194 |
| - var scale = this._map.getZoomScale(e.zoom), |
195 |
| - offset = this._map._latLngToNewLayerPoint(this._map.getBounds().getNorthWest(), e.zoom, e.center); |
196 |
| - |
197 |
| - L.DomUtil.setTransform(this._glMap._actualCanvas, offset.subtract(this._offset), scale); |
| 170 | + var scale = this._map.getZoomScale(e.zoom); |
| 171 | + var padding = this._map.getSize().multiplyBy(this.options.padding * scale); |
| 172 | + var viewHalf = this._getSize()._divideBy(2); |
| 173 | + // corrections for padding (scaled), adapted from |
| 174 | + // https://github.com/Leaflet/Leaflet/blob/master/src/map/Map.js#L1490-L1508 |
| 175 | + var topLeft = this._map.project(e.center, e.zoom) |
| 176 | + ._subtract(viewHalf) |
| 177 | + ._add(this._map._getMapPanePos() |
| 178 | + .add(padding))._round(); |
| 179 | + var offset = this._map.project(this._map.getBounds().getNorthWest(), e.zoom) |
| 180 | + ._subtract(topLeft); |
| 181 | + |
| 182 | + L.DomUtil.setTransform(this._glMap._actualCanvas, offset.subtract(this._offset), scale); |
198 | 183 | },
|
199 | 184 |
|
200 | 185 | _zoomStart: function (e) {
|
|
0 commit comments