Better tooltip offset handling (fix #4772) (#4773)

- default offset is now [0, 0]
- both offset.x and offset.y are always honoured
- positive x always move the tooltip on the right
- positive y always move the tooltip on the bottom
This commit is contained in:
Yohan Boniface 2016-08-02 16:51:22 +02:00 committed by Vladimir Agafonkin
parent fc1dc96638
commit e746211be7
4 changed files with 66 additions and 17 deletions

View File

@ -49,7 +49,7 @@
iconSize: [50, 50] iconSize: [50, 50]
}); });
L.marker([41.22, 9.48], {icon: icon}).addTo(map).bindTooltip('A div icon tooltip following mouse', {sticky: true, direction: 'auto'}); L.marker([41.22, 9.48], {icon: icon}).addTo(map).bindTooltip('A div icon tooltip following mouse', {sticky: true, direction: 'auto'});
L.marker([41.23, 9.47], {icon: icon}).addTo(map).bindTooltip('A div icon tooltip'); L.marker([41.23, 9.47], {icon: icon}).addTo(map).bindTooltip('A div icon tooltip with custom offset', {direction: 'top', offset: [-25, -25]});
L.marker([41.23, 9.42], {draggable: true}).addTo(map).bindTooltip('Draggable marker tooltip', {permanent: true, direction: 'auto'}); L.marker([41.23, 9.42], {draggable: true}).addTo(map).bindTooltip('Draggable marker tooltip', {permanent: true, direction: 'auto'});
L.marker([41.19, 9.43]).addTo(map).bindTooltip('Clickable marker tooltip', {permanent: true, interactive: true}).on('click', function () { alert('clicked!'); }); L.marker([41.19, 9.43]).addTo(map).bindTooltip('Clickable marker tooltip', {permanent: true, interactive: true}).on('click', function () { alert('clicked!'); });

12
dist/leaflet.css vendored
View File

@ -573,6 +573,12 @@
/* Directions */ /* Directions */
.leaflet-tooltip-bottom {
margin-top: 6px;
}
.leaflet-tooltip-top {
margin-top: -6px;
}
.leaflet-tooltip-bottom:before, .leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before { .leaflet-tooltip-top:before {
left: 50%; left: 50%;
@ -589,6 +595,12 @@
margin-left: -6px; margin-left: -6px;
border-bottom-color: #fff; border-bottom-color: #fff;
} }
.leaflet-tooltip-left {
margin-left: -6px;
}
.leaflet-tooltip-right {
margin-left: 6px;
}
.leaflet-tooltip-left:before, .leaflet-tooltip-left:before,
.leaflet-tooltip-right:before { .leaflet-tooltip-right:before {
top: 50%; top: 50%;

View File

@ -82,25 +82,63 @@ describe('Tooltip', function () {
expect(spy.calledOnce).to.be(true); expect(spy.calledOnce).to.be(true);
}); });
it("can be forced on top direction", function () { it("honours offset on left direction", function () {
var layer = new L.Marker(center).addTo(map); var layer = new L.Marker(center).addTo(map);
var spy = sinon.spy(); var spy = sinon.spy();
layer.on('click', spy); layer.on('click', spy);
layer.bindTooltip('A long tooltip that should be displayed on the left', {permanent: true, direction: 'left', interactive: true, offset: [-20, -20]});
expect(map.hasLayer(layer._tooltip)).to.be(true);
happen.at('click', 150, 180);
expect(spy.calledOnce).to.be(false);
happen.at('click', 130, 160);
expect(spy.calledOnce).to.be(true);
});
it("can be forced on top direction", function () {
var layer = L.circleMarker(center).addTo(map);
var spy = sinon.spy();
layer.on('click', spy);
layer.bindTooltip('A tooltip that should be displayed on the top', {permanent: true, direction: 'top', interactive: true}); layer.bindTooltip('A tooltip that should be displayed on the top', {permanent: true, direction: 'top', interactive: true});
expect(map.hasLayer(layer._tooltip)).to.be(true); expect(map.hasLayer(layer._tooltip)).to.be(true);
happen.at('click', 200, 170); // Marker is on the map center, which is 400px large. happen.at('click', 200, 180); // Marker is on the map center, which is 400px large.
expect(spy.calledOnce).to.be(true);
});
it("honours offset on top direction", function () {
var layer = L.circleMarker(center).addTo(map);
var spy = sinon.spy();
layer.on('click', spy);
layer.bindTooltip('A tooltip that should be displayed on the top', {permanent: true, direction: 'top', interactive: true, offset: [-20, -20]});
happen.at('click', 200, 180);
expect(spy.calledOnce).to.be(false);
happen.at('click', 180, 150);
expect(spy.calledOnce).to.be(true); expect(spy.calledOnce).to.be(true);
}); });
it("can be forced on bottom direction", function () { it("can be forced on bottom direction", function () {
var layer = new L.Marker(center).addTo(map); var layer = L.circleMarker(center).addTo(map);
var spy = sinon.spy(); var spy = sinon.spy();
layer.on('click', spy); layer.on('click', spy);
layer.bindTooltip('A tooltip that should be displayed on the top', {permanent: true, direction: 'bottom', interactive: true}); layer.bindTooltip('A tooltip that should be displayed on the top', {permanent: true, direction: 'bottom', interactive: true});
expect(map.hasLayer(layer._tooltip)).to.be(true); expect(map.hasLayer(layer._tooltip)).to.be(true);
happen.at('click', 200, 210); // Marker is on the map center, which is 400px large. happen.at('click', 200, 220); // Marker is on the map center, which is 400px large.
expect(spy.calledOnce).to.be(true);
});
it("honours offset on bottom direction", function () {
var layer = L.circleMarker(center).addTo(map);
var spy = sinon.spy();
layer.on('click', spy);
layer.bindTooltip('A tooltip that should be displayed on the top', {permanent: true, direction: 'bottom', interactive: true, offset: [20, 20]});
expect(map.hasLayer(layer._tooltip)).to.be(true);
happen.at('click', 200, 220);
expect(spy.calledOnce).to.be(false);
happen.at('click', 220, 230);
expect(spy.calledOnce).to.be(true); expect(spy.calledOnce).to.be(true);
}); });

View File

@ -11,9 +11,9 @@
* ``` * ```
* Note about tooltip offset. Leaflet takes two options in consideration * Note about tooltip offset. Leaflet takes two options in consideration
* for computing tooltip offseting: * for computing tooltip offseting:
* - the `offset` Tooltip option: it defaults to [6, -6], because the tooltip * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
* tip is 6px width and height. Remember to change this value if you override * Add a positive x offset to move the tooltip to the right, and a positive y offset to
* the tip in CSS. * move it to the bottom. Negatives will move to the left and top.
* - the `tooltipAnchor` Icon option: this will only be considered for Marker. You * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You
* should adapt this value if you use a custom icon. * should adapt this value if you use a custom icon.
*/ */
@ -29,10 +29,9 @@ L.Tooltip = L.DivOverlay.extend({
// `Map pane` where the tooltip will be added. // `Map pane` where the tooltip will be added.
pane: 'tooltipPane', pane: 'tooltipPane',
// @option offset: Point = Point(6, -6) // @option offset: Point = Point(0, 0)
// The offset of the tooltip position. Update it if you customize the // Optional offset of the tooltip position.
// tooltip tip in CSS. offset: [0, 0],
offset: [6, -6],
// @option direction: String = 'auto' // @option direction: String = 'auto'
// Direction where to open the tooltip. Possible values are: `right`, `left`, // Direction where to open the tooltip. Possible values are: `right`, `left`,
@ -124,17 +123,17 @@ L.Tooltip = L.DivOverlay.extend({
anchor = this._getAnchor(); anchor = this._getAnchor();
if (direction === 'top') { if (direction === 'top') {
pos = pos.add(L.point(-tooltipWidth / 2, -tooltipHeight + offset.y + anchor.y)); pos = pos.add(L.point(-tooltipWidth / 2 + offset.x, -tooltipHeight + offset.y + anchor.y));
} else if (direction === 'bottom') { } else if (direction === 'bottom') {
pos = pos.subtract(L.point(tooltipWidth / 2, offset.y)); pos = pos.subtract(L.point(tooltipWidth / 2 - offset.x, -offset.y));
} else if (direction === 'center') { } else if (direction === 'center') {
pos = pos.subtract(L.point(tooltipWidth / 2, tooltipHeight / 2 - anchor.y)); pos = pos.subtract(L.point(tooltipWidth / 2 + offset.x, tooltipHeight / 2 - anchor.y + offset.y));
} else if (direction === 'right' || direction === 'auto' && tooltipPoint.x < centerPoint.x) { } else if (direction === 'right' || direction === 'auto' && tooltipPoint.x < centerPoint.x) {
direction = 'right'; direction = 'right';
pos = pos.add([offset.x + anchor.x, anchor.y - tooltipHeight / 2]); pos = pos.add([offset.x + anchor.x, anchor.y - tooltipHeight / 2 + offset.y]);
} else { } else {
direction = 'left'; direction = 'left';
pos = pos.subtract(L.point(offset.x + tooltipWidth + anchor.x, tooltipHeight / 2 - anchor.y)); pos = pos.subtract(L.point(tooltipWidth + anchor.x - offset.x, tooltipHeight / 2 - anchor.y - offset.y));
} }
L.DomUtil.removeClass(container, 'leaflet-tooltip-right'); L.DomUtil.removeClass(container, 'leaflet-tooltip-right');