Skip to content

Commit af165dd

Browse files
fix vector drifts when zoomAnimation is false and zooming via flyTo or pinch (#8794)
Co-authored-by: Florian Bischof <[email protected]>
1 parent 8887c41 commit af165dd

File tree

3 files changed

+176
-3
lines changed

3 files changed

+176
-3
lines changed

debug/vector/vector-drift.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Leaflet debug page</title>
5+
<link rel="stylesheet" href="../../dist/leaflet.css" />
6+
<link rel="stylesheet" href="../css/screen.css" />
7+
<script src="../../dist/leaflet-src.js"></script>
8+
</head>
9+
<body>
10+
<button id="btn-1">A</button>
11+
<button id="btn-2">B</button>
12+
<div id="map"></div>
13+
14+
<script>
15+
var map = L.map('map', {
16+
zoomAnimation: false,
17+
// preferCanvas: true
18+
}).setView([0, 0], 7);
19+
20+
var markerA = L.marker([1, 0]).addTo(map);
21+
var markerB = L.marker([1, 2]).addTo(map);
22+
L.polygon([
23+
[0, 0],
24+
[2, 0],
25+
[2, 2],
26+
[0, 2],
27+
[0, 0],
28+
])
29+
.bindPopup('Hello world')
30+
.addTo(map);
31+
32+
// or pinch zoom in mobile
33+
document.getElementById('btn-1').addEventListener('click', function () {
34+
map.flyTo(markerA.getLatLng(), 6);
35+
});
36+
document.getElementById('btn-2').addEventListener('click', function () {
37+
map.flyTo(markerB.getLatLng(), 7);
38+
});
39+
</script>
40+
</body>
41+
</html>

spec/suites/map/handler/Map.TouchZoomSpec.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,137 @@ describe("Map.TouchZoom", function () {
157157
.down().moveBy(-200, 0, 500).up(100);
158158
});
159159

160+
it.skipIfNotTouch("Layer is rendered correctly while pinch zoom when zoomAnim is true", function (done) {
161+
if (L.Browser.ie) {
162+
// getBoundingClientRect doesn't return valid values in IE
163+
done();
164+
return;
165+
}
166+
map.remove();
167+
168+
map = new L.Map(container, {
169+
touchZoom: true,
170+
inertia: false,
171+
zoomAnimation: true
172+
});
173+
174+
map.setView([0, 0], 8);
175+
176+
var polygon = L.polygon([
177+
[0, 0],
178+
[0, 1],
179+
[1, 1],
180+
[1, 0]
181+
]).addTo(map);
182+
183+
var alreadyCalled = false;
184+
var hand = new Hand({
185+
timing: 'fastframe',
186+
onStop: function () {
187+
setTimeout(function () {
188+
if (alreadyCalled) {
189+
return; // Will recursivly call itself otherwise
190+
}
191+
alreadyCalled = true;
192+
193+
var renderedRect = polygon._path.getBoundingClientRect();
194+
195+
var width = renderedRect.width;
196+
var height = renderedRect.height;
197+
198+
expect(height < 50).to.be(true);
199+
expect(width < 50).to.be(true);
200+
expect(height + width > 0).to.be(true);
201+
202+
var x = renderedRect.x;
203+
var y = renderedRect.y;
204+
205+
expect(x).to.be.within(299, 301);
206+
expect(y).to.be.within(270, 280);
207+
208+
// Fingers lifted after expects as bug goes away when lifted
209+
hand._fingers[0].up();
210+
hand._fingers[1].up();
211+
212+
done();
213+
}, 100);
214+
}
215+
});
216+
217+
var f1 = hand.growFinger(touchEventType);
218+
var f2 = hand.growFinger(touchEventType);
219+
220+
hand.sync(5);
221+
f1.wait(100).moveTo(75, 300, 0)
222+
.down().moveBy(200, 0, 500);
223+
f2.wait(100).moveTo(525, 300, 0)
224+
.down().moveBy(-200, 0, 500);
225+
});
226+
227+
it.skipIfNotTouch("Layer is rendered correctly while pinch zoom when zoomAnim is false", function (done) {
228+
if (L.Browser.ie) {
229+
// getBoundingClientRect doesn't return valid values in IE
230+
done();
231+
return;
232+
}
233+
map.remove();
234+
235+
map = new L.Map(container, {
236+
touchZoom: true,
237+
inertia: false,
238+
zoomAnimation: false
239+
});
240+
241+
map.setView([0, 0], 8);
242+
243+
var polygon = L.polygon([
244+
[0, 0],
245+
[0, 1],
246+
[1, 1],
247+
[1, 0]
248+
]).addTo(map);
249+
250+
var alreadyCalled = false;
251+
var hand = new Hand({
252+
timing: 'fastframe',
253+
onStop: function () {
254+
setTimeout(function () {
255+
if (alreadyCalled) {
256+
return; // Will recursivly call itself otherwise
257+
}
258+
alreadyCalled = true;
259+
260+
var renderedRect = polygon._path.getBoundingClientRect();
261+
262+
var width = renderedRect.width;
263+
var height = renderedRect.height;
264+
265+
expect(height < 50).to.be(true);
266+
expect(width < 50).to.be(true);
267+
expect(height + width > 0).to.be(true);
268+
269+
var x = renderedRect.x;
270+
var y = renderedRect.y;
271+
272+
expect(x).to.be.within(299, 301);
273+
expect(y).to.be.within(270, 280);
274+
275+
// Fingers lifted after expects as bug goes away when lifted
276+
hand._fingers[0].up();
277+
hand._fingers[1].up();
278+
279+
done();
280+
}, 100);
281+
}
282+
});
283+
284+
var f1 = hand.growFinger(touchEventType);
285+
var f2 = hand.growFinger(touchEventType);
286+
287+
hand.sync(5);
288+
f1.wait(100).moveTo(75, 300, 0)
289+
.down().moveBy(200, 0, 500);
290+
f2.wait(100).moveTo(525, 300, 0)
291+
.down().moveBy(-200, 0, 500);
292+
});
160293
});

src/layer/vector/Renderer.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ export var Renderer = Layer.extend({
4747
if (!this._container) {
4848
this._initContainer(); // defined by renderer implementations
4949

50-
if (this._zoomAnimated) {
51-
DomUtil.addClass(this._container, 'leaflet-zoom-animated');
52-
}
50+
// always keep transform-origin as 0 0
51+
DomUtil.addClass(this._container, 'leaflet-zoom-animated');
5352
}
5453

5554
this.getPane().appendChild(this._container);

0 commit comments

Comments
 (0)