feat(Marker.Drag): autoPan implementation (#5651)
* feat(Marker.Drag): autoPan implementation * Adjust autoPanSpeed to 10 * Add tests for marker drag
This commit is contained in:
parent
b7cbcb39b8
commit
5228a62a1c
63
debug/map/marker-autopan.html
Normal file
63
debug/map/marker-autopan.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Leaflet debug page</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../css/screen.css" />
|
||||||
|
|
||||||
|
<script src="../leaflet-include.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="map"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
map = L.map('map', { center: [0, 0], zoom: 3, maxZoom: 4 });
|
||||||
|
|
||||||
|
var markerAutoPan = new L.Marker([0, -10], {
|
||||||
|
draggable: true,
|
||||||
|
autoPan: true,
|
||||||
|
title: 'AutoPan'
|
||||||
|
});
|
||||||
|
|
||||||
|
map.addLayer(markerAutoPan);
|
||||||
|
markerAutoPan.bindPopup("AutoPan");
|
||||||
|
|
||||||
|
|
||||||
|
var markerDraggable = new L.Marker([0, 10], {
|
||||||
|
title: 'Draggable'
|
||||||
|
});
|
||||||
|
|
||||||
|
map.addLayer(markerDraggable);
|
||||||
|
markerDraggable.bindPopup("Draggable");
|
||||||
|
markerDraggable.dragging.enable();
|
||||||
|
|
||||||
|
var poly = new L.Polygon([[0, 10], [0, 15.5], [0, 50], [20, 20.5]]);
|
||||||
|
map.addLayer(poly);
|
||||||
|
poly.bindPopup("Polygon");
|
||||||
|
|
||||||
|
|
||||||
|
markerDraggable.on('click', function(e) {
|
||||||
|
console.log('markerDraggable click');
|
||||||
|
});
|
||||||
|
markerAutoPan.on('click', function(e) {
|
||||||
|
console.log('markerAutoPan click');
|
||||||
|
})
|
||||||
|
map.on('click', function(e) {
|
||||||
|
console.log('map click');
|
||||||
|
});
|
||||||
|
|
||||||
|
poly.on('click', function(e) {
|
||||||
|
console.log('poly click');
|
||||||
|
});
|
||||||
|
|
||||||
|
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||||
|
attribution: '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||||
|
}).addTo(map);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -75,6 +75,7 @@
|
|||||||
|
|
||||||
<!-- /layer/marker/ -->
|
<!-- /layer/marker/ -->
|
||||||
<script src="suites/layer/marker/MarkerSpec.js"></script>
|
<script src="suites/layer/marker/MarkerSpec.js"></script>
|
||||||
|
<script src="suites/layer/marker/Marker.DragSpec.js"></script>
|
||||||
<script src="suites/layer/marker/Icon.DefaultSpec.js"></script>
|
<script src="suites/layer/marker/Icon.DefaultSpec.js"></script>
|
||||||
|
|
||||||
<!-- /layer/vector/ -->
|
<!-- /layer/vector/ -->
|
||||||
|
373
spec/suites/layer/marker/Marker.DragSpec.js
Normal file
373
spec/suites/layer/marker/Marker.DragSpec.js
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
describe("Marker.Drag", function () {
|
||||||
|
var map,
|
||||||
|
div;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
div = document.createElement('div');
|
||||||
|
div.style.width = div.style.height = '600px';
|
||||||
|
div.style.top = div.style.left = 0;
|
||||||
|
div.style.position = 'absolute';
|
||||||
|
document.body.appendChild(div);
|
||||||
|
|
||||||
|
map = L.map(div).setView([0, 0], 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
document.body.removeChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("drag", function () {
|
||||||
|
it("drags a marker with mouse", function (done) {
|
||||||
|
var marker = new L.Marker([0, 0], {
|
||||||
|
draggable: true
|
||||||
|
});
|
||||||
|
map.addLayer(marker);
|
||||||
|
|
||||||
|
var hand = new Hand({
|
||||||
|
timing: 'fastframe',
|
||||||
|
onStop: function () {
|
||||||
|
var center = map.getCenter();
|
||||||
|
expect(center.lat).to.be(0);
|
||||||
|
expect(center.lng).to.be(0);
|
||||||
|
|
||||||
|
var markerPos = marker.getLatLng();
|
||||||
|
// Marker drag is very timing sensitive, so we can't check
|
||||||
|
// exact values here, just verify that the drag is in the
|
||||||
|
// right ballpark
|
||||||
|
expect(markerPos.lat).to.be.within(-50, -30);
|
||||||
|
expect(markerPos.lng).to.be.within(340, 380);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var toucher = hand.growFinger('mouse');
|
||||||
|
|
||||||
|
toucher.wait(100).moveTo(300, 280, 0)
|
||||||
|
.down().moveBy(5, 0, 20).moveBy(256, 32, 1000).wait(100).up().wait(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("pans map when autoPan is enabled", function (done) {
|
||||||
|
var marker = new L.Marker([0, 0], {
|
||||||
|
draggable: true,
|
||||||
|
autoPan: true
|
||||||
|
});
|
||||||
|
map.addLayer(marker);
|
||||||
|
|
||||||
|
var hand = new Hand({
|
||||||
|
timing: 'fastframe',
|
||||||
|
onStop: function () {
|
||||||
|
var center = map.getCenter();
|
||||||
|
expect(center.lat).to.be(0);
|
||||||
|
expect(center.lng).to.be.within(10, 30);
|
||||||
|
|
||||||
|
var markerPos = marker.getLatLng();
|
||||||
|
// Marker drag is very timing sensitive, so we can't check
|
||||||
|
// exact values here, just verify that the drag is in the
|
||||||
|
// right ballpark
|
||||||
|
expect(markerPos.lat).to.be.within(-50, -30);
|
||||||
|
expect(markerPos.lng).to.be.within(400, 450);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var toucher = hand.growFinger('mouse');
|
||||||
|
|
||||||
|
toucher.wait(100).moveTo(300, 280, 0)
|
||||||
|
.down().moveBy(5, 0, 20).moveBy(290, 32, 1000).wait(100).up().wait(100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// describe("#setIcon", function () {
|
||||||
|
|
||||||
|
// it("set the correct x and y size attributes", function () {
|
||||||
|
// var expectedX = 96;
|
||||||
|
// var expectedY = 100;
|
||||||
|
// var sizedIcon = new L.Icon.Default({
|
||||||
|
// iconUrl: icon1.options.iconUrl + '?3',
|
||||||
|
// iconSize: [expectedX, expectedY]
|
||||||
|
// });
|
||||||
|
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: sizedIcon});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// var icon = marker._icon;
|
||||||
|
|
||||||
|
// expect(icon.style.width).to.be(expectedX + 'px');
|
||||||
|
// expect(icon.style.height).to.be(expectedY + 'px');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("set the correct x and y size attributes passing only one value", function () {
|
||||||
|
// var expectedXY = 96;
|
||||||
|
// var sizedIcon = new L.Icon.Default({
|
||||||
|
// iconUrl: icon1.options.iconUrl + '?3',
|
||||||
|
// iconSize: expectedXY
|
||||||
|
// });
|
||||||
|
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: sizedIcon});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// var icon = marker._icon;
|
||||||
|
|
||||||
|
// expect(icon.style.width).to.be(expectedXY + 'px');
|
||||||
|
// expect(icon.style.height).to.be(expectedXY + 'px');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("set the correct x and y size attributes passing a L.Point instance", function () {
|
||||||
|
// var expectedXY = 96;
|
||||||
|
// var sizedIcon = new L.Icon.Default({
|
||||||
|
// iconUrl: icon1.options.iconUrl + '?3',
|
||||||
|
// iconSize: L.point(expectedXY, expectedXY)
|
||||||
|
// });
|
||||||
|
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: sizedIcon});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// var icon = marker._icon;
|
||||||
|
|
||||||
|
// expect(icon.style.width).to.be(expectedXY + 'px');
|
||||||
|
// expect(icon.style.height).to.be(expectedXY + 'px');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("changes the icon to another image while re-using the IMG element", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: icon1});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// var beforeIcon = marker._icon;
|
||||||
|
// marker.setIcon(icon2);
|
||||||
|
// var afterIcon = marker._icon;
|
||||||
|
|
||||||
|
// expect(beforeIcon).to.be(afterIcon); // Check that the <IMG> element is re-used
|
||||||
|
// expect(afterIcon.src).to.contain(icon2._getIconUrl('icon'));
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("preserves draggability", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: icon1});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// marker.dragging.disable();
|
||||||
|
// marker.setIcon(icon2);
|
||||||
|
|
||||||
|
// expect(marker.dragging.enabled()).to.be(false);
|
||||||
|
|
||||||
|
// marker.dragging.enable();
|
||||||
|
|
||||||
|
// marker.setIcon(icon1);
|
||||||
|
|
||||||
|
// expect(marker.dragging.enabled()).to.be(true);
|
||||||
|
|
||||||
|
// map.removeLayer(marker);
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// expect(marker.dragging.enabled()).to.be(true);
|
||||||
|
|
||||||
|
// map.removeLayer(marker);
|
||||||
|
// // Dragging is still enabled, we should be able to disable it,
|
||||||
|
// // even if marker is off the map.
|
||||||
|
// expect(marker.dragging).to.be(undefined);
|
||||||
|
// marker.options.draggable = false;
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// map.removeLayer(marker);
|
||||||
|
|
||||||
|
// // We should also be able to enable dragging while off the map
|
||||||
|
// expect(marker.dragging).to.be(undefined);
|
||||||
|
// marker.options.draggable = true;
|
||||||
|
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// expect(marker.dragging.enabled()).to.be(true);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("changes the DivIcon to another DivIcon, while re-using the DIV element", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text'})});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// var beforeIcon = marker._icon;
|
||||||
|
// marker.setIcon(new L.DivIcon({html: 'Inner2Text'}));
|
||||||
|
// var afterIcon = marker._icon;
|
||||||
|
|
||||||
|
// expect(beforeIcon).to.be(afterIcon); // Check that the <DIV> element is re-used
|
||||||
|
// expect(afterIcon.innerHTML).to.contain('Inner2Text');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("removes text when changing to a blank DivIcon", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text'})});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// marker.setIcon(new L.DivIcon());
|
||||||
|
// var afterIcon = marker._icon;
|
||||||
|
|
||||||
|
// expect(marker._icon.innerHTML).to.not.contain('Inner1Text');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("changes a DivIcon to an image", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: new L.DivIcon({html: 'Inner1Text'})});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// var oldIcon = marker._icon;
|
||||||
|
|
||||||
|
// marker.setIcon(icon1);
|
||||||
|
|
||||||
|
// expect(oldIcon).to.not.be(marker._icon); // Check that the _icon is NOT re-used
|
||||||
|
// expect(oldIcon.parentNode).to.be(null);
|
||||||
|
|
||||||
|
// if (L.Browser.retina) {
|
||||||
|
// expect(marker._icon.src).to.contain('marker-icon-2x.png');
|
||||||
|
// } else {
|
||||||
|
// expect(marker._icon.src).to.contain('marker-icon.png');
|
||||||
|
// }
|
||||||
|
// expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("changes an image to a DivIcon", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: icon1});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// var oldIcon = marker._icon;
|
||||||
|
|
||||||
|
// marker.setIcon(new L.DivIcon({html: 'Inner1Text'}));
|
||||||
|
|
||||||
|
// expect(oldIcon).to.not.be(marker._icon); // Check that the _icon is NOT re-used
|
||||||
|
// expect(oldIcon.parentNode).to.be(null);
|
||||||
|
|
||||||
|
// expect(marker._icon.innerHTML).to.contain('Inner1Text');
|
||||||
|
// expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("reuses the icon/shadow when changing icon", function () {
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: icon1});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// var oldIcon = marker._icon;
|
||||||
|
// var oldShadow = marker._shadow;
|
||||||
|
|
||||||
|
// marker.setIcon(icon2);
|
||||||
|
|
||||||
|
// expect(oldIcon).to.be(marker._icon);
|
||||||
|
// expect(oldShadow).to.be(marker._shadow);
|
||||||
|
|
||||||
|
// expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||||
|
// expect(marker._shadow.parentNode).to.be(map._panes.shadowPane);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// describe("#setLatLng", function () {
|
||||||
|
// it("fires a move event", function () {
|
||||||
|
|
||||||
|
// var marker = new L.Marker([0, 0], {icon: icon1});
|
||||||
|
// map.addLayer(marker);
|
||||||
|
|
||||||
|
// var beforeLatLng = marker._latlng;
|
||||||
|
// var afterLatLng = new L.LatLng(1, 2);
|
||||||
|
|
||||||
|
// var eventArgs = null;
|
||||||
|
// marker.on('move', function (e) {
|
||||||
|
// eventArgs = e;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// marker.setLatLng(afterLatLng);
|
||||||
|
|
||||||
|
// expect(eventArgs).to.not.be(null);
|
||||||
|
// expect(eventArgs.oldLatLng).to.be(beforeLatLng);
|
||||||
|
// expect(eventArgs.latlng).to.be(afterLatLng);
|
||||||
|
// expect(marker.getLatLng()).to.be(afterLatLng);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// describe('events', function () {
|
||||||
|
// it('fires click event when clicked', function () {
|
||||||
|
// var spy = sinon.spy();
|
||||||
|
|
||||||
|
// var marker = L.marker([0, 0]).addTo(map);
|
||||||
|
|
||||||
|
// marker.on('click', spy);
|
||||||
|
// happen.click(marker._icon);
|
||||||
|
|
||||||
|
// expect(spy.called).to.be.ok();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('fires click event when clicked with DivIcon', function () {
|
||||||
|
// var spy = sinon.spy();
|
||||||
|
|
||||||
|
// var marker = L.marker([0, 0], {icon: new L.DivIcon()}).addTo(map);
|
||||||
|
|
||||||
|
// marker.on('click', spy);
|
||||||
|
// happen.click(marker._icon);
|
||||||
|
|
||||||
|
// expect(spy.called).to.be.ok();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('fires click event when clicked on DivIcon child element', function () {
|
||||||
|
// var spy = sinon.spy();
|
||||||
|
|
||||||
|
// var marker = L.marker([0, 0], {icon: new L.DivIcon({html: '<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" />'})}).addTo(map);
|
||||||
|
|
||||||
|
// marker.on('click', spy);
|
||||||
|
|
||||||
|
// happen.click(marker._icon);
|
||||||
|
// expect(spy.called).to.be.ok();
|
||||||
|
|
||||||
|
// happen.click(marker._icon.querySelector('img'));
|
||||||
|
// expect(spy.calledTwice).to.be.ok();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('fires click event when clicked on DivIcon child element set using setIcon', function () {
|
||||||
|
// var spy = sinon.spy();
|
||||||
|
|
||||||
|
// var marker = L.marker([0, 0]).addTo(map);
|
||||||
|
// marker.setIcon(new L.DivIcon({html: '<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" />'}));
|
||||||
|
|
||||||
|
// marker.on('click', spy);
|
||||||
|
|
||||||
|
// happen.click(marker._icon);
|
||||||
|
// expect(spy.called).to.be.ok();
|
||||||
|
|
||||||
|
// happen.click(marker._icon.querySelector('img'));
|
||||||
|
// expect(spy.calledTwice).to.be.ok();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("do not propagate click event", function () {
|
||||||
|
// var spy = sinon.spy();
|
||||||
|
// var spy2 = sinon.spy();
|
||||||
|
// var mapSpy = sinon.spy();
|
||||||
|
// var marker = new L.Marker(new L.LatLng(55.8, 37.6));
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// marker.on('click', spy);
|
||||||
|
// marker.on('click', spy2);
|
||||||
|
// map.on('click', mapSpy);
|
||||||
|
// happen.click(marker._icon);
|
||||||
|
// expect(spy.called).to.be.ok();
|
||||||
|
// expect(spy2.called).to.be.ok();
|
||||||
|
// expect(mapSpy.called).not.to.be.ok();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("do not propagate dblclick event", function () {
|
||||||
|
// var spy = sinon.spy();
|
||||||
|
// var spy2 = sinon.spy();
|
||||||
|
// var mapSpy = sinon.spy();
|
||||||
|
// var marker = new L.Marker(new L.LatLng(55.8, 37.6));
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// marker.on('dblclick', spy);
|
||||||
|
// marker.on('dblclick', spy2);
|
||||||
|
// map.on('dblclick', mapSpy);
|
||||||
|
// happen.dblclick(marker._icon);
|
||||||
|
// expect(spy.called).to.be.ok();
|
||||||
|
// expect(spy2.called).to.be.ok();
|
||||||
|
// expect(mapSpy.called).not.to.be.ok();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it("do not catch event if it does not listen to it", function (done) {
|
||||||
|
// var marker = new L.Marker([55, 37]);
|
||||||
|
// map.addLayer(marker);
|
||||||
|
// marker.once('mousemove', function (e) {
|
||||||
|
// // It should be the marker coordinates
|
||||||
|
// expect(e.latlng.equals(marker.getLatLng())).to.be.equal(true);
|
||||||
|
// });
|
||||||
|
// happen.mousemove(marker._icon);
|
||||||
|
|
||||||
|
// map.once('mousemove', function (e) {
|
||||||
|
// // It should be the mouse coordinates, not the marker ones
|
||||||
|
// expect(e.latlng.equals(marker.getLatLng())).to.be.equal(false);
|
||||||
|
// done();
|
||||||
|
// });
|
||||||
|
// happen.mousemove(marker._icon);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// });
|
||||||
|
});
|
@ -1,6 +1,9 @@
|
|||||||
import {Handler} from '../../core/Handler';
|
import {Handler} from '../../core/Handler';
|
||||||
import * as DomUtil from '../../dom/DomUtil';
|
import * as DomUtil from '../../dom/DomUtil';
|
||||||
import {Draggable} from '../../dom/Draggable';
|
import {Draggable} from '../../dom/Draggable';
|
||||||
|
import {toBounds} from '../../geometry/Bounds';
|
||||||
|
import {toPoint} from '../../geometry/Point';
|
||||||
|
import {requestAnimFrame, cancelAnimFrame} from '../../core/Util';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
|
* L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
|
||||||
@ -34,6 +37,7 @@ export var MarkerDrag = Handler.extend({
|
|||||||
|
|
||||||
this._draggable.on({
|
this._draggable.on({
|
||||||
dragstart: this._onDragStart,
|
dragstart: this._onDragStart,
|
||||||
|
predrag: this._onPreDrag,
|
||||||
drag: this._onDrag,
|
drag: this._onDrag,
|
||||||
dragend: this._onDragEnd
|
dragend: this._onDragEnd
|
||||||
}, this).enable();
|
}, this).enable();
|
||||||
@ -44,6 +48,7 @@ export var MarkerDrag = Handler.extend({
|
|||||||
removeHooks: function () {
|
removeHooks: function () {
|
||||||
this._draggable.off({
|
this._draggable.off({
|
||||||
dragstart: this._onDragStart,
|
dragstart: this._onDragStart,
|
||||||
|
predrag: this._onPreDrag,
|
||||||
drag: this._onDrag,
|
drag: this._onDrag,
|
||||||
dragend: this._onDragEnd
|
dragend: this._onDragEnd
|
||||||
}, this).disable();
|
}, this).disable();
|
||||||
@ -57,6 +62,41 @@ export var MarkerDrag = Handler.extend({
|
|||||||
return this._draggable && this._draggable._moved;
|
return this._draggable && this._draggable._moved;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_adjustPan: function (e) {
|
||||||
|
var marker = this._marker,
|
||||||
|
map = marker._map,
|
||||||
|
speed = this._marker.options.autoPanSpeed,
|
||||||
|
padding = this._marker.options.autoPanPadding,
|
||||||
|
iconPos = L.DomUtil.getPosition(marker._icon),
|
||||||
|
bounds = map.getPixelBounds(),
|
||||||
|
origin = map.getPixelOrigin(),
|
||||||
|
panBounds = toBounds(
|
||||||
|
bounds.min._subtract(origin).add(padding),
|
||||||
|
bounds.max._subtract(origin).subtract(padding)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!panBounds.contains(iconPos)) {
|
||||||
|
// Compute incremental movement
|
||||||
|
var movement = toPoint(
|
||||||
|
(Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) -
|
||||||
|
(Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x),
|
||||||
|
|
||||||
|
(Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) -
|
||||||
|
(Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y)
|
||||||
|
).multiplyBy(speed);
|
||||||
|
|
||||||
|
map.panBy(movement, {animate: false});
|
||||||
|
|
||||||
|
this._draggable._newPos._add(movement);
|
||||||
|
this._draggable._startPos._add(movement);
|
||||||
|
|
||||||
|
L.DomUtil.setPosition(marker._icon, this._draggable._newPos);
|
||||||
|
this._onDrag(e);
|
||||||
|
|
||||||
|
this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onDragStart: function () {
|
_onDragStart: function () {
|
||||||
// @section Dragging events
|
// @section Dragging events
|
||||||
// @event dragstart: Event
|
// @event dragstart: Event
|
||||||
@ -72,6 +112,13 @@ export var MarkerDrag = Handler.extend({
|
|||||||
.fire('dragstart');
|
.fire('dragstart');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onPreDrag: function (e) {
|
||||||
|
if (this._marker.options.autoPan) {
|
||||||
|
cancelAnimFrame(this._panRequest);
|
||||||
|
this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onDrag: function (e) {
|
_onDrag: function (e) {
|
||||||
var marker = this._marker,
|
var marker = this._marker,
|
||||||
shadow = marker._shadow,
|
shadow = marker._shadow,
|
||||||
@ -98,6 +145,8 @@ export var MarkerDrag = Handler.extend({
|
|||||||
// @event dragend: DragEndEvent
|
// @event dragend: DragEndEvent
|
||||||
// Fired when the user stops dragging the marker.
|
// Fired when the user stops dragging the marker.
|
||||||
|
|
||||||
|
cancelAnimFrame(this._panRequest);
|
||||||
|
|
||||||
// @event moveend: Event
|
// @event moveend: Event
|
||||||
// Fired when the marker stops moving (because of dragging).
|
// Fired when the marker stops moving (because of dragging).
|
||||||
delete this._oldLatLng;
|
delete this._oldLatLng;
|
||||||
|
@ -36,6 +36,18 @@ export var Marker = Layer.extend({
|
|||||||
// Whether the marker is draggable with mouse/touch or not.
|
// Whether the marker is draggable with mouse/touch or not.
|
||||||
draggable: false,
|
draggable: false,
|
||||||
|
|
||||||
|
// @option autoPan: Boolean = false
|
||||||
|
// Set it to `true` if you want the map to do panning animation when marker hits the edges.
|
||||||
|
autoPan: false,
|
||||||
|
|
||||||
|
// @option autoPanPadding: Point = Point(5, 5)
|
||||||
|
// Equivalent of setting both top left and bottom right autopan padding to the same value.
|
||||||
|
autoPanPadding: [50, 50],
|
||||||
|
|
||||||
|
// @option autoPanSpeed: Number = 100
|
||||||
|
// Numer of pixels the map should move by.
|
||||||
|
autoPanSpeed: 10,
|
||||||
|
|
||||||
// @option keyboard: Boolean = true
|
// @option keyboard: Boolean = true
|
||||||
// Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
|
// Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
|
||||||
keyboard: true,
|
keyboard: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user