Codebase list leaflet / 5a25813
Implemented map.panInside() to bring a target latlng into view (#6054) * Implemented panInside function to bring a target latlng into view * Replaced padding param with separate padding options like fitBounds. * Remove global L usage and tidy. * Comment update for the new padding options. * Trailing space fix. daverayment authored 5 years ago Per Liedman committed 5 years ago
2 changed file(s) with 137 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
10341034
10351035 });
10361036
1037
1038 describe("#panInside", function () {
1039 var center,
1040 tl,
1041 tlPix;
1042
1043 beforeEach(function () {
1044 var container = map.getContainer();
1045 container.style.height = container.style.width = "500px";
1046 document.body.appendChild(container);
1047 map.setView(L.latLng([53.0, 0.15]), 12, {animate: false});
1048 center = map.getCenter();
1049 tl = map.getBounds().getNorthWest();
1050 tlPix = map.getPixelBounds().min;
1051 });
1052
1053 afterEach(function () {
1054 document.body.removeChild(map.getContainer());
1055 });
1056
1057 it("does not pan the map when the target is within bounds", function () {
1058 map.panInside(tl, {animate:false});
1059 expect(center).to.equal(map.getCenter());
1060 });
1061
1062 it("pans the map when padding is provided and the target is within the border area", function () {
1063 var padding = [40, 20],
1064 p = tlPix.add([30, 0]), // Top-left
1065 distanceMoved;
1066 map.panInside(map.unproject(p), {padding: padding, animate: false});
1067 distanceMoved = map.getPixelBounds().min.subtract(tlPix);
1068 expect(distanceMoved.equals(L.point([-10, -20]))).to.eql(true);
1069
1070 tlPix = map.getPixelBounds().min;
1071 p = [map.getPixelBounds().max.x - 10, map.getPixelBounds().min.y]; // Top-right
1072 map.panInside(map.unproject(p), {padding: padding, animate: false});
1073 distanceMoved = map.getPixelBounds().min.subtract(tlPix);
1074 expect(distanceMoved.equals(L.point([30, -20]))).to.eql(true);
1075
1076 tlPix = map.getPixelBounds().min;
1077 p = [map.getPixelBounds().min.x + 35, map.getPixelBounds().max.y]; // Bottom-left
1078 map.panInside(map.unproject(p), {padding: padding, animate: false});
1079 distanceMoved = map.getPixelBounds().min.subtract(tlPix);
1080 expect(distanceMoved.equals(L.point([-5, 20]))).to.eql(true);
1081
1082 tlPix = map.getPixelBounds().min;
1083 p = [map.getPixelBounds().max.x - 15, map.getPixelBounds().max.y]; // Bottom-right
1084 map.panInside(map.unproject(p), {padding: padding, animate: false});
1085 distanceMoved = map.getPixelBounds().min.subtract(tlPix);
1086 expect(distanceMoved.equals(L.point([25, 20]))).to.eql(true);
1087 });
1088
1089 it("supports different padding values for each border", function () {
1090 var p = tlPix.add([40, 0]), // Top-Left
1091 distanceMoved,
1092 opts = {paddingTL: [60, 20], paddingBR: [10, 10]};
1093 map.panInside(map.unproject(p), opts);
1094 expect(center).to.equal(map.getCenter());
1095
1096 var br = map.getPixelBounds().max; // Bottom-Right
1097 map.panInside(map.unproject(L.point(br.x - 20, br.y)), opts);
1098 expect(center).to.not.equal(map.getCenter);
1099 });
1100
1101 it("pans on both X and Y axes when the target is outside of the view area and both the point's coords are outside the bounds", function () {
1102 var p = map.unproject(tlPix.subtract([200, 200]));
1103 map.panInside(p, {animate: false});
1104 expect(map.getBounds().contains(p)).to.be(true);
1105 expect(map.getCenter().lng).to.not.eql(center.lng);
1106 expect(map.getCenter().lat).to.not.eql(center.lat);
1107 });
1108
1109 it("pans only on the Y axis when the target's X coord is within bounds but the Y is not", function () {
1110 var p = L.latLng(tl.lat + 5, tl.lng);
1111 map.panInside(p, {animate: false});
1112 expect(map.getBounds().contains(p)).to.be(true);
1113 var dx = Math.abs(map.getCenter().lng - center.lng);
1114 expect(dx).to.be.lessThan(1.0E-9);
1115 expect(map.getCenter().lat).to.not.eql(center.lat);
1116 });
1117
1118 it("pans only on the X axis when the target's Y coord is within bounds but the X is not", function () {
1119 var p = L.latLng(tl.lat, tl.lng - 5);
1120 map.panInside(p, 0, {animate: false});
1121 expect(map.getBounds().contains(p)).to.be(true);
1122 expect(map.getCenter().lng).to.not.eql(center.lng);
1123 var dy = map.getCenter().lat - center.lat;
1124 expect(dy).to.be.lessThan(1.0E-9);
1125 });
1126 });
1127
1128
10371129 describe('#DOM events', function () {
10381130
10391131 var c, map;
507507 }
508508
509509 this._enforcingBounds = false;
510 return this;
511 },
512
513 // @method panInside(latlng: LatLng, options?: options): this
514 // Pans the map the minimum amount to make the `latlng` visible. Use
515 // `padding`, `paddingTopLeft` and `paddingTopRight` options to fit
516 // the display to more restricted bounds, like [`fitBounds`](#map-fitbounds).
517 // If `latlng` is already within the (optionally padded) display bounds,
518 // the map will not be panned.
519 panInside: function (latlng, options) {
520 options = options || {};
521
522 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),
523 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),
524 center = this.getCenter(),
525 pixelCenter = this.project(center),
526 pixelPoint = this.project(latlng),
527 pixelBounds = this.getPixelBounds(),
528 halfPixelBounds = pixelBounds.getSize().divideBy(2),
529 paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]);
530
531 if (!paddedBounds.contains(pixelPoint)) {
532 this._enforcingBounds = true;
533 var diff = pixelCenter.subtract(pixelPoint),
534 newCenter = toPoint(pixelPoint.x + diff.x, pixelPoint.y + diff.y);
535
536 if (pixelPoint.x < paddedBounds.min.x || pixelPoint.x > paddedBounds.max.x) {
537 newCenter.x = pixelCenter.x - diff.x;
538 if (diff.x > 0) {
539 newCenter.x += halfPixelBounds.x - paddingTL.x;
540 } else {
541 newCenter.x -= halfPixelBounds.x - paddingBR.x;
542 }
543 }
544 if (pixelPoint.y < paddedBounds.min.y || pixelPoint.y > paddedBounds.max.y) {
545 newCenter.y = pixelCenter.y - diff.y;
546 if (diff.y > 0) {
547 newCenter.y += halfPixelBounds.y - paddingTL.y;
548 } else {
549 newCenter.y -= halfPixelBounds.y - paddingBR.y;
550 }
551 }
552 this.panTo(this.unproject(newCenter), options);
553 this._enforcingBounds = false;
554 }
510555 return this;
511556 },
512557